drm/omap: Fix runtime PM imbalance on error
authorDinghao Liu <dinghao.liu@zju.edu.cn>
Sat, 22 Aug 2020 06:57:33 +0000 (14:57 +0800)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 10 Nov 2020 12:52:30 +0000 (14:52 +0200)
pm_runtime_get_sync() increments the runtime PM usage counter
even when it returns an error code. However, users of its
direct wrappers in omapdrm assume that PM usage counter will
not change on error. Thus a pairing decrement is needed on
the error handling path for these wrappers to keep the counter
balanced.

Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200822065743.13671-1-dinghao.liu@zju.edu.cn
drivers/gpu/drm/omapdrm/dss/dispc.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/venc.c

index 4859393..5991838 100644 (file)
@@ -653,8 +653,11 @@ int dispc_runtime_get(struct dispc_device *dispc)
        DSSDBG("dispc_runtime_get\n");
 
        r = pm_runtime_get_sync(&dispc->pdev->dev);
-       WARN_ON(r < 0);
-       return r < 0 ? r : 0;
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(&dispc->pdev->dev);
+               return r;
+       }
+       return 0;
 }
 
 void dispc_runtime_put(struct dispc_device *dispc)
index 5929b32..735a4e9 100644 (file)
@@ -1112,8 +1112,11 @@ static int dsi_runtime_get(struct dsi_data *dsi)
        DSSDBG("dsi_runtime_get\n");
 
        r = pm_runtime_get_sync(dsi->dev);
-       WARN_ON(r < 0);
-       return r < 0 ? r : 0;
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(dsi->dev);
+               return r;
+       }
+       return 0;
 }
 
 static void dsi_runtime_put(struct dsi_data *dsi)
index 6ccbc29..d7b2f5b 100644 (file)
@@ -858,8 +858,11 @@ int dss_runtime_get(struct dss_device *dss)
        DSSDBG("dss_runtime_get\n");
 
        r = pm_runtime_get_sync(&dss->pdev->dev);
-       WARN_ON(r < 0);
-       return r < 0 ? r : 0;
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(&dss->pdev->dev);
+               return r;
+       }
+       return 0;
 }
 
 void dss_runtime_put(struct dss_device *dss)
index ba4a21d..8de41e7 100644 (file)
@@ -43,10 +43,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi)
        DSSDBG("hdmi_runtime_get\n");
 
        r = pm_runtime_get_sync(&hdmi->pdev->dev);
-       WARN_ON(r < 0);
-       if (r < 0)
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(&hdmi->pdev->dev);
                return r;
-
+       }
        return 0;
 }
 
index 045aa44..54e5cb5 100644 (file)
@@ -44,10 +44,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi)
        DSSDBG("hdmi_runtime_get\n");
 
        r = pm_runtime_get_sync(&hdmi->pdev->dev);
-       WARN_ON(r < 0);
-       if (r < 0)
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(&hdmi->pdev->dev);
                return r;
-
+       }
        return 0;
 }
 
index 5c027c8..94cf50d 100644 (file)
@@ -361,8 +361,11 @@ static int venc_runtime_get(struct venc_device *venc)
        DSSDBG("venc_runtime_get\n");
 
        r = pm_runtime_get_sync(&venc->pdev->dev);
-       WARN_ON(r < 0);
-       return r < 0 ? r : 0;
+       if (WARN_ON(r < 0)) {
+               pm_runtime_put_noidle(&venc->pdev->dev);
+               return r;
+       }
+       return 0;
 }
 
 static void venc_runtime_put(struct venc_device *venc)