linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM
@ 2020-08-17 22:08 Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device Lubomir Rintel
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Lubomir Rintel @ 2020-08-17 22:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Jonathan Corbet, linux-media, linux-kernel

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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device
  2020-08-17 22:08 [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM Lubomir Rintel
@ 2020-08-17 22:08 ` Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list Lubomir Rintel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Lubomir Rintel @ 2020-08-17 22:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Jonathan Corbet, linux-media, linux-kernel, Lubomir Rintel

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 <lkundrak@v3.sk>
---
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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list
  2020-08-17 22:08 [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device Lubomir Rintel
@ 2020-08-17 22:08 ` Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM Lubomir Rintel
  3 siblings, 0 replies; 5+ messages in thread
From: Lubomir Rintel @ 2020-08-17 22:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Jonathan Corbet, linux-media, linux-kernel, Lubomir Rintel

The solemn reason for this was so that it would be possible to get a
mmp_camera from a platform_device in suspend/resume/remove hooks, because
drvdata used to be used by the v4l core.

Since commit 95db3a60e065 ("[media] v4l: Add a media_device pointer to the
v4l2_device structure") it is no longer case and thus we can make things
a great deal simpler.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
Changes since v1:
- Added this patch

 .../media/platform/marvell-ccic/mmp-driver.c  | 78 ++-----------------
 1 file changed, 8 insertions(+), 70 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 92b92255dac66..f04c01bced2f0 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -46,49 +46,6 @@ static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam)
 	return container_of(mcam, struct mmp_camera, mcam);
 }
 
-/*
- * A silly little infrastructure so we can keep track of our devices.
- * Chances are that we will never have more than one of them, but
- * the Armada 610 *does* have two controllers...
- */
-
-static LIST_HEAD(mmpcam_devices);
-static struct mutex mmpcam_devices_lock;
-
-static void mmpcam_add_device(struct mmp_camera *cam)
-{
-	mutex_lock(&mmpcam_devices_lock);
-	list_add(&cam->devlist, &mmpcam_devices);
-	mutex_unlock(&mmpcam_devices_lock);
-}
-
-static void mmpcam_remove_device(struct mmp_camera *cam)
-{
-	mutex_lock(&mmpcam_devices_lock);
-	list_del(&cam->devlist);
-	mutex_unlock(&mmpcam_devices_lock);
-}
-
-/*
- * Platform dev remove passes us a platform_device, and there's
- * no handy unused drvdata to stash a backpointer in.  So just
- * dig it out of our list.
- */
-static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
-{
-	struct mmp_camera *cam;
-
-	mutex_lock(&mmpcam_devices_lock);
-	list_for_each_entry(cam, &mmpcam_devices, devlist) {
-		if (cam->pdev == pdev) {
-			mutex_unlock(&mmpcam_devices_lock);
-			return cam;
-		}
-	}
-	mutex_unlock(&mmpcam_devices_lock);
-	return NULL;
-}
-
 /*
  * calc the dphy register values
  * There are three dphy registers being used.
@@ -227,6 +184,7 @@ static int mmpcam_probe(struct platform_device *pdev)
 	cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL);
 	if (cam == NULL)
 		return -ENOMEM;
+	platform_set_drvdata(pdev, cam);
 	cam->pdev = pdev;
 	INIT_LIST_HEAD(&cam->devlist);
 
@@ -313,11 +271,10 @@ static int mmpcam_probe(struct platform_device *pdev)
 	cam->irq = res->start;
 	ret = devm_request_irq(&pdev->dev, cam->irq, mmpcam_irq, IRQF_SHARED,
 					"mmp-camera", mcam);
-	if (ret == 0) {
-		mmpcam_add_device(cam);
-		return 0;
-	}
+	if (ret)
+		goto out;
 
+	return 0;
 out:
 	fwnode_handle_put(mcam->asd.match.fwnode);
 	mccic_shutdown(mcam);
@@ -330,14 +287,13 @@ static int mmpcam_remove(struct mmp_camera *cam)
 {
 	struct mcam_camera *mcam = &cam->mcam;
 
-	mmpcam_remove_device(cam);
 	mccic_shutdown(mcam);
 	return 0;
 }
 
 static int mmpcam_platform_remove(struct platform_device *pdev)
 {
-	struct mmp_camera *cam = mmpcam_find_device(pdev);
+	struct mmp_camera *cam = platform_get_drvdata(pdev);
 
 	if (cam == NULL)
 		return -ENODEV;
@@ -351,7 +307,7 @@ static int mmpcam_platform_remove(struct platform_device *pdev)
 
 static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct mmp_camera *cam = mmpcam_find_device(pdev);
+	struct mmp_camera *cam = platform_get_drvdata(pdev);
 
 	if (state.event != PM_EVENT_SUSPEND)
 		return 0;
@@ -361,7 +317,7 @@ static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
 
 static int mmpcam_resume(struct platform_device *pdev)
 {
-	struct mmp_camera *cam = mmpcam_find_device(pdev);
+	struct mmp_camera *cam = platform_get_drvdata(pdev);
 
 	return mccic_resume(&cam->mcam);
 }
@@ -387,22 +343,4 @@ static struct platform_driver mmpcam_driver = {
 	}
 };
 
-
-static int __init mmpcam_init_module(void)
-{
-	mutex_init(&mmpcam_devices_lock);
-	return platform_driver_register(&mmpcam_driver);
-}
-
-static void __exit mmpcam_exit_module(void)
-{
-	platform_driver_unregister(&mmpcam_driver);
-	/*
-	 * platform_driver_unregister() should have emptied the list
-	 */
-	if (!list_empty(&mmpcam_devices))
-		printk(KERN_ERR "mmp_camera leaving devices behind\n");
-}
-
-module_init(mmpcam_init_module);
-module_exit(mmpcam_exit_module);
+module_platform_driver(mmpcam_driver);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops
  2020-08-17 22:08 [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list Lubomir Rintel
@ 2020-08-17 22:08 ` Lubomir Rintel
  2020-08-17 22:08 ` [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM Lubomir Rintel
  3 siblings, 0 replies; 5+ messages in thread
From: Lubomir Rintel @ 2020-08-17 22:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Jonathan Corbet, linux-media, linux-kernel, Lubomir Rintel

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

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM
  2020-08-17 22:08 [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM Lubomir Rintel
                   ` (2 preceding siblings ...)
  2020-08-17 22:08 ` [PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops Lubomir Rintel
@ 2020-08-17 22:08 ` Lubomir Rintel
  3 siblings, 0 replies; 5+ messages in thread
From: Lubomir Rintel @ 2020-08-17 22:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Jonathan Corbet, linux-media, linux-kernel, Lubomir Rintel

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@v3.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-08-17 22:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-17 22:08 [PATCH v2 0/4] media: marvell-ccic: Add support for runtime PM Lubomir Rintel
2020-08-17 22:08 ` [PATCH v2 1/4] media: cafe-driver: use drvdata instead of back-casting from v4l2_device Lubomir Rintel
2020-08-17 22:08 ` [PATCH v2 2/4] media: marvell-ccic: mmp: get rid of mmpcam_devices list Lubomir Rintel
2020-08-17 22:08 ` [PATCH v2 3/4] media: marvell-ccic: mmp: use generic dev_pm_ops Lubomir Rintel
2020-08-17 22:08 ` [PATCH v2 4/4] media: marvell-ccic: add support for runtime PM Lubomir Rintel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).