summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-08-22 14:29:46 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-08-28 05:39:58 -0300
commitf2226a33bf9a431f616b435aa10a9ad4fea1d042 (patch)
tree18b849fa7d314eb0cfe16ea5a89a4446d2bf5624 /drivers/media
parent10d79b995be5399be0a59a72859ac4bfdf066299 (diff)
downloadlinux-f2226a33bf9a431f616b435aa10a9ad4fea1d042.tar.bz2
[media] v4l: vsp1: Add support for RT clock
The VSPR and VSPS instances use two clocks, the VSP1 system clock and the VSP1 realtime clock. Both of them need to be enabled to access the VSP1 registers. Add support for an optional RT clock and enable/disable it along with the system clock. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/vsp1/vsp1.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c40
2 files changed, 36 insertions, 5 deletions
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 11ac94bec3a3..d6c6ecd039ff 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -42,6 +42,7 @@ struct vsp1_device {
void __iomem *mmio;
struct clk *clock;
+ struct clk *rt_clock;
struct mutex lock;
int ref_count;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index aa8b9b288e61..1c9e771aa15c 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -290,6 +290,33 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
return 0;
}
+static int vsp1_clocks_enable(struct vsp1_device *vsp1)
+{
+ int ret;
+
+ ret = clk_prepare_enable(vsp1->clock);
+ if (ret < 0)
+ return ret;
+
+ if (IS_ERR(vsp1->rt_clock))
+ return 0;
+
+ ret = clk_prepare_enable(vsp1->rt_clock);
+ if (ret < 0) {
+ clk_disable_unprepare(vsp1->clock);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void vsp1_clocks_disable(struct vsp1_device *vsp1)
+{
+ if (!IS_ERR(vsp1->rt_clock))
+ clk_disable_unprepare(vsp1->rt_clock);
+ clk_disable_unprepare(vsp1->clock);
+}
+
/*
* vsp1_device_get - Acquire the VSP1 device
*
@@ -307,7 +334,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
if (vsp1->ref_count > 0)
goto done;
- ret = clk_prepare_enable(vsp1->clock);
+ ret = vsp1_clocks_enable(vsp1);
if (ret < 0) {
__vsp1 = NULL;
goto done;
@@ -315,7 +342,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
ret = vsp1_device_init(vsp1);
if (ret < 0) {
- clk_disable_unprepare(vsp1->clock);
+ vsp1_clocks_disable(vsp1);
__vsp1 = NULL;
goto done;
}
@@ -339,7 +366,7 @@ void vsp1_device_put(struct vsp1_device *vsp1)
mutex_lock(&vsp1->lock);
if (--vsp1->ref_count == 0)
- clk_disable_unprepare(vsp1->clock);
+ vsp1_clocks_disable(vsp1);
mutex_unlock(&vsp1->lock);
}
@@ -358,7 +385,7 @@ static int vsp1_pm_suspend(struct device *dev)
if (vsp1->ref_count == 0)
return 0;
- clk_disable_unprepare(vsp1->clock);
+ vsp1_clocks_disable(vsp1);
return 0;
}
@@ -371,7 +398,7 @@ static int vsp1_pm_resume(struct device *dev)
if (vsp1->ref_count)
return 0;
- return clk_prepare_enable(vsp1->clock);
+ return vsp1_clocks_enable(vsp1);
}
#endif
@@ -445,6 +472,9 @@ static int vsp1_probe(struct platform_device *pdev)
return PTR_ERR(vsp1->clock);
}
+ /* The RT clock is optional */
+ vsp1->rt_clock = devm_clk_get(&pdev->dev, "rt");
+
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "missing IRQ\n");