add support to use videobuf_iolock() instead of VPIF
defined vpif_uservirt_to_phys API. Use videobuf_to_dma_contig
API for both memory-mapped and userptr buffer allocations.
Correspondingly removed vpif_uservirt_to_phys() VPIF defined API.

Signed-off-by: Manjunath Hadli <manjunath.ha...@ti.com>
---
 drivers/media/video/davinci/vpif_capture.c |  110 +++--------------
 drivers/media/video/davinci/vpif_display.c |  183 ++++++----------------------
 2 files changed, 55 insertions(+), 238 deletions(-)

diff --git a/drivers/media/video/davinci/vpif_capture.c 
b/drivers/media/video/davinci/vpif_capture.c
index 5609e00..63388a3 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -88,52 +88,6 @@ static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 
 /**
- * vpif_uservirt_to_phys : translate user/virtual address to phy address
- * @virtp: user/virtual address
- *
- * This inline function is used to convert user space virtual address to
- * physical address.
- */
-static inline u32 vpif_uservirt_to_phys(u32 virtp)
-{
-       unsigned long physp = 0;
-       struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
-
-       vma = find_vma(mm, virtp);
-
-       /* For kernel direct-mapped memory, take the easy way */
-       if (virtp >= PAGE_OFFSET)
-               physp = virt_to_phys((void *)virtp);
-       else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
-               /**
-                * this will catch, kernel-allocated, mmaped-to-usermode
-                * addresses
-                */
-               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
-       else {
-               /* otherwise, use get_user_pages() for general userland pages */
-               int res, nr_pages = 1;
-                       struct page *pages;
-
-               down_read(&current->mm->mmap_sem);
-
-               res = get_user_pages(current, current->mm,
-                                    virtp, nr_pages, 1, 0, &pages, NULL);
-               up_read(&current->mm->mmap_sem);
-
-               if (res == nr_pages)
-                       physp = __pa(page_address(&pages[0]) +
-                                    (virtp & ~PAGE_MASK));
-               else {
-                       vpif_err("get_user_pages failed\n");
-                       return 0;
-               }
-       }
-       return physp;
-}
-
-/**
  * buffer_prepare :  callback function for buffer prepare
  * @q : buffer queue ptr
  * @vb: ptr to video buffer
@@ -152,7 +106,7 @@ static int vpif_buffer_prepare(struct videobuf_queue *q,
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
        unsigned long addr;
-
+       int ret;
 
        vpif_dbg(2, debug, "vpif_buffer_prepare\n");
 
@@ -162,32 +116,23 @@ static int vpif_buffer_prepare(struct videobuf_queue *q,
        if (VIDEOBUF_NEEDS_INIT == vb->state) {
                vb->width = common->width;
                vb->height = common->height;
-               vb->size = vb->width * vb->height;
+               vb->size = common->fmt.fmt.pix.sizeimage;
                vb->field = field;
-       }
-       vb->state = VIDEOBUF_PREPARED;
-       /**
-        * if user pointer memory mechanism is used, get the physical
-        * address of the buffer
-        */
-       if (V4L2_MEMORY_USERPTR == common->memory) {
-               if (0 == vb->baddr) {
-                       vpif_dbg(1, debug, "buffer address is 0\n");
-                       return -EINVAL;
 
-               }
-               vb->boff = vpif_uservirt_to_phys(vb->baddr);
-               if (!IS_ALIGNED(vb->boff, 8))
+               ret = videobuf_iolock(q, vb, NULL);
+               if (ret < 0)
                        goto exit;
-       }
 
-       addr = vb->boff;
-       if (q->streaming) {
-               if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
-                   !IS_ALIGNED((addr + common->ybtm_off), 8) ||
-                   !IS_ALIGNED((addr + common->ctop_off), 8) ||
-                   !IS_ALIGNED((addr + common->cbtm_off), 8))
-                       goto exit;
+               addr = videobuf_to_dma_contig(vb);
+
+               if (q->streaming) {
+                       if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
+                           !IS_ALIGNED((addr + common->ybtm_off), 8) ||
+                           !IS_ALIGNED((addr + common->ctop_off), 8) ||
+                           !IS_ALIGNED((addr + common->cbtm_off), 8))
+                               goto exit;
+               }
+               vb->state = VIDEOBUF_PREPARED;
        }
        return 0;
 exit:
