MLK-16823-2: mipi_csi: Add runtime suspend/resume
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Wed, 15 Nov 2017 12:13:30 +0000 (20:13 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:50:13 +0000 (14:50 -0500)
Add runtime suspend/resume support for ISI. For saving
power, the ISI turn off it's power domain after probe.

Reviewed-by: Sandor Yu <sandor.yu@nxp.com>
Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
(cherry picked from commit d0cf6f32660c5b03fda5083fee578579f22c4d3b)

drivers/media/platform/imx8/mxc-isi-cap.c
drivers/media/platform/imx8/mxc-isi-core.c
drivers/media/platform/imx8/mxc-isi-core.h

index 954bf12..3ed074b 100644 (file)
@@ -529,10 +529,13 @@ void mxc_isi_ctrls_delete(struct mxc_isi_dev *mxc_isi)
 static int mxc_isi_capture_open(struct file *file)
 {
        struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+       struct device *dev = &mxc_isi->pdev->dev;
        int ret = -EBUSY;
 
        dev_dbg(&mxc_isi->pdev->dev, "%s, ISI%d\n", __func__, mxc_isi->id);
 
+       pm_runtime_get_sync(dev);
+
        mutex_lock(&mxc_isi->lock);
        ret = v4l2_fh_open(file);
        mutex_unlock(&mxc_isi->lock);
@@ -544,6 +547,7 @@ static int mxc_isi_capture_open(struct file *file)
 static int mxc_isi_capture_release(struct file *file)
 {
        struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+       struct device *dev = &mxc_isi->pdev->dev;
        int ret;
 
        dev_dbg(&mxc_isi->pdev->dev, "%s\n", __func__);
@@ -553,6 +557,8 @@ static int mxc_isi_capture_release(struct file *file)
        mutex_unlock(&mxc_isi->lock);
        mxc_isi_channel_deinit(mxc_isi);
 
+       pm_runtime_put_sync(dev);
+
        return ret;
 }
 
@@ -814,6 +820,7 @@ static int mxc_isi_cap_streamoff(struct file *file, void *priv,
 
        ret = vb2_ioctl_streamoff(file, priv, type);
        mxc_isi_channel_disable(mxc_isi);
+
        return ret;
 }
 
index b79976e..1ddf3d9 100644 (file)
@@ -177,6 +177,11 @@ static int mxc_isi_probe(struct platform_device *pdev)
 
        mxc_isi->flags = MXC_ISI_PM_POWERED;
 
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+       pm_runtime_get_sync(dev);
+       pm_runtime_put_sync(dev);
+
        dev_dbg(dev, "mxc_isi.%d registered successfully\n", mxc_isi->id);
 
        return 0;
@@ -189,14 +194,17 @@ err_sclk:
 static int mxc_isi_remove(struct platform_device *pdev)
 {
        struct mxc_isi_dev *mxc_isi = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
 
        mxc_isi_unregister_capture_subdev(mxc_isi);
 
        clk_disable_unprepare(mxc_isi->clk);
+       pm_runtime_disable(dev);
 
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int mxc_isi_pm_suspend(struct device *dev)
 {
        struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
@@ -225,9 +233,42 @@ static int mxc_isi_pm_resume(struct device *dev)
        ret = clk_prepare_enable(mxc_isi->clk);
        return (ret) ? -EAGAIN : 0;
 }
+#endif
+
+static int mxc_isi_runtime_suspend(struct device *dev)
+{
+       struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+
+       if (mxc_isi->flags & MXC_ISI_RUNTIME_SUSPEND)
+               return 0;
+
+       if (mxc_isi->flags & MXC_ISI_PM_POWERED) {
+               clk_disable_unprepare(mxc_isi->clk);
+               mxc_isi->flags |= MXC_ISI_RUNTIME_SUSPEND;
+               mxc_isi->flags &= ~MXC_ISI_PM_POWERED;
+       }
+       return 0;
+}
+
+static int mxc_isi_runtime_resume(struct device *dev)
+{
+       struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+
+       if (mxc_isi->flags & MXC_ISI_PM_POWERED)
+               return 0;
+
+       if (mxc_isi->flags & MXC_ISI_RUNTIME_SUSPEND) {
+               clk_prepare_enable(mxc_isi->clk);
+               mxc_isi->flags |= MXC_ISI_PM_POWERED;
+               mxc_isi->flags &= ~MXC_ISI_RUNTIME_SUSPEND;
+       }
+
+       return 0;
+}
 
 static const struct dev_pm_ops mxc_isi_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(mxc_isi_pm_suspend, mxc_isi_pm_resume)
+       SET_RUNTIME_PM_OPS(mxc_isi_runtime_suspend, mxc_isi_runtime_resume, NULL)
 };
 
 static const struct of_device_id mxc_isi_of_match[] = {
index 52688f9..0c6b11d 100644 (file)
@@ -156,6 +156,7 @@ enum mxc_isi_m2m_in_fmt {
 enum mxc_isi_power_state {
        MXC_ISI_PM_SUSPENDED = 0x01,
        MXC_ISI_PM_POWERED = 0x02,
+       MXC_ISI_RUNTIME_SUSPEND = 0x04,
 };
 
 struct mxc_isi_fmt {