]> Pileus Git - ~andy/linux/blobdiff - drivers/media/video/davinci/vpfe_capture.c
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[~andy/linux] / drivers / media / video / davinci / vpfe_capture.c
index 398dbe71cb82aa60ca07e104b84c89f4274b959e..1c2588247289dbf4ce4f8c80c8b3d795e1dcff80 100644 (file)
@@ -475,6 +475,11 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
        ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
        if (!ret)
                vpfe_dev->initialized = 1;
+
+       /* Clear all VPFE/CCDC interrupts */
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(-1);
+
 unlock:
        mutex_unlock(&ccdc_lock);
        return ret;
@@ -534,6 +539,16 @@ static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
        list_del(&vpfe_dev->next_frm->queue);
        vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
        addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
+
+       ccdc_dev->hw_ops.setfbaddr(addr);
+}
+
+static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
+{
+       unsigned long addr;
+
+       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
+       addr += vpfe_dev->field_off;
        ccdc_dev->hw_ops.setfbaddr(addr);
 }
 
@@ -554,7 +569,6 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
 {
        struct vpfe_device *vpfe_dev = dev_id;
        enum v4l2_field field;
-       unsigned long addr;
        int fid;
 
        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
@@ -562,7 +576,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
 
        /* if streaming not started, don't do anything */
        if (!vpfe_dev->started)
-               return IRQ_HANDLED;
+               goto clear_intr;
 
        /* only for 6446 this will be applicable */
        if (NULL != ccdc_dev->hw_ops.reset)
@@ -574,7 +588,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
                        "frame format is progressive...\n");
                if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
                        vpfe_process_buffer_complete(vpfe_dev);
-               return IRQ_HANDLED;
+               goto clear_intr;
        }
 
        /* interlaced or TB capture check which field we are in hardware */
@@ -599,12 +613,9 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
                         * the CCDC memory address
                         */
                        if (field == V4L2_FIELD_SEQ_TB) {
-                               addr =
-                                 videobuf_to_dma_contig(vpfe_dev->cur_frm);
-                               addr += vpfe_dev->field_off;
-                               ccdc_dev->hw_ops.setfbaddr(addr);
+                               vpfe_schedule_bottom_field(vpfe_dev);
                        }
-                       return IRQ_HANDLED;
+                       goto clear_intr;
                }
                /*
                 * if one field is just being captured configure
@@ -624,6 +635,10 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
                 */
                vpfe_dev->field_id = fid;
        }
+clear_intr:
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(irq);
+
        return IRQ_HANDLED;
 }
 
@@ -635,8 +650,11 @@ static irqreturn_t vdint1_isr(int irq, void *dev_id)
        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
 
        /* if streaming not started, don't do anything */
-       if (!vpfe_dev->started)
+       if (!vpfe_dev->started) {
+               if (vpfe_dev->cfg->clr_intr)
+                       vpfe_dev->cfg->clr_intr(irq);
                return IRQ_HANDLED;
+       }
 
        spin_lock(&vpfe_dev->dma_queue_lock);
        if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
@@ -644,6 +662,10 @@ static irqreturn_t vdint1_isr(int irq, void *dev_id)
            vpfe_dev->cur_frm == vpfe_dev->next_frm)
                vpfe_schedule_next_buffer(vpfe_dev);
        spin_unlock(&vpfe_dev->dma_queue_lock);
+
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(irq);
+
        return IRQ_HANDLED;
 }
 
@@ -714,7 +736,7 @@ static int vpfe_release(struct file *file)
        /* Decrement device usrs counter */
        vpfe_dev->usrs--;
        /* Close the priority */
-       v4l2_prio_close(&vpfe_dev->prio, &fh->prio);
+       v4l2_prio_close(&vpfe_dev->prio, fh->prio);
        /* If this is the last file handle */
        if (!vpfe_dev->usrs) {
                vpfe_dev->initialized = 0;
@@ -1218,7 +1240,10 @@ static int vpfe_videobuf_setup(struct videobuf_queue *vq,
        struct vpfe_device *vpfe_dev = fh->vpfe_dev;
 
        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
-       *size = config_params.device_bufsize;
+       *size = vpfe_dev->fmt.fmt.pix.sizeimage;
+       if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
+               vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
+               *size = config_params.device_bufsize;
 
        if (*count < config_params.min_numbuffers)
                *count = config_params.min_numbuffers;
@@ -1233,6 +1258,8 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
 {
        struct vpfe_fh *fh = vq->priv_data;
        struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+       unsigned long addr;
+       int ret;
 
        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
 
@@ -1242,8 +1269,18 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
                vb->height = vpfe_dev->fmt.fmt.pix.height;
                vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
                vb->field = field;
+
+               ret = videobuf_iolock(vq, vb, NULL);;
+               if (ret < 0)
+                       return ret;
+
+               addr = videobuf_to_dma_contig(vb);
+               /* Make sure user addresses are aligned to 32 bytes */
+               if (!ALIGN(addr, 32))
+                       return -EINVAL;
+
+               vb->state = VIDEOBUF_PREPARED;
        }
-       vb->state = VIDEOBUF_PREPARED;
        return 0;
 }
 
@@ -1311,13 +1348,6 @@ static int vpfe_reqbufs(struct file *file, void *priv,
                return -EINVAL;
        }
 
-       if (V4L2_MEMORY_USERPTR == req_buf->memory) {
-               /* we don't support user ptr IO */
-               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
-                        " USERPTR IO not supported\n");
-               return  -EINVAL;
-       }
-
        ret = mutex_lock_interruptible(&vpfe_dev->lock);
        if (ret)
                return ret;
@@ -1831,7 +1861,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
                goto probe_free_dev_mem;
        }
 
-       mutex_lock(&ccdc_lock);
        /* Allocate memory for ccdc configuration */
        ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
        if (NULL == ccdc_cfg) {
@@ -1840,6 +1869,8 @@ static __init int vpfe_probe(struct platform_device *pdev)
                goto probe_free_lock;
        }
 
+       mutex_lock(&ccdc_lock);
+
        strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
        /* Get VINT0 irq resource */
        res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -2015,18 +2046,14 @@ static int __devexit vpfe_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int
-vpfe_suspend(struct device *dev)
+static int vpfe_suspend(struct device *dev)
 {
-       /* add suspend code here later */
-       return -1;
+       return 0;
 }
 
-static int
-vpfe_resume(struct device *dev)
+static int vpfe_resume(struct device *dev)
 {
-       /* add resume code here later */
-       return -1;
+       return 0;
 }
 
 static const struct dev_pm_ops vpfe_dev_pm_ops = {