]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
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)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 13 Aug 2021 07:29:57 +0000 (09:29 +0200)
BugLink: https://bugs.launchpad.net/bugs/1938340
[ Upstream commit 59f96244af9403ddf4810ec5c0fbe8920857634e ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
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 13c838d3f94730e0a7eebe1abca74f8c883df06d..0da36443173c1acecd2da7f86affd7a1a342e26b 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 972d9601d23602479446f2a804e8430751c4dca1..1b24f5bfc4af4d70cc1d9133cc3756c82ec7aba3 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 612b9872afc87199870bb2660da83b7922d1a686..8d9dc597deaafa5785af3096a52c27b4af936cf0 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 a77c49b1851151644cefbcd74d718f245412d833..74b49d30901ed634d42b6c744fa9487398f5093b 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 fe20af3a7178afef2713bb213787ebb949617358..4d8b18078ff379704fb136938bfe2c2b90a31eb6 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 c9704a147e5cfc203003bd2c3ca10ea35548e146..df8e2aa454d8fa920b3cfcc3d9fd213ef85f504a 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 e636c33e847bd6cb0832e25075285f2302e9df71..1272f4703b817b26a389d1a4c94c4bafe7c6d9e7 100644 (file)
@@ -508,11 +508,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;
 
@@ -1287,8 +1285,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 1aac167abb175a61835dbf21777bd1caf5d3bfd3..ebf39c8568943085e27a878ce524091fbfb49009 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,