Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / media / video / omap3isp / ispccdc.c
index 80796eb..54a4a3f 100644 (file)
@@ -366,7 +366,7 @@ static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
                dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
                             req->iovm->sgt->nents, DMA_TO_DEVICE);
        if (req->table)
-               iommu_vfree(isp->iommu, req->table);
+               omap_iommu_vfree(isp->domain, isp->iommu, req->table);
        kfree(req);
 }
 
@@ -438,15 +438,15 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
 
                req->enable = 1;
 
-               req->table = iommu_vmalloc(isp->iommu, 0, req->config.size,
-                                          IOMMU_FLAG);
+               req->table = omap_iommu_vmalloc(isp->domain, isp->iommu, 0,
+                                       req->config.size, IOMMU_FLAG);
                if (IS_ERR_VALUE(req->table)) {
                        req->table = 0;
                        ret = -ENOMEM;
                        goto done;
                }
 
-               req->iovm = find_iovm_area(isp->iommu, req->table);
+               req->iovm = omap_find_iovm_area(isp->iommu, req->table);
                if (req->iovm == NULL) {
                        ret = -ENOMEM;
                        goto done;
@@ -462,7 +462,7 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
                dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
                                    req->iovm->sgt->nents, DMA_TO_DEVICE);
 
-               table = da_to_va(isp->iommu, req->table);
+               table = omap_da_to_va(isp->iommu, req->table);
                if (copy_from_user(table, config->lsc, req->config.size)) {
                        ret = -EFAULT;
                        goto done;
@@ -731,18 +731,19 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
 
                        /*
                         * table_new must be 64-bytes aligned, but it's
-                        * already done by iommu_vmalloc().
+                        * already done by omap_iommu_vmalloc().
                         */
                        size = ccdc->fpc.fpnum * 4;
-                       table_new = iommu_vmalloc(isp->iommu, 0, size,
-                                                 IOMMU_FLAG);
+                       table_new = omap_iommu_vmalloc(isp->domain, isp->iommu,
+                                                       0, size, IOMMU_FLAG);
                        if (IS_ERR_VALUE(table_new))
                                return -ENOMEM;
 
-                       if (copy_from_user(da_to_va(isp->iommu, table_new),
+                       if (copy_from_user(omap_da_to_va(isp->iommu, table_new),
                                           (__force void __user *)
                                           ccdc->fpc.fpcaddr, size)) {
-                               iommu_vfree(isp->iommu, table_new);
+                               omap_iommu_vfree(isp->domain, isp->iommu,
+                                                               table_new);
                                return -EFAULT;
                        }
 
@@ -752,7 +753,7 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
 
                ccdc_configure_fpc(ccdc);
                if (table_old != 0)
-                       iommu_vfree(isp->iommu, table_old);
+                       omap_iommu_vfree(isp->domain, isp->iommu, table_old);
        }
 
        return ccdc_lsc_config(ccdc, ccdc_struct);
@@ -1405,11 +1406,14 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
 
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
-       struct video_device *vdev = &ccdc->subdev.devnode;
+       struct isp_pipeline *pipe =
+               to_isp_pipeline(&ccdc->video_out.video.entity);
+       struct video_device *vdev = ccdc->subdev.devnode;
        struct v4l2_event event;
 
        memset(&event, 0, sizeof(event));
-       event.type = V4L2_EVENT_OMAP3ISP_HS_VS;
+       event.type = V4L2_EVENT_FRAME_SYNC;
+       event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number);
 
        v4l2_event_queue(vdev, &event);
 }
@@ -1691,7 +1695,11 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
                                struct v4l2_event_subscription *sub)
 {
-       if (sub->type != V4L2_EVENT_OMAP3ISP_HS_VS)
+       if (sub->type != V4L2_EVENT_FRAME_SYNC)
+               return -EINVAL;
+
+       /* line number is zero at frame start */
+       if (sub->id != 0)
                return -EINVAL;
 
        return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
@@ -1828,7 +1836,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
                 * callers to request an output size bigger than the input size
                 * up to the nearest multiple of 16.
                 */
-               fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
+               fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
                fmt->width &= ~15;
                fmt->height = clamp_t(u32, height, 32, fmt->height);
                break;
@@ -2144,6 +2152,37 @@ static const struct media_entity_operations ccdc_media_ops = {
        .link_setup = ccdc_link_setup,
 };
 
+void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
+{
+       v4l2_device_unregister_subdev(&ccdc->subdev);
+       omap3isp_video_unregister(&ccdc->video_out);
+}
+
+int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
+       struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video node. */
+       ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&ccdc->video_out, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_ccdc_unregister_entities(ccdc);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP CCDC initialisation and cleanup
+ */
+
 /*
  * ccdc_init_entities - Initialize V4L2 subdev and media entity
  * @ccdc: ISP CCDC module
@@ -2185,50 +2224,23 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 
        ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
        if (ret < 0)
-               return ret;
+               goto error_video;
 
        /* Connect the CCDC subdev to the video node. */
        ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
                        &ccdc->video_out.video.entity, 0, 0);
        if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
-{
-       media_entity_cleanup(&ccdc->subdev.entity);
-
-       v4l2_device_unregister_subdev(&ccdc->subdev);
-       omap3isp_video_unregister(&ccdc->video_out);
-}
-
-int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
-       struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video node. */
-       ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&ccdc->video_out, vdev);
-       if (ret < 0)
-               goto error;
+               goto error_link;
 
        return 0;
 
-error:
-       omap3isp_ccdc_unregister_entities(ccdc);
+error_link:
+       omap3isp_video_cleanup(&ccdc->video_out);
+error_video:
+       media_entity_cleanup(me);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP CCDC initialisation and cleanup
- */
-
 /*
  * omap3isp_ccdc_init - CCDC module initialization.
  * @dev: Device pointer specific to the OMAP3 ISP.
@@ -2240,6 +2252,7 @@ error:
 int omap3isp_ccdc_init(struct isp_device *isp)
 {
        struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
+       int ret;
 
        spin_lock_init(&ccdc->lock);
        init_waitqueue_head(&ccdc->wait);
@@ -2268,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp)
        ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
        ccdc_apply_controls(ccdc);
 
-       return ccdc_init_entities(ccdc);
+       ret = ccdc_init_entities(ccdc);
+       if (ret < 0) {
+               mutex_destroy(&ccdc->ioctl_lock);
+               return ret;
+       }
+
+       return 0;
 }
 
 /*
@@ -2279,6 +2298,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
 {
        struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
 
+       omap3isp_video_cleanup(&ccdc->video_out);
+       media_entity_cleanup(&ccdc->subdev.entity);
+
        /* Free LSC requests. As the CCDC is stopped there's no active request,
         * so only the pending request and the free queue need to be handled.
         */
@@ -2287,5 +2309,7 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
        ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
 
        if (ccdc->fpc.fpcaddr != 0)
-               iommu_vfree(isp->iommu, ccdc->fpc.fpcaddr);
+               omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr);
+
+       mutex_destroy(&ccdc->ioctl_lock);
 }