[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20200817220850.401287-5-lkundrak@v3.sk>
Date: Tue, 18 Aug 2020 00:08:50 +0200
From: Lubomir Rintel <lkundrak@...sk>
To: Mauro Carvalho Chehab <mchehab@...nel.org>
Cc: Sakari Ailus <sakari.ailus@....fi>,
Jonathan Corbet <corbet@....net>, linux-media@...r.kernel.org,
linux-kernel@...r.kernel.org, Lubomir Rintel <lkundrak@...sk>
Subject: [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM
On MMP3, the camera block lives on na 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@...sk>
---
Changes since v1:
(all at suggestions from Sakari Ailus)
- s/on na separate/on a separate/ in commit message
- Move clock management into PM callbacks
.../media/platform/marvell-ccic/mcam-core.c | 31 ++-----------
.../media/platform/marvell-ccic/mmp-driver.c | 43 +++++++++++++++++--
2 files changed, 43 insertions(+), 31 deletions(-)
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index 3d4242b8182ba..a967f010341fa 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -24,6 +24,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/videodev2.h>
+#include <linux/pm_runtime.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
@@ -893,30 +894,6 @@ static void mcam_ctlr_power_down(struct mcam_camera *cam)
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
-/* ---------------------------------------------------------------------- */
-/*
- * Controller clocks.
- */
-static void mcam_clk_enable(struct mcam_camera *mcam)
-{
- unsigned int i;
-
- for (i = 0; i < NR_MCAM_CLK; i++) {
- if (!IS_ERR(mcam->clk[i]))
- clk_prepare_enable(mcam->clk[i]);
- }
-}
-
-static void mcam_clk_disable(struct mcam_camera *mcam)
-{
- int i;
-
- for (i = NR_MCAM_CLK - 1; i >= 0; i--) {
- if (!IS_ERR(mcam->clk[i]))
- clk_disable_unprepare(mcam->clk[i]);
- }
-}
-
/* ---------------------------------------------------------------------- */
/*
* Master sensor clock.
@@ -1633,7 +1610,7 @@ static int mcam_v4l_open(struct file *filp)
ret = sensor_call(cam, core, s_power, 1);
if (ret)
goto out;
- mcam_clk_enable(cam);
+ pm_runtime_get_sync(cam->dev);
__mcam_cam_reset(cam);
mcam_set_config_needed(cam, 1);
}
@@ -1656,7 +1633,7 @@ static int mcam_v4l_release(struct file *filp)
if (last_open) {
mcam_disable_mipi(cam);
sensor_call(cam, core, s_power, 0);
- mcam_clk_disable(cam);
+ pm_runtime_put(cam->dev);
if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
mcam_free_dma_bufs(cam);
}
@@ -1977,7 +1954,6 @@ void mccic_suspend(struct mcam_camera *cam)
mcam_ctlr_stop_dma(cam);
sensor_call(cam, core, s_power, 0);
- mcam_clk_disable(cam);
cam->state = cstate;
}
mutex_unlock(&cam->s_mutex);
@@ -1990,7 +1966,6 @@ int mccic_resume(struct mcam_camera *cam)
mutex_lock(&cam->s_mutex);
if (!list_empty(&cam->vdev.fh_list)) {
- mcam_clk_enable(cam);
ret = sensor_call(cam, core, s_power, 1);
if (ret) {
mutex_unlock(&cam->s_mutex);
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 78263e746cad2..c4b28a00a3a24 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", },
--
2.26.2
Powered by blists - more mailing lists