summaryrefslogtreecommitdiff
path: root/drivers/media/platform/imx8
diff options
context:
space:
mode:
authorRobby Cai <robby.cai@nxp.com>2017-11-22 18:58:59 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commited2f206069e31fd97f8a836000958e071fb87a15 (patch)
treeca0e3e00084258443f02bf166aca5adab419aba6 /drivers/media/platform/imx8
parent4db1b8b464fb0575561883339f29791607acaf30 (diff)
MLK-16943 mipi-csi: Add run time pm support
Add run time PM support for MIPI CSI (tested on iMX8MQ) Signed-off-by: Robby Cai <robby.cai@nxp.com> Reviewed-by: Sandor Yu <Sandor.yu@nxp.com>
Diffstat (limited to 'drivers/media/platform/imx8')
-rw-r--r--drivers/media/platform/imx8/mxc-mipi-csi2_yav.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c b/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c
index a8b89e745007..01fc53e9cf27 100644
--- a/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c
+++ b/drivers/media/platform/imx8/mxc-mipi-csi2_yav.c
@@ -316,6 +316,7 @@ static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on)
static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable)
{
struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
+ struct device *dev = &csi2dev->pdev->dev;
struct v4l2_subdev *sensor_sd = csi2dev->sensor_sd;
int ret = 0;
@@ -324,21 +325,23 @@ static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable)
if (enable) {
if (!csi2dev->running) {
+ pm_runtime_get_sync(dev);
mxc_mipi_csi2_phy_reset(csi2dev);
mxc_mipi_csi2_hc_config(csi2dev);
mxc_mipi_csi2_enable(csi2dev);
mxc_mipi_csi2_reg_dump(csi2dev);
- v4l2_subdev_call(sensor_sd, video, s_stream, true);
}
+ v4l2_subdev_call(sensor_sd, video, s_stream, true);
csi2dev->running++;
} else {
- if (csi2dev->running) {
- v4l2_subdev_call(sensor_sd, video, s_stream, false);
+ v4l2_subdev_call(sensor_sd, video, s_stream, false);
+ csi2dev->running--;
+ if (!csi2dev->running) {
+ pm_runtime_put(dev);
mxc_mipi_csi2_disable(csi2dev);
}
- csi2dev->running--;
}
return ret;
@@ -615,6 +618,7 @@ static int mipi_csi2_probe(struct platform_device *pdev)
csi2dev->running = 0;
csi2dev->flags = MXC_MIPI_CSI2_PM_POWERED;
+ pm_runtime_enable(&pdev->dev);
return 0;
@@ -631,6 +635,30 @@ static int mipi_csi2_remove(struct platform_device *pdev)
struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd);
mipi_csi2_clk_disable(csi2dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int mipi_csi2_pm_runtime_resume(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = mipi_csi2_clk_enable(csi2dev);
+ if (ret < 0) {
+ dev_info(dev, "%s:%d fail\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static int mipi_csi2_runtime_pm_suspend(struct device *dev)
+{
+ struct mxc_mipi_csi2_dev *csi2dev = dev_get_drvdata(dev);
+
+ mipi_csi2_clk_disable(csi2dev);
return 0;
}
@@ -677,6 +705,9 @@ static int mipi_csi2_pm_resume(struct device *dev)
static const struct dev_pm_ops mipi_csi_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(mipi_csi2_pm_suspend, mipi_csi2_pm_resume)
+ SET_RUNTIME_PM_OPS(mipi_csi2_runtime_pm_suspend,
+ mipi_csi2_pm_runtime_resume,
+ NULL)
};
static const struct of_device_id mipi_csi2_of_match[] = {