summaryrefslogtreecommitdiff
path: root/drivers/media/platform/marvell-ccic/mmp-driver.c
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2020-08-18 01:08:50 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-08-29 09:10:02 +0300
commit55cd34524aa37601a20cdb0f40c2047c57aa657b (patch)
tree316cc522378d52ca59fc08d5add06e84deb76e7a /drivers/media/platform/marvell-ccic/mmp-driver.c
parent9ac7400f49213ec107cc759bad5ab8a6f64684d6 (diff)
downloadlinux-55cd34524aa37601a20cdb0f40c2047c57aa657b.tar.xz
media: marvell-ccic: add support for runtime PM
On MMP3, the camera block lives on a separate power island. We want to turn it off if the CCIC is not in use to conserve power. Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/platform/marvell-ccic/mmp-driver.c')
-rw-r--r--drivers/media/platform/marvell-ccic/mmp-driver.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 78263e746cad..c4b28a00a3a2 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -20,6 +20,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/pm.h>
@@ -274,6 +275,7 @@ static int mmpcam_probe(struct platform_device *pdev)
if (ret)
goto out;
+ pm_runtime_enable(&pdev->dev);
return 0;
out:
fwnode_handle_put(mcam->asd.match.fwnode);
@@ -288,6 +290,7 @@ static int mmpcam_remove(struct mmp_camera *cam)
struct mcam_camera *mcam = &cam->mcam;
mccic_shutdown(mcam);
+ pm_runtime_force_suspend(mcam->dev);
return 0;
}
@@ -304,11 +307,40 @@ static int mmpcam_platform_remove(struct platform_device *pdev)
* Suspend/resume support.
*/
+static int mmpcam_runtime_resume(struct device *dev)
+{
+ struct mmp_camera *cam = dev_get_drvdata(dev);
+ struct mcam_camera *mcam = &cam->mcam;
+ unsigned int i;
+
+ for (i = 0; i < NR_MCAM_CLK; i++) {
+ if (!IS_ERR(mcam->clk[i]))
+ clk_prepare_enable(mcam->clk[i]);
+ }
+
+ return 0;
+}
+
+static int mmpcam_runtime_suspend(struct device *dev)
+{
+ struct mmp_camera *cam = dev_get_drvdata(dev);
+ struct mcam_camera *mcam = &cam->mcam;
+ int i;
+
+ for (i = NR_MCAM_CLK - 1; i >= 0; i--) {
+ if (!IS_ERR(mcam->clk[i]))
+ clk_disable_unprepare(mcam->clk[i]);
+ }
+
+ return 0;
+}
+
static int mmpcam_suspend(struct device *dev)
{
struct mmp_camera *cam = dev_get_drvdata(dev);
- mccic_suspend(&cam->mcam);
+ if (!pm_runtime_suspended(dev))
+ mccic_suspend(&cam->mcam);
return 0;
}
@@ -316,10 +348,15 @@ static int mmpcam_resume(struct device *dev)
{
struct mmp_camera *cam = dev_get_drvdata(dev);
- return mccic_resume(&cam->mcam);
+ if (!pm_runtime_suspended(dev))
+ return mccic_resume(&cam->mcam);
+ return 0;
}
-static SIMPLE_DEV_PM_OPS(mmpcam_pm_ops, mmpcam_suspend, mmpcam_resume);
+static const struct dev_pm_ops mmpcam_pm_ops = {
+ SET_RUNTIME_PM_OPS(mmpcam_runtime_suspend, mmpcam_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(mmpcam_suspend, mmpcam_resume)
+};
static const struct of_device_id mmpcam_of_match[] = {
{ .compatible = "marvell,mmp2-ccic", },