提交 6d1386c6 编写于 作者: M Magnus Damm 提交者: Paul Mundt

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.
Signed-off-by: NMagnus Damm <damm@igel.co.jp>
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 0246c471
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/clk.h> #include <linux/pm_runtime.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-dev.h> #include <media/v4l2-dev.h>
...@@ -86,7 +86,6 @@ struct sh_mobile_ceu_dev { ...@@ -86,7 +86,6 @@ struct sh_mobile_ceu_dev {
unsigned int irq; unsigned int irq;
void __iomem *base; void __iomem *base;
struct clk *clk;
unsigned long video_limit; unsigned long video_limit;
/* lock used to protect videobuf */ /* lock used to protect videobuf */
...@@ -361,7 +360,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) ...@@ -361,7 +360,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
if (ret) if (ret)
goto err; goto err;
clk_enable(pcdev->clk); pm_runtime_get_sync(ici->dev);
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
while (ceu_read(pcdev, CSTSR) & 1) while (ceu_read(pcdev, CSTSR) & 1)
...@@ -395,7 +394,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ...@@ -395,7 +394,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
} }
spin_unlock_irqrestore(&pcdev->lock, flags); spin_unlock_irqrestore(&pcdev->lock, flags);
clk_disable(pcdev->clk); pm_runtime_put_sync(ici->dev);
icd->ops->release(icd); icd->ops->release(icd);
...@@ -798,7 +797,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -798,7 +797,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
struct sh_mobile_ceu_dev *pcdev; struct sh_mobile_ceu_dev *pcdev;
struct resource *res; struct resource *res;
void __iomem *base; void __iomem *base;
char clk_name[8];
unsigned int irq; unsigned int irq;
int err = 0; int err = 0;
...@@ -862,13 +860,9 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -862,13 +860,9 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit_release_mem; goto exit_release_mem;
} }
snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id); pm_suspend_ignore_children(&pdev->dev, true);
pcdev->clk = clk_get(&pdev->dev, clk_name); pm_runtime_enable(&pdev->dev);
if (IS_ERR(pcdev->clk)) { pm_runtime_resume(&pdev->dev);
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
err = PTR_ERR(pcdev->clk);
goto exit_free_irq;
}
pcdev->ici.priv = pcdev; pcdev->ici.priv = pcdev;
pcdev->ici.dev = &pdev->dev; pcdev->ici.dev = &pdev->dev;
...@@ -878,12 +872,10 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -878,12 +872,10 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
err = soc_camera_host_register(&pcdev->ici); err = soc_camera_host_register(&pcdev->ici);
if (err) if (err)
goto exit_free_clk; goto exit_free_irq;
return 0; return 0;
exit_free_clk:
clk_put(pcdev->clk);
exit_free_irq: exit_free_irq:
free_irq(pcdev->irq, pcdev); free_irq(pcdev->irq, pcdev);
exit_release_mem: exit_release_mem:
...@@ -904,7 +896,6 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev) ...@@ -904,7 +896,6 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev)
struct sh_mobile_ceu_dev, ici); struct sh_mobile_ceu_dev, ici);
soc_camera_host_unregister(soc_host); soc_camera_host_unregister(soc_host);
clk_put(pcdev->clk);
free_irq(pcdev->irq, pcdev); free_irq(pcdev->irq, pcdev);
if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
dma_release_declared_memory(&pdev->dev); dma_release_declared_memory(&pdev->dev);
...@@ -913,9 +904,27 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev) ...@@ -913,9 +904,27 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver sh_mobile_ceu_driver = {
.driver = { .driver = {
.name = "sh_mobile_ceu", .name = "sh_mobile_ceu",
.pm = &sh_mobile_ceu_dev_pm_ops,
}, },
.probe = sh_mobile_ceu_probe, .probe = sh_mobile_ceu_probe,
.remove = sh_mobile_ceu_remove, .remove = sh_mobile_ceu_remove,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册