On 4/28/20 6:59 AM, Dmitry Osipenko wrote:
External email: Use caution opening links or attachments
28.04.2020 07:20, Sowjanya Komatineni пишет:
diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c
index b3dd0c3..29ccdae 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -272,8 +272,25 @@ static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable)
struct tegra_vi_channel *chan = v4l2_get_subdev_hostdata(subdev);
struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
struct tegra_csi *csi = csi_chan->csi;
+ int ret;
+
+ if (enable && atomic_add_return(1, &csi->clk_refcnt) == 1) {
+ ret = pm_runtime_get_sync(csi->dev);
+ if (ret < 0) {
+ dev_err(csi->dev,
+ "failed to get runtime PM: %d\n", ret);
+ pm_runtime_put_noidle(csi->dev);
+ atomic_dec(&csi->clk_refcnt);
+ return ret;
+ }
+ }
+
+ ret = csi->ops->csi_streaming(csi_chan, chan->pg_mode, enable);
- return csi->ops->csi_streaming(csi_chan, chan->pg_mode, enable);
+ if ((ret < 0 || !enable) && atomic_dec_and_test(&csi->clk_refcnt))
+ pm_runtime_put_sync(csi->dev);
Runtime PM maintains its own refcount, why these
clk_refcnt/power_on_refcnt are needed?
Streaming is per channel and we can't turn power/clocks off while other
channels may still be running.