2020-08-17 23:19:48

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM

This is a second version of the patch set that enable runtime PM for
mmp-camera. The ultimate goal is to conserve power on MMP3 where the
camera block lives on a separate power island whose genpd should be
turned off when the camera is not in use.

The previous version of the set contained only one patch, that is now
last in the set. It was modified to move clock handling to the runtime
PM callbacks:

[PATCH v2 4/4] media: marvell-ccic: add support for runtime PM

The previous two are new and they lay foundation for the patch 4/4:

[PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list
[PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops

The first one is not strictly related to the rest, it just makes things
a bit nicer for the version of marvell-ccic found on the Cafe chip and
consistent with what's done for mmp-camera:

[PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting

Please take a look and consider applying.

Thank you
Lubo


2020-08-17 23:20:00

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops

This simplifies things a bit and makes adding runtime PM a more
straightforward.

Signed-off-by: Lubomir Rintel <[email protected]>
---
Changes since v1:
- Added this patch

.../media/platform/marvell-ccic/mmp-driver.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index f04c01bced2f0..78263e746cad2 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -303,26 +303,23 @@ static int mmpcam_platform_remove(struct platform_device *pdev)
/*
* Suspend/resume support.
*/
-#ifdef CONFIG_PM

-static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
+static int mmpcam_suspend(struct device *dev)
{
- struct mmp_camera *cam = platform_get_drvdata(pdev);
+ struct mmp_camera *cam = dev_get_drvdata(dev);

- if (state.event != PM_EVENT_SUSPEND)
- return 0;
mccic_suspend(&cam->mcam);
return 0;
}

-static int mmpcam_resume(struct platform_device *pdev)
+static int mmpcam_resume(struct device *dev)
{
- struct mmp_camera *cam = platform_get_drvdata(pdev);
+ struct mmp_camera *cam = dev_get_drvdata(dev);

return mccic_resume(&cam->mcam);
}

-#endif
+static SIMPLE_DEV_PM_OPS(mmpcam_pm_ops, mmpcam_suspend, mmpcam_resume);

static const struct of_device_id mmpcam_of_match[] = {
{ .compatible = "marvell,mmp2-ccic", },
@@ -333,13 +330,10 @@ MODULE_DEVICE_TABLE(of, mmpcam_of_match);
static struct platform_driver mmpcam_driver = {
.probe = mmpcam_probe,
.remove = mmpcam_platform_remove,
-#ifdef CONFIG_PM
- .suspend = mmpcam_suspend,
- .resume = mmpcam_resume,
-#endif
.driver = {
.name = "mmp-camera",
.of_match_table = of_match_ptr(mmpcam_of_match),
+ .pm = &mmpcam_pm_ops,
}
};

--
2.26.2

2020-08-17 23:20:05

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device

Since commit commit 95db3a60e065 ("[media] v4l: Add a media_device pointer
to the v4l2_device structure") the v4l core doesn't insist on using drvdata
itself. Therefore we can use it ourselves, making things somewhat simpler.

Signed-off-by: Lubomir Rintel <[email protected]>
---
Changes since v1:
- Added this patch

drivers/media/platform/marvell-ccic/cafe-driver.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index 58b9915ac7a40..00f623d62c962 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -497,6 +497,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
if (cam == NULL)
goto out;
+ pci_set_drvdata(pdev, cam);
cam->pdev = pdev;
mcam = &cam->mcam;
mcam->chip_id = MCAM_CAFE;
@@ -592,8 +593,7 @@ static void cafe_shutdown(struct cafe_camera *cam)

static void cafe_pci_remove(struct pci_dev *pdev)
{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
+ struct cafe_camera *cam = pci_get_drvdata(pdev);

if (cam == NULL) {
printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
@@ -609,8 +609,7 @@ static void cafe_pci_remove(struct pci_dev *pdev)
*/
static int __maybe_unused cafe_pci_suspend(struct device *dev)
{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
+ struct cafe_camera *cam = dev_get_drvdata(dev);

mccic_suspend(&cam->mcam);
return 0;
@@ -619,8 +618,7 @@ static int __maybe_unused cafe_pci_suspend(struct device *dev)

static int __maybe_unused cafe_pci_resume(struct device *dev)
{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
+ struct cafe_camera *cam = dev_get_drvdata(dev);

cafe_ctlr_init(&cam->mcam);
return mccic_resume(&cam->mcam);
--
2.26.2

2020-08-17 23:20:11

by Lubomir Rintel

[permalink] [raw]
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 <[email protected]>

---
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