diff options
author | Konrad Dybcio <konrad.dybcio@linaro.org> | 2023-10-14 02:07:46 +0300 |
---|---|---|
committer | Rob Clark <robdclark@chromium.org> | 2023-10-16 17:29:42 +0300 |
commit | b9986846189cea87a9d93052cfab462c9e74f447 (patch) | |
tree | d2346831c35ecaabc71c58e86b5774ac5e325d0a | |
parent | 5e05be78264594634860087953649487f486ffcc (diff) | |
download | linux-b9986846189cea87a9d93052cfab462c9e74f447.tar.xz |
drm/msm/a6xx: Fix up QMP handling
The commit referenced in the Fixes tag had a couple problems (as
pointed out by Dan):
- qmp_put was never called, resulting in refcnt leaks
- failling to acquire the QMP mailbox on A7xx would not undo the probe
function properly
- the qmp_put call present in the code was unreachable
Fix all of these issues.
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Fixes: 88a0997f2f94 ("drm/msm/a6xx: Send ACD state to QMP at GMU resume")
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/562761/
Signed-off-by: Rob Clark <robdclark@chromium.org>
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 0555a0134fad..8c4900444b2c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1558,6 +1558,9 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) dev_pm_domain_detach(gmu->gxpd, false); } + if (!IS_ERR_OR_NULL(gmu->qmp)) + qmp_put(gmu->qmp); + iounmap(gmu->mmio); if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc")) iounmap(gmu->rscc); @@ -1654,6 +1657,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct platform_device *pdev = of_find_device_by_node(node); + struct device_link *link; int ret; if (!pdev) @@ -1777,15 +1781,17 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) goto err_mmio; } - if (!device_link_add(gmu->dev, gmu->cxpd, - DL_FLAG_PM_RUNTIME)) { + link = device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME); + if (!link) { ret = -ENODEV; goto detach_cxpd; } gmu->qmp = qmp_get(gmu->dev); - if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) - return PTR_ERR(gmu->qmp); + if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) { + ret = PTR_ERR(gmu->qmp); + goto remove_device_link; + } init_completion(&gmu->pd_gate); complete_all(&gmu->pd_gate); @@ -1810,8 +1816,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) return 0; - if (!IS_ERR_OR_NULL(gmu->qmp)) - qmp_put(gmu->qmp); +remove_device_link: + device_link_del(link); detach_cxpd: dev_pm_domain_detach(gmu->cxpd, false); |