summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-19 09:07:33 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-19 09:07:33 -0300
commitf2a7801e07fd070a74c3574cfb31f912bfa54113 (patch)
treecf28342776e27702c01ccf9cfbf4d18af47cb073
parent43ea66b6132f9d32464c11b15d5c5b190312d093 (diff)
downloadmediapointer-dvb-s2-f2a7801e07fd070a74c3574cfb31f912bfa54113.tar.gz
mediapointer-dvb-s2-f2a7801e07fd070a74c3574cfb31f912bfa54113.tar.bz2
backport commit 6d1386c6b8db54ac8d94c01194e0c27cd538532b
From: Mauro Carvalho Chehab <mchehab@redhat.com> Author: Magnus Damm <damm@igel.co.jp> Date: Fri Aug 14 10:49:17 2009 +0000 v4l2: Runtime PM for SuperH Mobile CEU This patch modifies the SuperH Mobile CEU driver to support Runtime PM. Driver callbacks for Runtime PM are empty because the device registers are always re-initialized after pm_runtime_get_sync(). The Runtime PM functions replaces the clock framework module stop bit handling in this driver. Priority: normal Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--linux/drivers/media/video/sh_mobile_ceu_camera.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c
index d35f66d8a..7e78202c0 100644
--- a/linux/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c
@@ -30,7 +30,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
@@ -94,7 +94,6 @@ struct sh_mobile_ceu_dev {
unsigned int irq;
void __iomem *base;
- struct clk *clk;
unsigned long video_limit;
/* lock used to protect videobuf */
@@ -406,7 +405,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
"SuperH Mobile CEU driver attached to camera %d\n",
icd->devnum);
- clk_enable(pcdev->clk);
+ pm_runtime_get_sync(ici->dev);
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
while (ceu_read(pcdev, CSTSR) & 1)
@@ -440,7 +439,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
}
spin_unlock_irqrestore(&pcdev->lock, flags);
- clk_disable(pcdev->clk);
+ pm_runtime_put_sync(ici->dev);
dev_info(icd->dev.parent,
"SuperH Mobile CEU driver detached from camera %d\n",
@@ -1650,7 +1649,6 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
struct sh_mobile_ceu_dev *pcdev;
struct resource *res;
void __iomem *base;
- char clk_name[8];
unsigned int irq;
int err = 0;
@@ -1714,13 +1712,9 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit_release_mem;
}
- snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id);
- pcdev->clk = clk_get(&pdev->dev, clk_name);
- if (IS_ERR(pcdev->clk)) {
- dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
- err = PTR_ERR(pcdev->clk);
- goto exit_free_irq;
- }
+ pm_suspend_ignore_children(&pdev->dev, true);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_resume(&pdev->dev);
pcdev->ici.priv = pcdev;
pcdev->ici.v4l2_dev.dev = &pdev->dev;
@@ -1730,12 +1724,10 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
err = soc_camera_host_register(&pcdev->ici);
if (err)
- goto exit_free_clk;
+ goto exit_free_irq;
return 0;
-exit_free_clk:
- clk_put(pcdev->clk);
exit_free_irq:
free_irq(pcdev->irq, pcdev);
exit_release_mem:
@@ -1756,7 +1748,6 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
struct sh_mobile_ceu_dev, ici);
soc_camera_host_unregister(soc_host);
- clk_put(pcdev->clk);
free_irq(pcdev->irq, pcdev);
if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
dma_release_declared_memory(&pdev->dev);
@@ -1765,9 +1756,27 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
return 0;
}
+static int sh_mobile_ceu_runtime_nop(struct device *dev)
+{
+ /* Runtime PM callback shared between ->runtime_suspend()
+ * and ->runtime_resume(). Simply returns success.
+ *
+ * This driver re-initializes all registers after
+ * pm_runtime_get_sync() anyway so there is no need
+ * to save and restore registers here.
+ */
+ return 0;
+}
+
+static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
+ .runtime_suspend = sh_mobile_ceu_runtime_nop,
+ .runtime_resume = sh_mobile_ceu_runtime_nop,
+};
+
static struct platform_driver sh_mobile_ceu_driver = {
.driver = {
.name = "sh_mobile_ceu",
+ .pm = &sh_mobile_ceu_dev_pm_ops,
},
.probe = sh_mobile_ceu_probe,
.remove = __exit_p(sh_mobile_ceu_remove),