@@ -334,10 +279,7 @@ static void vpif_schedule_next_buffer(struct common_obj 
*common)
        /* Remove that buffer from the buffer queue */
        list_del(&common->next_frm->queue);
        common->next_frm->state = VIDEOBUF_ACTIVE;
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = common->next_frm->boff;
-       else
-               addr = videobuf_to_dma_contig(common->next_frm);
+       addr = videobuf_to_dma_contig(common->next_frm);
 
        /* Set top and bottom field addresses in VPIF registers */
        common->set_addr(addr + common->ytop_off,
@@ -513,10 +455,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
        } else
                vid_ch->buf_field = common->fmt.fmt.pix.field;
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = common->fmt.fmt.pix.sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = common->fmt.fmt.pix.sizeimage;
 
        hpitch = common->fmt.fmt.pix.bytesperline;
        vpitch = sizeimage / (hpitch * 2);
@@ -668,10 +607,7 @@ static int vpif_check_format(struct channel_obj *ch,
                hpitch = vpif_params->std_info.width;
        }
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = pixfmt->sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = pixfmt->sizeimage;
 
        vpitch = sizeimage / (hpitch * 2);
 
@@ -932,7 +868,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
                                            reqbuf->type,
                                            common->fmt.fmt.pix.field,
                                            sizeof(struct videobuf_buffer), fh,
-                                           &common->lock);
+                                           NULL);
 
        /* Set io allowed member of file handle to TRUE */
        fh->io_allowed[index] = 1;
@@ -1049,10 +985,7 @@ static int vpif_qbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
 
        buf1->state = VIDEOBUF_ACTIVE;
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = buf1->boff;
-       else
-               addr = videobuf_to_dma_contig(buf1);
+       addr = videobuf_to_dma_contig(buf1);
 
        common->next_frm = buf1;
        common->set_addr(addr + common->ytop_off,
@@ -1177,10 +1110,7 @@ static int vpif_streamon(struct file *file, void *priv,
        ch->field_id = 0;
        common->started = 1;
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = common->cur_frm->boff;
-       else
-               addr = videobuf_to_dma_contig(common->cur_frm);
+       addr = videobuf_to_dma_contig(common->cur_frm);
 
        /* Calculate the offset for Y and C data in the buffer */
        vpif_calculate_offsets(ch);
diff --git a/drivers/media/video/davinci/vpif_display.c 
b/drivers/media/video/davinci/vpif_display.c
index 27bc03d..a2b8e1a 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -90,46 +90,6 @@ static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 
 /*
- * vpif_uservirt_to_phys: This function is used to convert user
- * space virtual address to physical address.
- */
-static u32 vpif_uservirt_to_phys(u32 virtp)
-{
-       struct mm_struct *mm = current->mm;
-       unsigned long physp = 0;
-       struct vm_area_struct *vma;
-
-       vma = find_vma(mm, virtp);
-
-       /* For kernel direct-mapped memory, take the easy way */
-       if (virtp >= PAGE_OFFSET) {
-               physp = virt_to_phys((void *)virtp);
-       } else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
-               /* this will catch, kernel-allocated, mmaped-to-usermode addr */
-               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
-       } else {
-               /* otherwise, use get_user_pages() for general userland pages */
-               int res, nr_pages = 1;
-               struct page *pages;
-               down_read(&current->mm->mmap_sem);
-
-               res = get_user_pages(current, current->mm,
-                                    virtp, nr_pages, 1, 0, &pages, NULL);
-               up_read(&current->mm->mmap_sem);
-
-               if (res == nr_pages) {
-                       physp = __pa(page_address(&pages[0]) +
-                                                       (virtp & ~PAGE_MASK));
-               } else {
-                       vpif_err("get_user_pages failed\n");
-                       return 0;
-               }
-       }
-
-       return physp;
-}
-
-/*
  * buffer_prepare: This is the callback function called from videobuf_qbuf()
  * function the buffer is prepared and user space virtual address is converted
  * into physical address
@@ -141,36 +101,30 @@ static int vpif_buffer_prepare(struct videobuf_queue *q,
        struct vpif_fh *fh = q->priv_data;
        struct common_obj *common;
        unsigned long addr;
+       int ret;
 
        common = &fh->channel->common[VPIF_VIDEO_INDEX];
        if (VIDEOBUF_NEEDS_INIT == vb->state) {
                vb->width       = common->width;
                vb->height      = common->height;
-               vb->size        = vb->width * vb->height;
+               /* Updating the size based on the application requirement */
+               vb->size        = common->fmt.fmt.pix.sizeimage;
                vb->field       = field;
-       }
-       vb->state = VIDEOBUF_PREPARED;
 
