diff options
Diffstat (limited to 'drivers/media/video/omap3isp/ispccdc.c')
-rw-r--r-- | drivers/media/video/omap3isp/ispccdc.c | 86 |
1 files changed, 51 insertions, 35 deletions
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index 253fdcce2df2..b0b0fa5a3572 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c | |||
@@ -1836,7 +1836,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
1836 | * callers to request an output size bigger than the input size | 1836 | * callers to request an output size bigger than the input size |
1837 | * up to the nearest multiple of 16. | 1837 | * up to the nearest multiple of 16. |
1838 | */ | 1838 | */ |
1839 | fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15); | 1839 | fmt->width = clamp_t(u32, width, 32, fmt->width + 15); |
1840 | fmt->width &= ~15; | 1840 | fmt->width &= ~15; |
1841 | fmt->height = clamp_t(u32, height, 32, fmt->height); | 1841 | fmt->height = clamp_t(u32, height, 32, fmt->height); |
1842 | break; | 1842 | break; |
@@ -2152,6 +2152,37 @@ static const struct media_entity_operations ccdc_media_ops = { | |||
2152 | .link_setup = ccdc_link_setup, | 2152 | .link_setup = ccdc_link_setup, |
2153 | }; | 2153 | }; |
2154 | 2154 | ||
2155 | void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc) | ||
2156 | { | ||
2157 | v4l2_device_unregister_subdev(&ccdc->subdev); | ||
2158 | omap3isp_video_unregister(&ccdc->video_out); | ||
2159 | } | ||
2160 | |||
2161 | int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc, | ||
2162 | struct v4l2_device *vdev) | ||
2163 | { | ||
2164 | int ret; | ||
2165 | |||
2166 | /* Register the subdev and video node. */ | ||
2167 | ret = v4l2_device_register_subdev(vdev, &ccdc->subdev); | ||
2168 | if (ret < 0) | ||
2169 | goto error; | ||
2170 | |||
2171 | ret = omap3isp_video_register(&ccdc->video_out, vdev); | ||
2172 | if (ret < 0) | ||
2173 | goto error; | ||
2174 | |||
2175 | return 0; | ||
2176 | |||
2177 | error: | ||
2178 | omap3isp_ccdc_unregister_entities(ccdc); | ||
2179 | return ret; | ||
2180 | } | ||
2181 | |||
2182 | /* ----------------------------------------------------------------------------- | ||
2183 | * ISP CCDC initialisation and cleanup | ||
2184 | */ | ||
2185 | |||
2155 | /* | 2186 | /* |
2156 | * ccdc_init_entities - Initialize V4L2 subdev and media entity | 2187 | * ccdc_init_entities - Initialize V4L2 subdev and media entity |
2157 | * @ccdc: ISP CCDC module | 2188 | * @ccdc: ISP CCDC module |
@@ -2193,50 +2224,23 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) | |||
2193 | 2224 | ||
2194 | ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); | 2225 | ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); |
2195 | if (ret < 0) | 2226 | if (ret < 0) |
2196 | return ret; | 2227 | goto error_video; |
2197 | 2228 | ||
2198 | /* Connect the CCDC subdev to the video node. */ | 2229 | /* Connect the CCDC subdev to the video node. */ |
2199 | ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, | 2230 | ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, |
2200 | &ccdc->video_out.video.entity, 0, 0); | 2231 | &ccdc->video_out.video.entity, 0, 0); |
2201 | if (ret < 0) | 2232 | if (ret < 0) |
2202 | return ret; | 2233 | goto error_link; |
2203 | |||
2204 | return 0; | ||
2205 | } | ||
2206 | |||
2207 | void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc) | ||
2208 | { | ||
2209 | media_entity_cleanup(&ccdc->subdev.entity); | ||
2210 | |||
2211 | v4l2_device_unregister_subdev(&ccdc->subdev); | ||
2212 | omap3isp_video_unregister(&ccdc->video_out); | ||
2213 | } | ||
2214 | |||
2215 | int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc, | ||
2216 | struct v4l2_device *vdev) | ||
2217 | { | ||
2218 | int ret; | ||
2219 | |||
2220 | /* Register the subdev and video node. */ | ||
2221 | ret = v4l2_device_register_subdev(vdev, &ccdc->subdev); | ||
2222 | if (ret < 0) | ||
2223 | goto error; | ||
2224 | |||
2225 | ret = omap3isp_video_register(&ccdc->video_out, vdev); | ||
2226 | if (ret < 0) | ||
2227 | goto error; | ||
2228 | 2234 | ||
2229 | return 0; | 2235 | return 0; |
2230 | 2236 | ||
2231 | error: | 2237 | error_link: |
2232 | omap3isp_ccdc_unregister_entities(ccdc); | 2238 | omap3isp_video_cleanup(&ccdc->video_out); |
2239 | error_video: | ||
2240 | media_entity_cleanup(me); | ||
2233 | return ret; | 2241 | return ret; |
2234 | } | 2242 | } |
2235 | 2243 | ||
2236 | /* ----------------------------------------------------------------------------- | ||
2237 | * ISP CCDC initialisation and cleanup | ||
2238 | */ | ||
2239 | |||
2240 | /* | 2244 | /* |
2241 | * omap3isp_ccdc_init - CCDC module initialization. | 2245 | * omap3isp_ccdc_init - CCDC module initialization. |
2242 | * @dev: Device pointer specific to the OMAP3 ISP. | 2246 | * @dev: Device pointer specific to the OMAP3 ISP. |
@@ -2248,6 +2252,7 @@ error: | |||
2248 | int omap3isp_ccdc_init(struct isp_device *isp) | 2252 | int omap3isp_ccdc_init(struct isp_device *isp) |
2249 | { | 2253 | { |
2250 | struct isp_ccdc_device *ccdc = &isp->isp_ccdc; | 2254 | struct isp_ccdc_device *ccdc = &isp->isp_ccdc; |
2255 | int ret; | ||
2251 | 2256 | ||
2252 | spin_lock_init(&ccdc->lock); | 2257 | spin_lock_init(&ccdc->lock); |
2253 | init_waitqueue_head(&ccdc->wait); | 2258 | init_waitqueue_head(&ccdc->wait); |
@@ -2276,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp) | |||
2276 | ccdc->update = OMAP3ISP_CCDC_BLCLAMP; | 2281 | ccdc->update = OMAP3ISP_CCDC_BLCLAMP; |
2277 | ccdc_apply_controls(ccdc); | 2282 | ccdc_apply_controls(ccdc); |
2278 | 2283 | ||
2279 | return ccdc_init_entities(ccdc); | 2284 | ret = ccdc_init_entities(ccdc); |
2285 | if (ret < 0) { | ||
2286 | mutex_destroy(&ccdc->ioctl_lock); | ||
2287 | return ret; | ||
2288 | } | ||
2289 | |||
2290 | return 0; | ||
2280 | } | 2291 | } |
2281 | 2292 | ||
2282 | /* | 2293 | /* |
@@ -2287,6 +2298,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp) | |||
2287 | { | 2298 | { |
2288 | struct isp_ccdc_device *ccdc = &isp->isp_ccdc; | 2299 | struct isp_ccdc_device *ccdc = &isp->isp_ccdc; |
2289 | 2300 | ||
2301 | omap3isp_video_cleanup(&ccdc->video_out); | ||
2302 | media_entity_cleanup(&ccdc->subdev.entity); | ||
2303 | |||
2290 | /* Free LSC requests. As the CCDC is stopped there's no active request, | 2304 | /* Free LSC requests. As the CCDC is stopped there's no active request, |
2291 | * so only the pending request and the free queue need to be handled. | 2305 | * so only the pending request and the free queue need to be handled. |
2292 | */ | 2306 | */ |
@@ -2296,4 +2310,6 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp) | |||
2296 | 2310 | ||
2297 | if (ccdc->fpc.fpcaddr != 0) | 2311 | if (ccdc->fpc.fpcaddr != 0) |
2298 | omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr); | 2312 | omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr); |
2313 | |||
2314 | mutex_destroy(&ccdc->ioctl_lock); | ||
2299 | } | 2315 | } |