[PATCH] [v2] drm/omap: Fix runtime PM imbalance on error

From: Dinghao Liu
Date: Sat Aug 22 2020 - 02:59:11 EST


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@xxxxxxxxxx>
---

Changelog:

v2: - Fix 5 additional similar cases in omapdrm.
---
drivers/gpu/drm/omapdrm/dss/dispc.c | 7 +++++--
drivers/gpu/drm/omapdrm/dss/dsi.c | 7 +++++--
drivers/gpu/drm/omapdrm/dss/dss.c | 7 +++++--
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 6 +++---
drivers/gpu/drm/omapdrm/dss/hdmi5.c | 6 +++---
drivers/gpu/drm/omapdrm/dss/venc.c | 7 +++++--
6 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 48593932bddf..599183879caf 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -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)
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index eeccf40bae41..973bfa14a104 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -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)
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 6ccbc29c4ce4..d7b2f5bcac16 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -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)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 2578c95570f6..2cc804bdc2e4 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -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;
}

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 4d4c1fabd0a1..92fe05d3da5a 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -45,10 +45,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;
}

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index e0817934ee16..4844743fd507 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -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)
--
2.17.1