diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2015-03-09 02:39:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 17:37:19 -0400 |
commit | 3781760a3d2bed2df8ed4cc3d061f8541bf7bd1d (patch) | |
tree | 72bc245c24098b5fcb4d6f331c02f1a6628a0360 | |
parent | 2af12f025870f664244defab14796da2fdb5009e (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.c | 62 |
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 | ||
180 | static 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 | |||
194 | static 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 | |||
180 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( | 204 | const 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 | ||
604 | eadd: | 626 | eadd: |
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 | ||
1203 | static void soc_camera_clk_disable(struct v4l2_clk *clk) | 1215 | static 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); |
1797 | enodrv: | 1805 | enodrv: |
1798 | eadddev: | 1806 | eadddev: |
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 | } |
1803 | eadd: | 1809 | eadd: |
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; |