-       /* if user pointer memory mechanism is used, get the physical
-        * address of the buffer */
-       if (V4L2_MEMORY_USERPTR == common->memory) {
-               if (!vb->baddr) {
-                       vpif_err("buffer_address is 0\n");
-                       return -EINVAL;
-               }
-
-               vb->boff = vpif_uservirt_to_phys(vb->baddr);
-               if (!ISALIGNED(vb->boff))
+               ret = videobuf_iolock(q, vb, NULL);
+               if (ret < 0)
                        goto buf_align_exit;
-       }
 
-       addr = vb->boff;
-       if (q->streaming && (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
-               if (!ISALIGNED(addr + common->ytop_off) ||
-                   !ISALIGNED(addr + common->ybtm_off) ||
-                   !ISALIGNED(addr + common->ctop_off) ||
-                   !ISALIGNED(addr + common->cbtm_off))
-                       goto buf_align_exit;
+               addr = videobuf_to_dma_contig(vb);
+               if (q->streaming &&
+                       (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
+                       if (!ISALIGNED(addr + common->ytop_off) ||
+                           !ISALIGNED(addr + common->ybtm_off) ||
+                           !ISALIGNED(addr + common->ctop_off) ||
+                           !ISALIGNED(addr + common->cbtm_off))
+                               goto buf_align_exit;
+               }
+               vb->state = VIDEOBUF_PREPARED;
        }
        return 0;
 
@@ -247,7 +201,9 @@ static void vpif_buffer_release(struct videobuf_queue *q,
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
-       videobuf_dma_contig_free(q, vb);
+       if (V4L2_MEMORY_USERPTR != vb->memory)
+               videobuf_dma_contig_free(q, vb);
+
        vb->state = VIDEOBUF_NEEDS_INIT;
 
        if (V4L2_MEMORY_MMAP != common->memory)
@@ -472,10 +428,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
                vid_ch->buf_field = common->fmt.fmt.pix.field;
        }
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = common->fmt.fmt.pix.sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = common->fmt.fmt.pix.sizeimage;
 
        hpitch = common->fmt.fmt.pix.bytesperline;
        vpitch = sizeimage / (hpitch * 2);
@@ -552,10 +505,7 @@ static int vpif_check_format(struct channel_obj *ch,
        if (pixfmt->bytesperline <= 0)
                goto invalid_pitch_exit;
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = pixfmt->sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = pixfmt->sizeimage;
 
        if (vpif_update_resolution(ch))
                return -EINVAL;
@@ -875,7 +825,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
                                            &common->irqlock,
                                            reqbuf->type, field,
                                            sizeof(struct videobuf_buffer), fh,
-                                           &common->lock);
+                                           NULL);
 
        /* Set io allowed member of file handle to TRUE */
        fh->io_allowed[index] = 1;
@@ -904,17 +854,20 @@ static int vpif_querybuf(struct file *file, void *priv,
 
 static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 {
+       struct vpif_fh *fh = NULL;
+       struct channel_obj *ch = NULL;
+       struct common_obj *common = NULL;
 
-       struct vpif_fh *fh = priv;
-       struct channel_obj *ch = fh->channel;
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct v4l2_buffer tbuf = *buf;
-       struct videobuf_buffer *buf1;
-       unsigned long addr = 0;
-       unsigned long flags;
-       int ret = 0;
+       if (!buf || !priv)
+               return -EINVAL;
 
-       if (common->fmt.type != tbuf.type)
+       fh = priv;
+       ch = fh->channel;
+       if (!ch)
+               return -EINVAL;
+
+       common = &(ch->common[VPIF_VIDEO_INDEX]);
+       if (common->fmt.type != buf->type)
                return -EINVAL;
 
        if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
@@ -922,73 +875,7 @@ static int vpif_qbuf(struct file *file, void *priv, struct 
v4l2_buffer *buf)
                return -EACCES;
        }
 
-       if (!(list_empty(&common->dma_queue)) ||
-           (common->cur_frm != common->next_frm) ||
-           !(common->started) ||
-           (common->started && (0 == ch->field_id)))
-               return videobuf_qbuf(&common->buffer_queue, buf);
-
-       /* bufferqueue is empty store buffer address in VPIF registers */
-       mutex_lock(&common->buffer_queue.vb_lock);
-       buf1 = common->buffer_queue.bufs[tbuf.index];
-       if (buf1->memory != tbuf.memory) {
-               vpif_err("invalid buffer type\n");
-               goto qbuf_exit;
-       }
-
-       if ((buf1->state == VIDEOBUF_QUEUED) ||
-           (buf1->state == VIDEOBUF_ACTIVE)) {
-               vpif_err("invalid state\n");
-               goto qbuf_exit;
-       }
-
-       switch (buf1->memory) {
-       case V4L2_MEMORY_MMAP:
-               if (buf1->baddr == 0)
-                       goto qbuf_exit;
-               break;
-
-       case V4L2_MEMORY_USERPTR:
-               if (tbuf.length < buf1->bsize)
-                       goto qbuf_exit;
-
-               if ((VIDEOBUF_NEEDS_INIT != buf1->state)
-                           && (buf1->baddr != tbuf.m.userptr)) {
-                       vpif_buffer_release(&common->buffer_queue, buf1);
-                       buf1->baddr = tbuf.m.userptr;
-               }
-               break;
-
-       default:
-               goto qbuf_exit;
-       }
-
-       local_irq_save(flags);
-       ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
-                                       common->buffer_queue.field);
-       if (ret < 0) {
-               local_irq_restore(flags);
-               goto qbuf_exit;
-       }
-
-       buf1->state = VIDEOBUF_ACTIVE;
-       addr = buf1->boff;
-       common->next_frm = buf1;
-       if (tbuf.type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
-               common->set_addr((addr + common->ytop_off),
-                                (addr + common->ybtm_off),
-                                (addr + common->ctop_off),
-                                (addr + common->cbtm_off));
-       }
-
-       local_irq_restore(flags);
-       list_add_tail(&buf1->stream, &common->buffer_queue.stream);
-       mutex_unlock(&common->buffer_queue.vb_lock);
-       return 0;
-
-qbuf_exit:
-       mutex_unlock(&common->buffer_queue.vb_lock);
-       return -EINVAL;
+       return videobuf_qbuf(&common->buffer_queue, buf);
 }
 
 static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
@@ -1127,7 +1014,7 @@ static int vpif_streamon(struct file *file, void *priv,
        ch->field_id = 0;
        common->started = 1;
        if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-               addr = common->cur_frm->boff;
+               addr = videobuf_to_dma_contig(common->cur_frm);
                /* Calculate the offset for Y and C data  in the buffer */
                vpif_calculate_offsets(ch);
 
-- 
1.7.4.1

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to