aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2015-03-09 02:39:34 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 17:37:19 -0400
commit3781760a3d2bed2df8ed4cc3d061f8541bf7bd1d (patch)
tree72bc245c24098b5fcb4d6f331c02f1a6628a0360
parent2af12f025870f664244defab14796da2fdb5009e (diff)
[media] soc-camera: Make clock_start and clock_stop operations optional
Instead of forcing drivers to implement empty clock operations, make them optional. v4l2 clock registration in the soc-camera core should probably be conditionned on the availability of those operations, but careful review and/or testing of all drivers would be needed, so that should be a separate step. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c62
1 files changed, 33 insertions, 29 deletions
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 2a400d424637..78251329ed9f 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -177,6 +177,30 @@ static int __soc_camera_power_off(struct soc_camera_device *icd)
177 return 0; 177 return 0;
178} 178}
179 179
180static int soc_camera_clock_start(struct soc_camera_host *ici)
181{
182 int ret;
183
184 if (!ici->ops->clock_start)
185 return 0;
186
187 mutex_lock(&ici->clk_lock);
188 ret = ici->ops->clock_start(ici);
189 mutex_unlock(&ici->clk_lock);
190
191 return ret;
192}
193
194static void soc_camera_clock_stop(struct soc_camera_host *ici)
195{
196 if (!ici->ops->clock_stop)
197 return;
198
199 mutex_lock(&ici->clk_lock);
200 ici->ops->clock_stop(ici);
201 mutex_unlock(&ici->clk_lock);
202}
203
180const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 204const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
181 struct soc_camera_device *icd, unsigned int fourcc) 205 struct soc_camera_device *icd, unsigned int fourcc)
182{ 206{
@@ -584,9 +608,7 @@ static int soc_camera_add_device(struct soc_camera_device *icd)
584 return -EBUSY; 608 return -EBUSY;
585 609
586 if (!icd->clk) { 610 if (!icd->clk) {
587 mutex_lock(&ici->clk_lock); 611 ret = soc_camera_clock_start(ici);
588 ret = ici->ops->clock_start(ici);
589 mutex_unlock(&ici->clk_lock);
590 if (ret < 0) 612 if (ret < 0)
591 return ret; 613 return ret;
592 } 614 }
@@ -602,11 +624,8 @@ static int soc_camera_add_device(struct soc_camera_device *icd)
602 return 0; 624 return 0;
603 625
604eadd: 626eadd:
605 if (!icd->clk) { 627 if (!icd->clk)
606 mutex_lock(&ici->clk_lock); 628 soc_camera_clock_stop(ici);
607 ici->ops->clock_stop(ici);
608 mutex_unlock(&ici->clk_lock);
609 }
610 return ret; 629 return ret;
611} 630}
612 631
@@ -619,11 +638,8 @@ static void soc_camera_remove_device(struct soc_camera_device *icd)
619 638
620 if (ici->ops->remove) 639 if (ici->ops->remove)
621 ici->ops->remove(icd); 640 ici->ops->remove(icd);
622 if (!icd->clk) { 641 if (!icd->clk)
623 mutex_lock(&ici->clk_lock); 642 soc_camera_clock_stop(ici);
624 ici->ops->clock_stop(ici);
625 mutex_unlock(&ici->clk_lock);
626 }
627 ici->icd = NULL; 643 ici->icd = NULL;
628} 644}
629 645
@@ -1180,7 +1196,6 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk)
1180{ 1196{
1181 struct soc_camera_device *icd = clk->priv; 1197 struct soc_camera_device *icd = clk->priv;
1182 struct soc_camera_host *ici; 1198 struct soc_camera_host *ici;
1183 int ret;
1184 1199
1185 if (!icd || !icd->parent) 1200 if (!icd || !icd->parent)
1186 return -ENODEV; 1201 return -ENODEV;
@@ -1194,10 +1209,7 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk)
1194 * If a different client is currently being probed, the host will tell 1209 * If a different client is currently being probed, the host will tell
1195 * you to go 1210 * you to go
1196 */ 1211 */
1197 mutex_lock(&ici->clk_lock); 1212 return soc_camera_clock_start(ici);
1198 ret = ici->ops->clock_start(ici);
1199 mutex_unlock(&ici->clk_lock);
1200 return ret;
1201} 1213}
1202 1214
1203static void soc_camera_clk_disable(struct v4l2_clk *clk) 1215static void soc_camera_clk_disable(struct v4l2_clk *clk)
@@ -1210,9 +1222,7 @@ static void soc_camera_clk_disable(struct v4l2_clk *clk)
1210 1222
1211 ici = to_soc_camera_host(icd->parent); 1223 ici = to_soc_camera_host(icd->parent);
1212 1224
1213 mutex_lock(&ici->clk_lock); 1225 soc_camera_clock_stop(ici);
1214 ici->ops->clock_stop(ici);
1215 mutex_unlock(&ici->clk_lock);
1216 1226
1217 module_put(ici->ops->owner); 1227 module_put(ici->ops->owner);
1218} 1228}
@@ -1754,9 +1764,7 @@ static int soc_camera_probe(struct soc_camera_host *ici,
1754 ret = -EINVAL; 1764 ret = -EINVAL;
1755 goto eadd; 1765 goto eadd;
1756 } else { 1766 } else {
1757 mutex_lock(&ici->clk_lock); 1767 ret = soc_camera_clock_start(ici);
1758 ret = ici->ops->clock_start(ici);
1759 mutex_unlock(&ici->clk_lock);
1760 if (ret < 0) 1768 if (ret < 0)
1761 goto eadd; 1769 goto eadd;
1762 1770
@@ -1796,9 +1804,7 @@ efinish:
1796 module_put(control->driver->owner); 1804 module_put(control->driver->owner);
1797enodrv: 1805enodrv:
1798eadddev: 1806eadddev:
1799 mutex_lock(&ici->clk_lock); 1807 soc_camera_clock_stop(ici);
1800 ici->ops->clock_stop(ici);
1801 mutex_unlock(&ici->clk_lock);
1802 } 1808 }
1803eadd: 1809eadd:
1804 if (icd->vdev) { 1810 if (icd->vdev) {
@@ -1936,8 +1942,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1936 ((!ici->ops->init_videobuf || 1942 ((!ici->ops->init_videobuf ||
1937 !ici->ops->reqbufs) && 1943 !ici->ops->reqbufs) &&
1938 !ici->ops->init_videobuf2) || 1944 !ici->ops->init_videobuf2) ||
1939 !ici->ops->clock_start ||
1940 !ici->ops->clock_stop ||
1941 !ici->ops->poll || 1945 !ici->ops->poll ||
1942 !ici->v4l2_dev.dev) 1946 !ici->v4l2_dev.dev)
1943 return -EINVAL; 1947 return -EINVAL;