media: exynos4-is: fix pm_runtime_get_sync() usage count
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Fri, 23 Apr 2021 15:19:17 +0000 (17:19 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 10 May 2021 09:36:34 +0000 (11:36 +0200)
The pm_runtime_get_sync() internally increments the
dev->power.usage_count without decrementing it, even on errors.

On some places, this is ok, but on others the usage count
ended being unbalanced on failures.

Replace it by the new pm_runtime_resume_and_get(), introduced by:
commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
in order to properly decrement the usage counter, avoiding
a potential PM usage counter leak.

As a bonus, such function always return zero on success. So,
some code can be simplified.

Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/exynos4-is/fimc-capture.c
drivers/media/platform/exynos4-is/fimc-is.c
drivers/media/platform/exynos4-is/fimc-isp-video.c
drivers/media/platform/exynos4-is/fimc-isp.c
drivers/media/platform/exynos4-is/fimc-lite.c
drivers/media/platform/exynos4-is/fimc-m2m.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/mipi-csis.c

index 13c838d..0da3644 100644 (file)
@@ -478,11 +478,9 @@ static int fimc_capture_open(struct file *file)
                goto unlock;
 
        set_bit(ST_CAPT_BUSY, &fimc->state);
-       ret = pm_runtime_get_sync(&fimc->pdev->dev);
-       if (ret < 0) {
-               pm_runtime_put_sync(&fimc->pdev->dev);
+       ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
+       if (ret < 0)
                goto unlock;
-       }
 
        ret = v4l2_fh_open(file);
        if (ret) {
index 972d960..1b24f5b 100644 (file)
@@ -828,9 +828,9 @@ static int fimc_is_probe(struct platform_device *pdev)
                        goto err_irq;
        }
 
-       ret = pm_runtime_get_sync(dev);
+       ret = pm_runtime_resume_and_get(dev);
        if (ret < 0)
-               goto err_pm;
+               goto err_irq;
 
        vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
index 612b987..8d9dc59 100644 (file)
@@ -275,7 +275,7 @@ static int isp_video_open(struct file *file)
        if (ret < 0)
                goto unlock;
 
-       ret = pm_runtime_get_sync(&isp->pdev->dev);
+       ret = pm_runtime_resume_and_get(&isp->pdev->dev);
        if (ret < 0)
                goto rel_fh;
 
@@ -293,7 +293,6 @@ static int isp_video_open(struct file *file)
        if (!ret)
                goto unlock;
 rel_fh:
-       pm_runtime_put_noidle(&isp->pdev->dev);
        v4l2_fh_release(file);
 unlock:
        mutex_unlock(&isp->video_lock);
index a77c49b..74b49d3 100644 (file)
@@ -304,11 +304,10 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
        pr_debug("on: %d\n", on);
 
        if (on) {
-               ret = pm_runtime_get_sync(&is->pdev->dev);
-               if (ret < 0) {
-                       pm_runtime_put(&is->pdev->dev);
+               ret = pm_runtime_resume_and_get(&is->pdev->dev);
+               if (ret < 0)
                        return ret;
-               }
+
                set_bit(IS_ST_PWR_ON, &is->state);
 
                ret = fimc_is_start_firmware(is);
index fe20af3..4d8b180 100644 (file)
@@ -469,9 +469,9 @@ static int fimc_lite_open(struct file *file)
        }
 
        set_bit(ST_FLITE_IN_USE, &fimc->state);
-       ret = pm_runtime_get_sync(&fimc->pdev->dev);
+       ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
        if (ret < 0)
-               goto err_pm;
+               goto err_in_use;
 
        ret = v4l2_fh_open(file);
        if (ret < 0)
@@ -499,6 +499,7 @@ static int fimc_lite_open(struct file *file)
        v4l2_fh_release(file);
 err_pm:
        pm_runtime_put_sync(&fimc->pdev->dev);
+err_in_use:
        clear_bit(ST_FLITE_IN_USE, &fimc->state);
 unlock:
        mutex_unlock(&fimc->lock);
index c9704a1..df8e2aa 100644 (file)
@@ -73,17 +73,14 @@ static void fimc_m2m_shutdown(struct fimc_ctx *ctx)
 static int start_streaming(struct vb2_queue *q, unsigned int count)
 {
        struct fimc_ctx *ctx = q->drv_priv;
-       int ret;
 
-       ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
-       return ret > 0 ? 0 : ret;
+       return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev);
 }
 
 static void stop_streaming(struct vb2_queue *q)
 {
        struct fimc_ctx *ctx = q->drv_priv;
 
-
        fimc_m2m_shutdown(ctx);
        fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
        pm_runtime_put(&ctx->fimc_dev->pdev->dev);
index 13d192b..e025178 100644 (file)
@@ -512,11 +512,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
        if (!fmd->pmf)
                return -ENXIO;
 
-       ret = pm_runtime_get_sync(fmd->pmf);
-       if (ret < 0) {
-               pm_runtime_put(fmd->pmf);
+       ret = pm_runtime_resume_and_get(fmd->pmf);
+       if (ret < 0)
                return ret;
-       }
 
        fmd->num_sensors = 0;
 
@@ -1291,8 +1289,7 @@ static int cam_clk_prepare(struct clk_hw *hw)
        if (camclk->fmd->pmf == NULL)
                return -ENODEV;
 
-       ret = pm_runtime_get_sync(camclk->fmd->pmf);
-       return ret < 0 ? ret : 0;
+       return pm_runtime_resume_and_get(camclk->fmd->pmf);
 }
 
 static void cam_clk_unprepare(struct clk_hw *hw)
index 1aac167..ebf39c8 100644 (file)
@@ -494,7 +494,7 @@ static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
        struct device *dev = &state->pdev->dev;
 
        if (on)
-               return pm_runtime_get_sync(dev);
+               return pm_runtime_resume_and_get(dev);
 
        return pm_runtime_put_sync(dev);
 }
@@ -509,11 +509,9 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
 
        if (enable) {
                s5pcsis_clear_counters(state);
-               ret = pm_runtime_get_sync(&state->pdev->dev);
-               if (ret && ret != 1) {
-                       pm_runtime_put_noidle(&state->pdev->dev);
+               ret = pm_runtime_resume_and_get(&state->pdev->dev);
+               if (ret < 0)
                        return ret;
-               }
        }
 
        mutex_lock(&state->lock);
@@ -535,7 +533,7 @@ unlock:
        if (!enable)
                pm_runtime_put(&state->pdev->dev);
 
-       return ret == 1 ? 0 : ret;
+       return ret;
 }
 
 static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,