Vaibhav, There are changes to vpfe capture on Arago tree on top of this. For example, vpfe_uservirt_to_phys() is removed and is replaced with videobuf_iolock(). So please get the latest changes to upstream. Murali On Tue, Feb 23, 2010 at 3:34 AM, <hvaibhav@xxxxxx> wrote: > From: Vaibhav Hiremath <hvaibhav@xxxxxx> > > > Signed-off-by: Vaibhav Hiremath <hvaibhav@xxxxxx> > Signed-off-by: Muralidharan Karicheri <m-karicheri2@xxxxxx> > --- > drivers/media/video/ti-media/vpfe_capture.c | 94 ++++++++++++++++++++++---- > 1 files changed, 79 insertions(+), 15 deletions(-) > > diff --git a/drivers/media/video/ti-media/vpfe_capture.c b/drivers/media/video/ti-media/vpfe_capture.c > index cece265..7d4ab44 100644 > --- a/drivers/media/video/ti-media/vpfe_capture.c > +++ b/drivers/media/video/ti-media/vpfe_capture.c > @@ -538,7 +538,24 @@ static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev) > struct videobuf_buffer, queue); > list_del(&vpfe_dev->next_frm->queue); > vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE; > - addr = videobuf_to_dma_contig(vpfe_dev->next_frm); > + if (V4L2_MEMORY_USERPTR == vpfe_dev->memory) > + addr = vpfe_dev->cur_frm->boff; > + else > + 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; > + > + if (V4L2_MEMORY_USERPTR == vpfe_dev->memory) > + addr = vpfe_dev->cur_frm->boff; > + else > + addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); > + > + addr += vpfe_dev->field_off; > ccdc_dev->hw_ops.setfbaddr(addr); > } > > @@ -559,7 +576,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"); > @@ -604,10 +620,7 @@ 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); > } > goto clear_intr; > } > @@ -1234,7 +1247,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; > @@ -1243,6 +1259,46 @@ static int vpfe_videobuf_setup(struct videobuf_queue *vq, > return 0; > } > > +/* > + * vpfe_uservirt_to_phys: This function is used to convert user > + * space virtual address to physical address. > + */ > +static u32 vpfe_uservirt_to_phys(struct vpfe_device *vpfe_dev, 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(¤t->mm->mmap_sem); > + > + res = get_user_pages(current, current->mm, > + virtp, nr_pages, 1, 0, &pages, NULL); > + up_read(¤t->mm->mmap_sem); > + > + if (res == nr_pages) > + physp = __pa(page_address(&pages[0]) + > + (virtp & ~PAGE_MASK)); > + else { > + v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, > + "get_user_pages failed\n"); > + return 0; > + } > + } > + return physp; > +} > + > static int vpfe_videobuf_prepare(struct videobuf_queue *vq, > struct videobuf_buffer *vb, > enum v4l2_field field) > @@ -1259,6 +1315,18 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq, > vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; > vb->field = field; > } > + > + if (V4L2_MEMORY_USERPTR == vpfe_dev->memory) { > + if (!vb->baddr) { > + v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, > + "buffer address is 0\n"); > + return -EINVAL; > + } > + vb->boff = vpfe_uservirt_to_phys(vpfe_dev, vb->baddr); > + /* Make sure user addresses are aligned to 32 bytes */ > + if (!ALIGN(vb->boff, 32)) > + return -EINVAL; > + } > vb->state = VIDEOBUF_PREPARED; > return 0; > } > @@ -1327,13 +1395,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; > @@ -1541,7 +1602,10 @@ static int vpfe_streamon(struct file *file, void *priv, > vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE; > /* Initialize field_id and started member */ > vpfe_dev->field_id = 0; > - addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); > + if (V4L2_MEMORY_USERPTR == vpfe_dev->memory) > + addr = vpfe_dev->cur_frm->boff; > + else > + addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); > > /* Calculate field offset */ > vpfe_calculate_offsets(vpfe_dev); > -- > 1.6.2.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Murali Karicheri mkaricheri@xxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html