media: qcom: camss: fix error path on configuration of power domains
authorVladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Tue, 13 Aug 2024 21:03:42 +0000 (00:03 +0300)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Sat, 12 Oct 2024 17:09:05 +0000 (19:09 +0200)
There is a chance to meet runtime issues during configuration of CAMSS
power domains, because on the error path dev_pm_domain_detach() is
unexpectedly called with NULL or error pointer.

One of the simplest ways to reproduce the problem is to probe CAMSS
driver before registration of CAMSS power domains, for instance if
a platform CAMCC driver is simply not built.

Warning backtrace example:

    Unable to handle kernel NULL pointer dereference at virtual address 00000000000001a2

    <snip>

    pc : dev_pm_domain_detach+0x8/0x48
    lr : camss_probe+0x374/0x9c0

    <snip>

    Call trace:
     dev_pm_domain_detach+0x8/0x48
     platform_probe+0x70/0xf0
     really_probe+0xc4/0x2a8
     __driver_probe_device+0x80/0x140
     driver_probe_device+0x48/0x170
     __device_attach_driver+0xc0/0x148
     bus_for_each_drv+0x88/0xf0
     __device_attach+0xb0/0x1c0
     device_initial_probe+0x1c/0x30
     bus_probe_device+0xb4/0xc0
     deferred_probe_work_func+0x90/0xd0
     process_one_work+0x164/0x3e0
     worker_thread+0x310/0x420
     kthread+0x120/0x130
     ret_from_fork+0x10/0x20

Fixes: 23aa4f0cd327 ("media: qcom: camss: Move VFE power-domain specifics into vfe.c")
Cc: <stable@vger.kernel.org>
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/qcom/camss/camss.c

index 151e4c4338f000ce572f0e45247909bf094b35c9..34c1bd5ed54096e43465f3d7b8d5f6250aed0860 100644 (file)
@@ -2130,10 +2130,8 @@ static int camss_configure_pd(struct camss *camss)
        if (camss->res->pd_name) {
                camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
                                                            camss->res->pd_name);
-               if (IS_ERR(camss->genpd)) {
-                       ret = PTR_ERR(camss->genpd);
-                       goto fail_pm;
-               }
+               if (IS_ERR(camss->genpd))
+                       return PTR_ERR(camss->genpd);
        }
 
        if (!camss->genpd) {
@@ -2143,14 +2141,13 @@ static int camss_configure_pd(struct camss *camss)
                 */
                camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
                                                          camss->genpd_num - 1);
+               if (IS_ERR(camss->genpd))
+                       return PTR_ERR(camss->genpd);
        }
-       if (IS_ERR_OR_NULL(camss->genpd)) {
-               if (!camss->genpd)
-                       ret = -ENODEV;
-               else
-                       ret = PTR_ERR(camss->genpd);
-               goto fail_pm;
-       }
+
+       if (!camss->genpd)
+               return -ENODEV;
+
        camss->genpd_link = device_link_add(camss->dev, camss->genpd,
                                            DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
                                            DL_FLAG_RPM_ACTIVE);