Hi Dragan,
At 2024-07-04 18:35:42, "Dragan Simic" <dsi...@manjaro.org> wrote:
>Hello Andy,
>
>On 2024-07-04 04:10, Andy Yan wrote:
>> At 2024-07-04 07:32:02, "Dragan Simic" <dsi...@manjaro.org> wrote:
>>> After the additional firmware-related module information was 
>>> introduced by
>>> the commit c0677e41a47f ("drm/rockchip: cdn-dp-core: add 
>>> MODULE_FIRMWARE
>>> macro"), there's no longer need for the firmware-loading workarounds 
>>> whose
>>> sole purpose was to prevent the missing firmware blob in an initial 
>>> ramdisk
>>> from causing driver initialization to fail.  Thus, delete the 
>>> workarounds,
>>> which removes a sizable chunk of redundant code.
>> 
>> What would happen if there was no ramdisk? And the firmware is in 
>> rootfs ?
>> 
>> For example: A buildroot based tiny embedded system。
>
>Good point, let me explain, please.
>
>In general, if a driver is built into the kernel, there should also be
>an initial ramdisk that contains the related firmware blobs, because 
>it's
>unknown is the root filesystem available when the driver is probed.  If
>a driver is built as a module and there's no initial ramdisk, having
>the related firmware blobs on the root filesystem should be fine, 
>because
>the firmware blobs and the kernel module become available at the same
>time, through the root filesystem. [1]
>
>Another option for a driver built statically into the kernel, when 
>there's
>no initial ramdisk, is to build the required firmware blobs into the 
>kernel
>image. [2]  Of course, that's feasible only when a kernel image is built
>specificially for some device, because otherwise it would become too 
>large
>because of too many drivers and their firmware blobs becoming included,
>but that seems to fit the Buildroot-based example.
>
>To sum it up, mechanisms already exist in the kernel for various 
>scenarios
>when it comes to loading firmware blobs.  Even if the deleted workaround
>attempts to solve some issue specific to some environment, that isn't 
>the
>right place or the right way for solving any issues of that kind.
>
>While preparing this patch, I even tried to find another kernel driver 
>that
>also implements some similar workarounds for firmware loading, to 
>justify
>the existence of such workarounds and to possibly move them into the 
>kernel's
>firmware-loading interface.  Alas, I was unable to find such workarounds 
>in
>other drivers, which solidified my reasoning behind classifying the 
>removed
>code as out-of-place and redundant.
For some tiny embedded system,there is no such ramdisk,for example:
a buildroot based rootfs,the buildroot only generate rootfs。

And FYI, there are mainline drivers try to fix such issue by defer_probe,for 
example: 
smc_abc[0]
There are also some other similar scenario in gpu driver{1}[2]


[0]https://elixir.bootlin.com/linux/latest/source/drivers/tee/optee/smc_abi.c#L1518
[1]https://patchwork.kernel.org/project/dri-devel/patch/20240109120604.603700-1-javi...@redhat.com/
[2]https://lore.kernel.org/dri-devel/87y1918psd....@minerva.mail-host-address-is-not-set/T/


>
>[1] 
>https://www.kernel.org/doc/Documentation/driver-api/firmware/direct-fs-lookup.rst
>[2] 
>https://www.kernel.org/doc/Documentation/driver-api/firmware/built-in-fw.rst
>
>>> Various utilities used by Linux distributions to generate initial 
>>> ramdisks
>>> need to obey the firmware-related module information, so we can rely 
>>> on the
>>> firmware blob being present in the generated initial ramdisks.
>>> 
>>> Signed-off-by: Dragan Simic <dsi...@manjaro.org>
>>> ---
>>> drivers/gpu/drm/rockchip/cdn-dp-core.c | 53 +++++---------------------
>>> 1 file changed, 10 insertions(+), 43 deletions(-)
>>> 
>>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
>>> b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>>> index bd7aa891b839..e1a7c6a1172b 100644
>>> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
>>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>>> @@ -44,9 +44,9 @@ static inline struct cdn_dp_device 
>>> *encoder_to_dp(struct drm_encoder *encoder)
>>> #define DPTX_HPD_DEL                (2 << 12)
>>> #define DPTX_HPD_SEL_MASK   (3 << 28)
>>> 
>>> -#define CDN_FW_TIMEOUT_MS  (64 * 1000)
>>> #define CDN_DPCD_TIMEOUT_MS 5000
>>> #define CDN_DP_FIRMWARE             "rockchip/dptx.bin"
>>> +
>>> MODULE_FIRMWARE(CDN_DP_FIRMWARE);
>>> 
>>> struct cdn_dp_data {
>>> @@ -909,61 +909,28 @@ static int cdn_dp_audio_codec_init(struct 
>>> cdn_dp_device *dp,
>>>     return PTR_ERR_OR_ZERO(dp->audio_pdev);
>>> }
>>> 
>>> -static int cdn_dp_request_firmware(struct cdn_dp_device *dp)
>>> -{
>>> -   int ret;
>>> -   unsigned long timeout = jiffies + 
>>> msecs_to_jiffies(CDN_FW_TIMEOUT_MS);
>>> -   unsigned long sleep = 1000;
>>> -
>>> -   WARN_ON(!mutex_is_locked(&dp->lock));
>>> -
>>> -   if (dp->fw_loaded)
>>> -           return 0;
>>> -
>>> -   /* Drop the lock before getting the firmware to avoid blocking boot 
>>> */
>>> -   mutex_unlock(&dp->lock);
>>> -
>>> -   while (time_before(jiffies, timeout)) {
>>> -           ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev);
>>> -           if (ret == -ENOENT) {
>>> -                   msleep(sleep);
>>> -                   sleep *= 2;
>>> -                   continue;
>>> -           } else if (ret) {
>>> -                   DRM_DEV_ERROR(dp->dev,
>>> -                                 "failed to request firmware: %d\n", ret);
>>> -                   goto out;
>>> -           }
>>> -
>>> -           dp->fw_loaded = true;
>>> -           ret = 0;
>>> -           goto out;
>>> -   }
>>> -
>>> -   DRM_DEV_ERROR(dp->dev, "Timed out trying to load firmware\n");
>>> -   ret = -ETIMEDOUT;
>>> -out:
>>> -   mutex_lock(&dp->lock);
>>> -   return ret;
>>> -}
>>> -
>>> static void cdn_dp_pd_event_work(struct work_struct *work)
>>> {
>>>     struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
>>>                                             event_work);
>>>     struct drm_connector *connector = &dp->connector;
>>>     enum drm_connector_status old_status;
>>> -
>>>     int ret;
>>> 
>>>     mutex_lock(&dp->lock);
>>> 
>>>     if (dp->suspended)
>>>             goto out;
>>> 
>>> -   ret = cdn_dp_request_firmware(dp);
>>> -   if (ret)
>>> -           goto out;
>>> +   if (!dp->fw_loaded) {
>>> +           ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev);
>>> +           if (ret) {
>>> +                   DRM_DEV_ERROR(dp->dev, "Loading firmware failed: %d\n", 
>>> ret);
>>> +                   goto out;
>>> +           }
>>> +
>>> +           dp->fw_loaded = true;
>>> +   }
>>> 
>>>     dp->connected = true;
>>> 

Reply via email to