[PATCH 0/2] DaVinci: VPIF: upgrade with v4l helpers

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/2] DaVinci: VPIF: upgrade with v4l helpers

Lad, Prabhakar
From: "Lad, Prabhakar" <[hidden email]>

Hi All,

This patch series upgrades the vpif capture & display
driver with the all the helpers provided by v4l, this makes
the driver much simpler and cleaner. This also includes few
checkpatch issues.

Sending them as single patch one for capture and another for
display, splitting them would have caused a huge number small
patches.

Lad, Prabhakar (2):
  media: davinci: vpif capture: upgrade the driver with v4l offerings
  media: davinci: vpif display: upgrade the driver with v4l offerings

 drivers/media/platform/davinci/vpif_capture.c |  916 ++++++-------------------
 drivers/media/platform/davinci/vpif_capture.h |   32 +-
 drivers/media/platform/davinci/vpif_display.c |  788 ++++++---------------
 drivers/media/platform/davinci/vpif_display.h |   31 +-
 4 files changed, 446 insertions(+), 1321 deletions(-)

--
1.7.9.5

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|

[PATCH 1/2] media: davinci: vpif capture: upgrade the driver with v4l offerings

Lad, Prabhakar
From: "Lad, Prabhakar" <[hidden email]>

This patch upgrades the vpif display driver with
v4l helpers, this patch does the following,

1: initialize the vb2 queue and context at the time of probe
and removes context at remove() callback.
2: uses vb2_ioctl_*() helpers.
3: uses vb2_fop_*() helpers.
4: uses SIMPLE_DEV_PM_OPS.
5: uses vb2_ioctl_*() helpers.
6: vidioc_g/s_priority is now handled by v4l core.
7: removed driver specific fh and now using one provided by v4l.
8: fixes checkpatch warnings.

Signed-off-by: Lad, Prabhakar <[hidden email]>
---
 drivers/media/platform/davinci/vpif_capture.c |  916 ++++++-------------------
 drivers/media/platform/davinci/vpif_capture.h |   32 +-
 2 files changed, 229 insertions(+), 719 deletions(-)

diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 8dea0b8..76c15b3 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Texas Instruments Inc
+ * Copyright (C) 2009-14 Texas Instruments Inc
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,6 +17,9 @@
  *
  * TODO : add support for VBI & HBI data service
  *  add static buffer allocation
+ *
+ * Contributors:
+ *      Lad, Prabhakar <[hidden email]>
  */
 
 #include <linux/module.h>
@@ -37,6 +40,8 @@ MODULE_VERSION(VPIF_CAPTURE_VERSION);
 #define vpif_dbg(level, debug, fmt, arg...) \
  v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
 
+#define VPIF_DRIVER_NAME "vpif_capture"
+
 static int debug = 1;
 static u32 ch0_numbuffers = 3;
 static u32 ch1_numbuffers = 3;
@@ -65,11 +70,20 @@ static struct vpif_config_params config_params = {
  .channel_bufsize[1] = 720 * 576 * 2,
 };
 
+static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };
+
 /* global variables */
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
+static int vpif_check_format(struct channel_obj *ch,
+     struct v4l2_pix_format *pixfmt, int update);
+
+static inline struct vpif_cap_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+{
+ return container_of(vb, struct vpif_cap_buffer, vb);
+}
 
 /**
  * buffer_prepare :  callback function for buffer prepare
@@ -81,10 +95,8 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode);
  */
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 {
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
  struct vb2_queue *q = vb->vb2_queue;
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(q);
  struct common_obj *common;
  unsigned long addr;
 
@@ -100,7 +112,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
  goto exit;
  addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
- if (q->streaming) {
+ if (vb2_is_streaming(q)) {
  if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
  !IS_ALIGNED((addr + common->ybtm_off), 8) ||
  !IS_ALIGNED((addr + common->ctop_off), 8) ||
@@ -131,9 +143,7 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
  unsigned int *nbuffers, unsigned int *nplanes,
  unsigned int sizes[], void *alloc_ctxs[])
 {
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common;
  unsigned long size;
 
@@ -141,8 +151,7 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
 
  vpif_dbg(2, debug, "vpif_buffer_setup\n");
 
- /* If memory type is not mmap, return */
- if (V4L2_MEMORY_MMAP == common->memory) {
+ if (vq->memory == V4L2_MEMORY_MMAP) {
  /* Calculate the size of the buffer */
  size = config_params.channel_bufsize[ch->channel_id];
  /*
@@ -183,11 +192,8 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
  */
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 {
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct channel_obj *ch = fh->channel;
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
+ struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+ struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
  struct common_obj *common;
  unsigned long flags;
 
@@ -210,11 +216,8 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
  */
 static void vpif_buf_cleanup(struct vb2_buffer *vb)
 {
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+ struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
  struct common_obj *common;
  unsigned long flags;
 
@@ -227,65 +230,35 @@ static void vpif_buf_cleanup(struct vb2_buffer *vb)
 
 }
 
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
-}
-
 static int vpif_buffer_init(struct vb2_buffer *vb)
 {
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
+ struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
 
  INIT_LIST_HEAD(&buf->list);
 
  return 0;
 }
 
-static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
- { {1, 1} };
-
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
- struct vpif_capture_config *vpif_config_data =
- vpif_dev->platform_data;
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct vpif_capture_config *vpif_config_data;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  struct vpif_params *vpif = &ch->vpifparams;
- unsigned long addr = 0;
- unsigned long flags;
+ struct vpif_cap_buffer *buf, *tmp;
+ unsigned long addr, flags;
  int ret;
 
  spin_lock_irqsave(&common->irqlock, flags);
 
- /* Get the next frame from the buffer queue */
- common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
-    struct vpif_cap_buffer, list);
- /* Remove buffer from the buffer queue */
- list_del(&common->cur_frm->list);
- spin_unlock_irqrestore(&common->irqlock, flags);
- /* Mark state of the current frame to active */
- common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
- /* Initialize field_id and started member */
+ /* Initialize field_id */
  ch->field_id = 0;
- common->started = 1;
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
+ ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
+ if (ret) {
+ ret = -EINVAL;
+ goto err;
+ }
 
  /* Calculate the offset for Y and C data in the buffer */
  vpif_calculate_offsets(ch);
@@ -296,30 +269,50 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
     (!vpif->std_info.frm_fmt &&
      (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
  vpif_dbg(1, debug, "conflict in field format and std format\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
  }
 
+ vpif_config_data = vpif_dev->platform_data;
  /* configure 1 or 2 channel mode */
  if (vpif_config_data->setup_input_channel_mode) {
  ret = vpif_config_data->
  setup_input_channel_mode(vpif->std_info.ycmux_mode);
  if (ret < 0) {
  vpif_dbg(1, debug, "can't set vpif channel mode\n");
- return ret;
+ ret = -EINVAL;
+ goto err;
  }
  }
 
+ ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
+
+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
+ vpif_dbg(1, debug, "stream on failed in subdev\n");
+ goto err;
+ }
+
  /* Call vpif_set_params function to set the parameters and addresses */
  ret = vpif_set_video_params(vpif, ch->channel_id);
-
  if (ret < 0) {
  vpif_dbg(1, debug, "can't set video params\n");
- return ret;
+ ret = -EINVAL;
+ goto err;
  }
 
- common->started = ret;
  vpif_config_addr(ch, ret);
 
+ /* Get the next frame from the buffer queue */
+ common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
+    struct vpif_cap_buffer, list);
+ /* Remove buffer from the buffer queue */
+ list_del(&common->cur_frm->list);
+ spin_unlock_irqrestore(&common->irqlock, flags);
+ /* Mark state of the current frame to active */
+ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+
+ addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
  common->set_addr(addr + common->ytop_off,
  addr + common->ybtm_off,
  addr + common->ctop_off,
@@ -330,31 +323,35 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
  * VPIF register
  */
  channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
+ if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
  channel0_intr_assert();
  channel0_intr_enable(1);
  enable_channel0(1);
  }
- if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
-    (common->started == 2)) {
+ if (VPIF_CHANNEL1_VIDEO == ch->channel_id) {
  channel1_intr_assert();
  channel1_intr_enable(1);
  enable_channel1(1);
  }
 
  return 0;
+
+err:
+ list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ }
+
+ return ret;
 }
 
 /* abort streaming and wait for last buffer */
 static int vpif_stop_streaming(struct vb2_queue *vq)
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common;
  unsigned long flags;
-
- if (!vb2_is_streaming(vq))
- return 0;
+ int ret;
 
  common = &ch->common[VPIF_VIDEO_INDEX];
 
@@ -363,12 +360,15 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
  enable_channel0(0);
  channel0_intr_enable(0);
  }
- if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
+ if (VPIF_CHANNEL1_VIDEO == ch->channel_id) {
  enable_channel1(0);
  channel1_intr_enable(0);
  }
- common->started = 0;
+
+ ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
+
+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ vpif_dbg(1, debug, "stream off failed in subdev\n");
 
  /* release all active buffers */
  spin_lock_irqsave(&common->irqlock, flags);
@@ -396,8 +396,8 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 
 static struct vb2_ops video_qops = {
  .queue_setup = vpif_buffer_queue_setup,
- .wait_prepare = vpif_wait_prepare,
- .wait_finish = vpif_wait_finish,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
  .buf_init = vpif_buffer_init,
  .buf_prepare = vpif_buffer_prepare,
  .start_streaming = vpif_start_streaming,
@@ -417,8 +417,7 @@ static struct vb2_ops video_qops = {
 static void vpif_process_buffer_complete(struct common_obj *common)
 {
  v4l2_get_timestamp(&common->cur_frm->vb.v4l2_buf.timestamp);
- vb2_buffer_done(&common->cur_frm->vb,
-    VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_DONE);
  /* Make curFrm pointing to nextFrm */
  common->cur_frm = common->next_frm;
 }
@@ -433,7 +432,7 @@ static void vpif_process_buffer_complete(struct common_obj *common)
  */
 static void vpif_schedule_next_buffer(struct common_obj *common)
 {
- unsigned long addr = 0;
+ unsigned long addr;
 
  spin_lock(&common->irqlock);
  common->next_frm = list_entry(common->dma_queue.next,
@@ -479,7 +478,7 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
  for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
  common = &ch->common[i];
  /* skip If streaming is not started in this channel */
- if (0 == common->started)
+ if (!vb2_is_streaming(&common->buffer_queue))
  continue;
 
  /* Check the field format */
@@ -683,10 +682,6 @@ static void vpif_config_format(struct channel_obj *ch)
  vpif_dbg(2, debug, "vpif_config_format\n");
 
  common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
- if (config_params.numbuffers[ch->channel_id] == 0)
- common->memory = V4L2_MEMORY_USERPTR;
- else
- common->memory = V4L2_MEMORY_MMAP;
 
  common->fmt.fmt.pix.sizeimage
     = config_params.channel_bufsize[ch->channel_id];
@@ -837,415 +832,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 }
 
 /**
- * vpif_mmap : It is used to map kernel space buffers into user spaces
- * @filep: file pointer
- * @vma: ptr to vm_area_struct
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- /* Get the channel object and file handle object */
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
- int ret;
-
- vpif_dbg(2, debug, "vpif_mmap\n");
-
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
- ret = vb2_mmap(&common->buffer_queue, vma);
- mutex_unlock(&common->lock);
- return ret;
-}
-
-/**
- * vpif_poll: It is used for select/poll system call
- * @filep: file pointer
- * @wait: poll table to wait
- */
-static unsigned int vpif_poll(struct file *filep, poll_table * wait)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *channel = fh->channel;
- struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
- unsigned int res = 0;
-
- vpif_dbg(2, debug, "vpif_poll\n");
-
- if (common->started) {
- mutex_lock(&common->lock);
- res = vb2_poll(&common->buffer_queue, filep, wait);
- mutex_unlock(&common->lock);
- }
- return res;
-}
-
-/**
- * vpif_open : vpif open handler
- * @filep: file ptr
- *
- * It creates object of file handle structure and stores it in private_data
- * member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
- struct video_device *vdev = video_devdata(filep);
- struct common_obj *common;
- struct video_obj *vid_ch;
- struct channel_obj *ch;
- struct vpif_fh *fh;
-
- vpif_dbg(2, debug, "vpif_open\n");
-
- ch = video_get_drvdata(vdev);
-
- vid_ch = &ch->video;
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* Allocate memory for the file handle object */
- fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
- if (NULL == fh) {
- vpif_err("unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
-
- if (mutex_lock_interruptible(&common->lock)) {
- kfree(fh);
- return -ERESTARTSYS;
- }
- /* store pointer to fh in private_data member of filep */
- filep->private_data = fh;
- fh->channel = ch;
- fh->initialized = 0;
- /* If decoder is not initialized. initialize it */
- if (!ch->initialized) {
- fh->initialized = 1;
- ch->initialized = 1;
- memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
- }
- /* Increment channel usrs counter */
- ch->usrs++;
- /* Set io_allowed member to false */
- fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&ch->prio, &fh->prio);
- mutex_unlock(&common->lock);
- return 0;
-}
-
-/**
- * vpif_release : function to clean up file close
- * @filep: file pointer
- *
- * This function deletes buffer queue, frees the buffers and the vpif file
- * handle
- */
-static int vpif_release(struct file *filep)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- vpif_dbg(2, debug, "vpif_release\n");
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- mutex_lock(&common->lock);
- /* if this instance is doing IO */
- if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
- /* Reset io_usrs member of channel object */
- common->io_usrs = 0;
- /* Free buffers allocated */
- vb2_queue_release(&common->buffer_queue);
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
- }
-
- /* Decrement channel usrs counter */
- ch->usrs--;
-
- /* Close the priority */
- v4l2_prio_close(&ch->prio, fh->prio);
-
- if (fh->initialized)
- ch->initialized = 0;
-
- mutex_unlock(&common->lock);
- filep->private_data = NULL;
- kfree(fh);
- return 0;
-}
-
-/**
- * vpif_reqbufs() - request buffer handler
- * @file: file ptr
- * @priv: file handle
- * @reqbuf: request buffer structure ptr
- */
-static int vpif_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- u8 index = 0;
- struct vb2_queue *q;
- int ret;
-
- vpif_dbg(2, debug, "vpif_reqbufs\n");
-
- /**
- * This file handle has not initialized the channel,
- * It is not allowed to do settings
- */
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
-    || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
- return -EINVAL;
-
- index = VPIF_VIDEO_INDEX;
-
- common = &ch->common[index];
-
- if (0 != common->io_usrs)
- return -EBUSY;
-
- /* Initialize videobuf2 queue as per the buffer type */
- common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
- if (IS_ERR(common->alloc_ctx)) {
- vpif_err("Failed to get the context\n");
- return PTR_ERR(common->alloc_ctx);
- }
- q = &common->buffer_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fh;
- q->ops = &video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct vpif_cap_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->min_buffers_needed = 1;
-
- ret = vb2_queue_init(q);
- if (ret) {
- vpif_err("vpif_capture: vb2_queue_init() failed\n");
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
- return ret;
- }
- /* Set io allowed member of file handle to TRUE */
- fh->io_allowed[index] = 1;
- /* Increment io usrs member of channel object to 1 */
- common->io_usrs = 1;
- /* Store type of memory requested in channel object */
- common->memory = reqbuf->memory;
- INIT_LIST_HEAD(&common->dma_queue);
-
- /* Allocate buffers */
- return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-/**
- * vpif_querybuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_querybuf\n");
-
- if (common->fmt.type != buf->type)
- return -EINVAL;
-
- if (common->memory != V4L2_MEMORY_MMAP) {
- vpif_dbg(1, debug, "Invalid memory\n");
- return -EINVAL;
- }
-
- return vb2_querybuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_qbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-
- 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;
-
- vpif_dbg(2, debug, "vpif_qbuf\n");
-
- if (common->fmt.type != tbuf.type) {
- vpif_err("invalid buffer type\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh io not allowed\n");
- return -EACCES;
- }
-
- return vb2_qbuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_dqbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_dqbuf\n");
-
- return vb2_dqbuf(&common->buffer_queue, buf,
- (file->f_flags & O_NONBLOCK));
-}
-
-/**
- * vpif_streamon() - streamon handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
-
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
- struct vpif_params *vpif;
- int ret = 0;
-
- vpif_dbg(2, debug, "vpif_streamon\n");
-
- vpif = &ch->vpifparams;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- vpif_dbg(1, debug, "buffer type not supported\n");
- return -EINVAL;
- }
-
- /* If file handle is not allowed IO, return error */
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_dbg(1, debug, "io not allowed\n");
- return -EACCES;
- }
-
- /* If Streaming is already started, return error */
- if (common->started) {
- vpif_dbg(1, debug, "channel->started\n");
- return -EBUSY;
- }
-
- if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
-    oth_ch->common[VPIF_VIDEO_INDEX].started &&
-    vpif->std_info.ycmux_mode == 0) ||
-   ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
-    (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
- vpif_dbg(1, debug, "other channel is being used\n");
- return -EBUSY;
- }
-
- ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
- if (ret)
- return ret;
-
- /* Enable streamon on the sub device */
- ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
-
- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
- vpif_dbg(1, debug, "stream on failed in subdev\n");
- return ret;
- }
-
- /* Call vb2_streamon to start streaming in videobuf2 */
- ret = vb2_streamon(&common->buffer_queue, buftype);
- if (ret) {
- vpif_dbg(1, debug, "vb2_streamon\n");
- return ret;
- }
-
- return ret;
-}
-
-/**
- * vpif_streamoff() - streamoff handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
-
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret;
-
- vpif_dbg(2, debug, "vpif_streamoff\n");
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- vpif_dbg(1, debug, "buffer type not supported\n");
- return -EINVAL;
- }
-
- /* If io is allowed for this file handle, return error */
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_dbg(1, debug, "io not allowed\n");
- return -EACCES;
- }
-
- /* If streaming is not started, return error */
- if (!common->started) {
- vpif_dbg(1, debug, "channel->started\n");
- return -EINVAL;
- }
-
- /* disable channel */
- if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
- enable_channel0(0);
- channel0_intr_enable(0);
- } else {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
-
- common->started = 0;
-
- ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
-
- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
- vpif_dbg(1, debug, "stream off failed in subdev\n");
-
- return vb2_streamoff(&common->buffer_queue, buftype);
-}
-
-/**
  * vpif_input_to_subdev() - Maps input to sub device
  * @vpif_cfg - global config ptr
  * @chan_cfg - channel config ptr
@@ -1348,9 +934,9 @@ static int vpif_set_input(
  */
 static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- int ret = 0;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
+ int ret;
 
  vpif_dbg(2, debug, "vpif_querystd\n");
 
@@ -1375,8 +961,8 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
  */
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  vpif_dbg(2, debug, "vpif_g_std\n");
 
@@ -1392,31 +978,15 @@ static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
  */
 static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
+ int ret;
 
  vpif_dbg(2, debug, "vpif_s_std\n");
 
- if (common->started) {
- vpif_err("streaming in progress\n");
+ if (vb2_is_streaming(&common->buffer_queue))
  return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
 
  /* Call encoder subdevice function to set the standard */
  ch->video.stdid = std_id;
@@ -1452,8 +1022,8 @@ static int vpif_enum_input(struct file *file, void *priv,
 
  struct vpif_capture_config *config = vpif_dev->platform_data;
  struct vpif_capture_chan_config *chan_cfg;
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  chan_cfg = &config->chan_config[ch->channel_id];
 
@@ -1475,8 +1045,8 @@ static int vpif_enum_input(struct file *file, void *priv,
  */
 static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  *index = ch->input_idx;
  return 0;
@@ -1492,34 +1062,18 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 {
  struct vpif_capture_config *config = vpif_dev->platform_data;
  struct vpif_capture_chan_config *chan_cfg;
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret;
+
+ if (vb2_is_streaming(&common->buffer_queue))
+ return -EBUSY;
 
  chan_cfg = &config->chan_config[ch->channel_id];
 
  if (index >= chan_cfg->input_count)
  return -EINVAL;
 
- if (common->started) {
- vpif_err("Streaming in progress\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
  return vpif_set_input(config, ch, index);
 }
 
@@ -1532,8 +1086,8 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
  struct v4l2_fmtdesc *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  if (fmt->index != 0) {
  vpif_dbg(1, debug, "Invalid format index\n");
@@ -1562,8 +1116,8 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 
  return vpif_check_format(ch, pixfmt, 1);
@@ -1579,8 +1133,8 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
  /* Check the validity of the buffer type */
@@ -1601,8 +1155,8 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  struct v4l2_pix_format *pixfmt;
  int ret = 0;
@@ -1610,31 +1164,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
  vpif_dbg(2, debug, "%s\n", __func__);
 
  /* If streaming is started, return error */
- if (common->started) {
+ if (vb2_is_streaming(&common->buffer_queue)) {
  vpif_dbg(1, debug, "Streaming is started\n");
  return -EBUSY;
  }
 
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
-
  pixfmt = &fmt->fmt.pix;
  /* Check for valid field format */
  ret = vpif_check_format(ch, pixfmt, 0);
-
  if (ret)
  return ret;
+
  /* store the format in the channel object */
  common->fmt = *fmt;
  return 0;
@@ -1662,37 +1202,6 @@ static int vpif_querycap(struct file *file, void  *priv,
 }
 
 /**
- * vpif_g_priority() - get priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_g_priority(struct file *file, void *priv,
-   enum v4l2_priority *prio)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- *prio = v4l2_prio_max(&ch->prio);
-
- return 0;
-}
-
-/**
- * vpif_s_priority() - set priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
-/**
  * vpif_cropcap() - cropcap handler
  * @file: file ptr
  * @priv: file handle
@@ -1701,8 +1210,8 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
 static int vpif_cropcap(struct file *file, void *priv,
  struct v4l2_cropcap *crop)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
  if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
@@ -1726,8 +1235,8 @@ static int
 vpif_enum_dv_timings(struct file *file, void *priv,
      struct v4l2_enum_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  int ret;
 
  ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
@@ -1746,8 +1255,8 @@ static int
 vpif_query_dv_timings(struct file *file, void *priv,
       struct v4l2_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  int ret;
 
  ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
@@ -1765,8 +1274,8 @@ vpif_query_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
  struct v4l2_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct vpif_params *vpifparams = &ch->vpifparams;
  struct vpif_channel_config_params *std_info = &vpifparams->std_info;
  struct video_obj *vid_ch = &ch->video;
@@ -1853,8 +1362,8 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
  struct v4l2_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct video_obj *vid_ch = &ch->video;
 
  *timings = vid_ch->dv_timings;
@@ -1879,49 +1388,46 @@ static int vpif_log_status(struct file *filep, void *priv)
 
 /* vpif capture ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
- .vidioc_querycap         = vpif_querycap,
- .vidioc_g_priority = vpif_g_priority,
- .vidioc_s_priority = vpif_s_priority,
+ .vidioc_querycap = vpif_querycap,
  .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap   = vpif_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
  .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
  .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
+
  .vidioc_enum_input = vpif_enum_input,
  .vidioc_s_input = vpif_s_input,
  .vidioc_g_input = vpif_g_input,
- .vidioc_reqbufs         = vpif_reqbufs,
- .vidioc_querybuf         = vpif_querybuf,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
  .vidioc_querystd = vpif_querystd,
- .vidioc_s_std           = vpif_s_std,
+ .vidioc_s_std = vpif_s_std,
  .vidioc_g_std = vpif_g_std,
- .vidioc_qbuf             = vpif_qbuf,
- .vidioc_dqbuf           = vpif_dqbuf,
- .vidioc_streamon         = vpif_streamon,
- .vidioc_streamoff       = vpif_streamoff,
- .vidioc_cropcap         = vpif_cropcap,
- .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
- .vidioc_query_dv_timings        = vpif_query_dv_timings,
- .vidioc_s_dv_timings            = vpif_s_dv_timings,
- .vidioc_g_dv_timings            = vpif_g_dv_timings,
+
+ .vidioc_cropcap = vpif_cropcap,
+
+ .vidioc_enum_dv_timings = vpif_enum_dv_timings,
+ .vidioc_query_dv_timings = vpif_query_dv_timings,
+ .vidioc_s_dv_timings = vpif_s_dv_timings,
+ .vidioc_g_dv_timings = vpif_g_dv_timings,
+
  .vidioc_log_status = vpif_log_status,
 };
 
 /* vpif file operations */
 static struct v4l2_file_operations vpif_fops = {
- .owner = THIS_MODULE,
- .open = vpif_open,
- .release = vpif_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vpif_mmap,
- .poll = vpif_poll
-};
-
-/* vpif video template */
-static struct video_device vpif_video_template = {
- .name = "vpif",
- .fops = &vpif_fops,
- .minor = -1,
- .ioctl_ops = &vpif_ioctl_ops,
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+ .poll = vb2_fop_poll
 };
 
 /**
@@ -1999,7 +1505,9 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 static int vpif_probe_complete(void)
 {
  struct common_obj *common;
+ struct video_device *vdev;
  struct channel_obj *ch;
+ struct vb2_queue *q;
  int i, j, err, k;
 
  for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
@@ -2009,16 +1517,55 @@ static int vpif_probe_complete(void)
  spin_lock_init(&common->irqlock);
  mutex_init(&common->lock);
  ch->video_dev->lock = &common->lock;
- /* Initialize prio member of channel object */
- v4l2_prio_init(&ch->prio);
- video_set_drvdata(ch->video_dev, ch);
 
  /* select input 0 */
  err = vpif_set_input(vpif_obj.config, ch, 0);
  if (err)
  goto probe_out;
 
- err = video_register_device(ch->video_dev,
+ /* Initialize vb2 queue */
+ q = &common->buffer_queue;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR;
+ q->drv_priv = ch;
+ q->ops = &video_qops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct vpif_cap_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->min_buffers_needed = 3;
+ q->lock = &common->lock;
+ q->gfp_flags = GFP_DMA32;
+
+ err = vb2_queue_init(q);
+ if (err) {
+ vpif_err("vpif_display: vb2_queue_init() failed\n");
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
+ goto probe_out;
+ }
+
+ common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
+ if (IS_ERR(common->alloc_ctx)) {
+ vpif_err("Failed to get the context\n");
+ err = PTR_ERR(common->alloc_ctx);
+ goto probe_out;
+ }
+
+ INIT_LIST_HEAD(&common->dma_queue);
+
+ /* Initialize the video_device structure */
+ vdev = ch->video_dev;
+ strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+ vdev->release = video_device_release;
+ vdev->fops = &vpif_fops;
+ vdev->ioctl_ops = &vpif_ioctl_ops;
+ vdev->lock = &common->lock;
+ vdev->queue = q;
+ vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+ vdev->vfl_dir = VFL_DIR_RX;
+ set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+ video_set_drvdata(vdev, ch);
+
+ err = video_register_device(vdev,
     VFL_TYPE_GRABBER, (j ? 1 : 0));
  if (err)
  goto probe_out;
@@ -2031,6 +1578,8 @@ probe_out:
  for (k = 0; k < j; k++) {
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[k];
+ common = &ch->common[k];
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
  /* Unregister video device */
  video_unregister_device(ch->video_dev);
  }
@@ -2085,7 +1634,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
  while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
  err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
- IRQF_SHARED, "VPIF_Capture",
+ IRQF_SHARED, VPIF_DRIVER_NAME,
  (void *)(&vpif_obj.dev[res_idx]->
  channel_id));
  if (err) {
@@ -2109,13 +1658,6 @@ static __init int vpif_probe(struct platform_device *pdev)
  goto vpif_unregister;
  }
 
- /* Initialize field of video device */
- *vfd = vpif_video_template;
- vfd->v4l2_dev = &vpif_obj.v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name),
- "VPIF_Capture_DRIVER_V%s",
- VPIF_CAPTURE_VERSION);
  /* Set video_dev to the video device */
  ch->video_dev = vfd;
  }
@@ -2209,6 +1751,7 @@ vpif_unregister:
  */
 static int vpif_remove(struct platform_device *device)
 {
+ struct common_obj *common;
  struct channel_obj *ch;
  int i;
 
@@ -2219,6 +1762,8 @@ static int vpif_remove(struct platform_device *device)
  for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
+ common = &ch->common[i];
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
  /* Unregister video device */
  video_unregister_device(ch->video_dev);
  kfree(vpif_obj.dev[i]);
@@ -2226,13 +1771,12 @@ static int vpif_remove(struct platform_device *device)
  return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /**
  * vpif_suspend: vpif device suspend
  */
 static int vpif_suspend(struct device *dev)
 {
-
  struct common_obj *common;
  struct channel_obj *ch;
  int i;
@@ -2241,18 +1785,19 @@ static int vpif_suspend(struct device *dev)
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
  common = &ch->common[VPIF_VIDEO_INDEX];
+
+ if (!vb2_is_streaming(&common->buffer_queue))
+ continue;
+
  mutex_lock(&common->lock);
- if (ch->usrs && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
- enable_channel0(0);
- channel0_intr_enable(0);
- }
- if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-    common->started == 2) {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
+ /* Disable channel */
+ if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+ enable_channel0(0);
+ channel0_intr_enable(0);
+ }
+ if (ch->channel_id == VPIF_CHANNEL1_VIDEO) {
+ enable_channel1(0);
+ channel1_intr_enable(0);
  }
  mutex_unlock(&common->lock);
  }
@@ -2273,18 +1818,19 @@ static int vpif_resume(struct device *dev)
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
  common = &ch->common[VPIF_VIDEO_INDEX];
+
+ if (!vb2_is_streaming(&common->buffer_queue))
+ continue;
+
  mutex_lock(&common->lock);
- if (ch->usrs && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
- enable_channel0(1);
- channel0_intr_enable(1);
- }
- if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-    common->started == 2) {
- enable_channel1(1);
- channel1_intr_enable(1);
- }
+ /* Enable channel */
+ if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+ enable_channel0(1);
+ channel0_intr_enable(1);
+ }
+ if (ch->channel_id == VPIF_CHANNEL1_VIDEO) {
+ enable_channel1(1);
+ channel1_intr_enable(1);
  }
  mutex_unlock(&common->lock);
  }
@@ -2292,21 +1838,15 @@ static int vpif_resume(struct device *dev)
  return 0;
 }
 
-static const struct dev_pm_ops vpif_dev_pm_ops = {
- .suspend = vpif_suspend,
- .resume = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_dev_pm_ops)
-#else
-#define vpif_pm_ops NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
 static __refdata struct platform_driver vpif_driver = {
  .driver = {
- .name = "vpif_capture",
+ .name = VPIF_DRIVER_NAME,
  .owner = THIS_MODULE,
- .pm = vpif_pm_ops,
+ .pm = &vpif_pm_ops,
  },
  .probe = vpif_probe,
  .remove = vpif_remove,
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 5a29d9a..8af3b33 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -19,8 +19,6 @@
 #ifndef VPIF_CAPTURE_H
 #define VPIF_CAPTURE_H
 
-#ifdef __KERNEL__
-
 /* Header files */
 #include <media/videobuf2-dma-contig.h>
 #include <media/v4l2-device.h>
@@ -63,11 +61,6 @@ struct common_obj {
  struct vpif_cap_buffer *cur_frm;
  /* Pointer pointing to current v4l2_buffer */
  struct vpif_cap_buffer *next_frm;
- /*
- * This field keeps track of type of buffer exchange mechanism
- * user has selected
- */
- enum v4l2_memory memory;
  /* Used to store pixel format */
  struct v4l2_format fmt;
  /* Buffer queue used in video-buf */
@@ -80,12 +73,8 @@ struct common_obj {
  spinlock_t irqlock;
  /* lock used to access this structure */
  struct mutex lock;
- /* number of users performing IO */
- u32 io_usrs;
- /* Indicates whether streaming started */
- u8 started;
  /* Function pointer to set the addresses */
- void (*set_addr) (unsigned long, unsigned long, unsigned long,
+ void (*set_addr)(unsigned long, unsigned long, unsigned long,
   unsigned long);
  /* offset where Y top starts from the starting of the buffer */
  u32 ytop_off;
@@ -104,14 +93,8 @@ struct common_obj {
 struct channel_obj {
  /* Identifies video device for this channel */
  struct video_device *video_dev;
- /* Used to keep track of state of the priority */
- struct v4l2_prio_state prio;
- /* number of open instances of the channel */
- int usrs;
  /* Indicates id of the field which is being displayed */
  u32 field_id;
- /* flag to indicate whether decoder is initialized */
- u8 initialized;
  /* Identifies channel */
  enum vpif_channel_id channel_id;
  /* Current input */
@@ -126,18 +109,6 @@ struct channel_obj {
  struct video_obj video;
 };
 
-/* File handle structure */
-struct vpif_fh {
- /* pointer to channel object for opened device */
- struct channel_obj *channel;
- /* Indicates whether this file handle is doing IO */
- u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
- /* Used to keep track priority of this instance */
- enum v4l2_priority prio;
- /* Used to indicate channel is initialize or not */
- u8 initialized;
-};
-
 struct vpif_device {
  struct v4l2_device v4l2_dev;
  struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
@@ -157,5 +128,4 @@ struct vpif_config_params {
  u8 max_device_type;
 };
 
-#endif /* End of __KERNEL__ */
 #endif /* VPIF_CAPTURE_H */
--
1.7.9.5

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|

[PATCH 2/2] media: davinci: vpif display: upgrade the driver with v4l offerings

Lad, Prabhakar
In reply to this post by Lad, Prabhakar
From: "Lad, Prabhakar" <[hidden email]>

This patch upgrades the vpif display driver with
v4l helpers, this patch does the following,

1: initialize the vb2 queue and context at the time of probe
and removes context at remove() callback.
2: uses vb2_ioctl_*() helpers.
3: uses vb2_fop_*() helpers.
4: uses SIMPLE_DEV_PM_OPS.
5: uses vb2_ioctl_*() helpers.
6: vidioc_g/s_priority is now handled by v4l core.
7: removed driver specific fh and now using one provided by v4l.
8: fixes checkpatch warnings.

Signed-off-by: Lad, Prabhakar <[hidden email]>
---
 drivers/media/platform/davinci/vpif_display.c |  788 +++++++------------------
 drivers/media/platform/davinci/vpif_display.h |   31 +-
 2 files changed, 217 insertions(+), 602 deletions(-)

diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index aed41ed..bfbe73e 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -2,7 +2,7 @@
  * vpif-display - VPIF display driver
  * Display driver for TI DaVinci VPIF
  *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -12,6 +12,9 @@
  * kind, whether express or implied; without even the implied warranty
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
+ *
+ * Contributors:
+ *      Lad, Prabhakar <[hidden email]>
  */
 
 #include <linux/interrupt.h>
@@ -34,6 +37,8 @@ MODULE_VERSION(VPIF_DISPLAY_VERSION);
 #define vpif_dbg(level, debug, fmt, arg...) \
  v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
 
+#define VPIF_DRIVER_NAME "vpif_display"
+
 static int debug = 1;
 static u32 ch2_numbuffers = 3;
 static u32 ch3_numbuffers = 3;
@@ -64,9 +69,16 @@ static struct vpif_config_params config_params = {
 
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
+static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
+
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 
+static inline struct vpif_disp_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+{
+ return container_of(vb, struct vpif_disp_buffer, vb);
+}
+
 /*
  * buffer_prepare: This is the callback function called from vb2_qbuf()
  * function the buffer is prepared and user space virtual address is converted
@@ -74,12 +86,12 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode);
  */
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
  struct vb2_queue *q = vb->vb2_queue;
+ struct channel_obj *ch = vb2_get_drv_priv(q);
  struct common_obj *common;
  unsigned long addr;
 
- common = &fh->channel->common[VPIF_VIDEO_INDEX];
+ common = &ch->common[VPIF_VIDEO_INDEX];
  if (vb->state != VB2_BUF_STATE_ACTIVE &&
  vb->state != VB2_BUF_STATE_PREPARED) {
  vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
@@ -88,7 +100,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
  goto buf_align_exit;
 
  addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- if (q->streaming &&
+ if (vb2_is_streaming(q) &&
  (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
  if (!ISALIGNED(addr + common->ytop_off) ||
  !ISALIGNED(addr + common->ybtm_off) ||
@@ -112,12 +124,11 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
  unsigned int *nbuffers, unsigned int *nplanes,
  unsigned int sizes[], void *alloc_ctxs[])
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  unsigned long size;
 
- if (V4L2_MEMORY_MMAP == common->memory) {
+ if (vq->memory == V4L2_MEMORY_MMAP) {
  size = config_params.channel_bufsize[ch->channel_id];
  /*
  * Checking if the buffer size exceeds the available buffer
@@ -154,15 +165,12 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
  */
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
- struct channel_obj *ch = fh->channel;
+ struct vpif_disp_buffer *buf = to_vpif_buffer(vb);
+ struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
  struct common_obj *common;
  unsigned long flags;
 
  common = &ch->common[VPIF_VIDEO_INDEX];
-
  /* add the buffer to the DMA queue */
  spin_lock_irqsave(&common->irqlock, flags);
  list_add_tail(&buf->list, &common->dma_queue);
@@ -175,10 +183,8 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
  */
 static void vpif_buf_cleanup(struct vb2_buffer *vb)
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
- struct channel_obj *ch = fh->channel;
+ struct vpif_disp_buffer *buf = to_vpif_buffer(vb);
+ struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
  struct common_obj *common;
  unsigned long flags;
 
@@ -190,66 +196,30 @@ static void vpif_buf_cleanup(struct vb2_buffer *vb)
  spin_unlock_irqrestore(&common->irqlock, flags);
 }
 
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
-}
-
 static int vpif_buffer_init(struct vb2_buffer *vb)
 {
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
+ struct vpif_disp_buffer *buf = to_vpif_buffer(vb);
 
  INIT_LIST_HEAD(&buf->list);
 
  return 0;
 }
 
-static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
-
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
- struct vpif_display_config *vpif_config_data =
- vpif_dev->platform_data;
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct vpif_display_config *vpif_config_data;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  struct vpif_params *vpif = &ch->vpifparams;
- unsigned long addr = 0;
- unsigned long flags;
+ struct vpif_disp_buffer *buf, *tmp;
+ unsigned long addr, flags;
  int ret;
 
  spin_lock_irqsave(&common->irqlock, flags);
 
- /* Get the next frame from the buffer queue */
- common->next_frm = common->cur_frm =
-    list_entry(common->dma_queue.next,
-       struct vpif_disp_buffer, list);
-
- list_del(&common->cur_frm->list);
- spin_unlock_irqrestore(&common->irqlock, flags);
- /* Mark state of the current frame to active */
- common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
-
- /* Initialize field_id and started member */
+ /* Initialize field_id */
  ch->field_id = 0;
- common->started = 1;
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
  /* Calculate the offset for Y and C data  in the buffer */
  vpif_calculate_offsets(ch);
 
@@ -259,33 +229,49 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
  || (!ch->vpifparams.std_info.frm_fmt
  && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
  vpif_err("conflict in field format and std format\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
  }
 
+ vpif_config_data = vpif_dev->platform_data;
  /* clock settings */
  if (vpif_config_data->set_clock) {
  ret = vpif_config_data->set_clock(ch->vpifparams.std_info.
  ycmux_mode, ch->vpifparams.std_info.hd_sd);
  if (ret < 0) {
  vpif_err("can't set clock\n");
- return ret;
+ goto err;
  }
  }
 
  /* set the parameters and addresses */
  ret = vpif_set_video_params(vpif, ch->channel_id + 2);
  if (ret < 0)
- return ret;
+ goto err;
 
- common->started = ret;
  vpif_config_addr(ch, ret);
+
+ /* Get the next frame from the buffer queue */
+ common->next_frm = common->cur_frm =
+    list_entry(common->dma_queue.next,
+       struct vpif_disp_buffer, list);
+
+ list_del(&common->cur_frm->list);
+ spin_unlock_irqrestore(&common->irqlock, flags);
+ /* Mark state of the current frame to active */
+ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+
+ addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
  common->set_addr((addr + common->ytop_off),
     (addr + common->ybtm_off),
     (addr + common->ctop_off),
     (addr + common->cbtm_off));
 
- /* Set interrupt for both the fields in VPIF
-    Register enable channel in VPIF register */
+ /*
+ * Set interrupt for both the fields in VPIF
+ * Register enable channel in VPIF register
+ */
  channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
  if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
  channel2_intr_assert();
@@ -295,8 +281,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
  channel2_clipping_enable(1);
  }
 
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
- || (common->started == 2)) {
+ if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
  channel3_intr_assert();
  channel3_intr_enable(1);
  enable_channel3(1);
@@ -305,19 +290,23 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
  }
 
  return 0;
+
+err:
+ list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ }
+
+ return ret;
 }
 
 /* abort streaming and wait for last buffer */
 static int vpif_stop_streaming(struct vb2_queue *vq)
 {
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
+ struct channel_obj *ch = vb2_get_drv_priv(vq);
  struct common_obj *common;
  unsigned long flags;
 
- if (!vb2_is_streaming(vq))
- return 0;
-
  common = &ch->common[VPIF_VIDEO_INDEX];
 
  /* Disable channel */
@@ -325,12 +314,10 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
  enable_channel2(0);
  channel2_intr_enable(0);
  }
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
+ if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
  enable_channel3(0);
  channel3_intr_enable(0);
  }
- common->started = 0;
 
  /* release all active buffers */
  spin_lock_irqsave(&common->irqlock, flags);
@@ -358,8 +345,8 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 
 static struct vb2_ops video_qops = {
  .queue_setup = vpif_buffer_queue_setup,
- .wait_prepare = vpif_wait_prepare,
- .wait_finish = vpif_wait_finish,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
  .buf_init = vpif_buffer_init,
  .buf_prepare = vpif_buffer_prepare,
  .start_streaming = vpif_start_streaming,
@@ -370,7 +357,7 @@ static struct vb2_ops video_qops = {
 
 static void process_progressive_mode(struct common_obj *common)
 {
- unsigned long addr = 0;
+ unsigned long addr;
 
  spin_lock(&common->irqlock);
  /* Get the next buffer from buffer queue */
@@ -445,10 +432,11 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
  field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
  for (i = 0; i < VPIF_NUMOBJECTS; i++) {
  common = &ch->common[i];
- /* If streaming is started in this channel */
- if (0 == common->started)
+
+ if (!vb2_is_streaming(&common->buffer_queue))
  continue;
 
+ /* If streaming is started in this channel */
  if (1 == ch->vpifparams.std_info.frm_fmt) {
  spin_lock(&common->irqlock);
  if (list_empty(&common->dma_queue)) {
@@ -626,11 +614,6 @@ static void vpif_config_format(struct channel_obj *ch)
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
  common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
- if (config_params.numbuffers[ch->channel_id] == 0)
- common->memory = V4L2_MEMORY_USERPTR;
- else
- common->memory = V4L2_MEMORY_MMAP;
-
  common->fmt.fmt.pix.sizeimage =
  config_params.channel_bufsize[ch->channel_id];
  common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
@@ -699,127 +682,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
  }
 }
 
-/*
- * vpif_mmap: It is used to map kernel space buffers into user spaces
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
- int ret;
-
- vpif_dbg(2, debug, "vpif_mmap\n");
-
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
- ret = vb2_mmap(&common->buffer_queue, vma);
- mutex_unlock(&common->lock);
- return ret;
-}
-
-/*
- * vpif_poll: It is used for select/poll system call
- */
-static unsigned int vpif_poll(struct file *filep, poll_table *wait)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- unsigned int res = 0;
-
- if (common->started) {
- mutex_lock(&common->lock);
- res = vb2_poll(&common->buffer_queue, filep, wait);
- mutex_unlock(&common->lock);
- }
-
- return res;
-}
-
-/*
- * vpif_open: It creates object of file handle structure and stores it in
- * private_data member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
- struct video_device *vdev = video_devdata(filep);
- struct channel_obj *ch = video_get_drvdata(vdev);
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_fh *fh;
-
- /* Allocate memory for the file handle object */
- fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
- if (fh == NULL) {
- vpif_err("unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
-
- if (mutex_lock_interruptible(&common->lock)) {
- kfree(fh);
- return -ERESTARTSYS;
- }
- /* store pointer to fh in private_data member of filep */
- filep->private_data = fh;
- fh->channel = ch;
- fh->initialized = 0;
- if (!ch->initialized) {
- fh->initialized = 1;
- ch->initialized = 1;
- memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
- }
-
- /* Increment channel usrs counter */
- atomic_inc(&ch->usrs);
- /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
- fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&ch->prio, &fh->prio);
- mutex_unlock(&common->lock);
-
- return 0;
-}
-
-/*
- * vpif_release: This function deletes buffer queue, frees the buffers and
- * the vpif file handle
- */
-static int vpif_release(struct file *filep)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- mutex_lock(&common->lock);
- /* if this instance is doing IO */
- if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
- /* Reset io_usrs member of channel object */
- common->io_usrs = 0;
- /* Free buffers allocated */
- vb2_queue_release(&common->buffer_queue);
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
-
- common->numbuffers =
-    config_params.numbuffers[ch->channel_id];
- }
-
- /* Decrement channel usrs counter */
- atomic_dec(&ch->usrs);
- /* If this file handle has initialize encoder device, reset it */
- if (fh->initialized)
- ch->initialized = 0;
-
- /* Close the priority */
- v4l2_prio_close(&ch->prio, fh->prio);
- filep->private_data = NULL;
- fh->initialized = 0;
- mutex_unlock(&common->lock);
- kfree(fh);
-
- return 0;
-}
-
 /* functions implementing ioctls */
 /**
  * vpif_querycap() - QUERYCAP handler
@@ -834,7 +696,7 @@ static int vpif_querycap(struct file *file, void  *priv,
 
  cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
  cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
+ strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
  snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
  dev_name(vpif_dev));
  strlcpy(cap->card, config->card_name, sizeof(cap->card));
@@ -861,8 +723,8 @@ static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
 static int vpif_g_fmt_vid_out(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
  /* Check the validity of the buffer type */
@@ -878,28 +740,14 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv,
 static int vpif_s_fmt_vid_out(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct v4l2_pix_format *pixfmt;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
-    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
-
- /* Check for the priority */
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
- fh->initialized = 1;
- }
+ struct v4l2_pix_format *pixfmt;
+ int ret;
 
- if (common->started) {
- vpif_dbg(1, debug, "Streaming in progress\n");
+ if (vb2_is_streaming(&common->buffer_queue)) {
+ vpif_err("Streaming in progress\n");
  return -EBUSY;
  }
 
@@ -919,8 +767,8 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv,
 static int vpif_try_fmt_vid_out(struct file *file, void *priv,
  struct v4l2_format *fmt)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
  int ret = 0;
@@ -934,131 +782,18 @@ static int vpif_try_fmt_vid_out(struct file *file, void *priv,
  return ret;
 }
 
-static int vpif_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- enum v4l2_field field;
- struct vb2_queue *q;
- u8 index = 0;
- int ret;
-
- /* This file handle has not initialized the channel,
-   It is not allowed to do settings */
- if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
-    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_err("Channel Busy\n");
- return -EBUSY;
- }
- }
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
- return -EINVAL;
-
- index = VPIF_VIDEO_INDEX;
-
- common = &ch->common[index];
-
- if (common->fmt.type != reqbuf->type || !vpif_dev)
- return -EINVAL;
- if (0 != common->io_usrs)
- return -EBUSY;
-
- if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
- field = V4L2_FIELD_INTERLACED;
- else
- field = common->fmt.fmt.pix.field;
- } else {
- field = V4L2_VBI_INTERLACED;
- }
- /* Initialize videobuf2 queue as per the buffer type */
- common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
- if (IS_ERR(common->alloc_ctx)) {
- vpif_err("Failed to get the context\n");
- return PTR_ERR(common->alloc_ctx);
- }
- q = &common->buffer_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fh;
- q->ops = &video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct vpif_disp_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->min_buffers_needed = 1;
-
- ret = vb2_queue_init(q);
- if (ret) {
- vpif_err("vpif_display: vb2_queue_init() failed\n");
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
- return ret;
- }
- /* Set io allowed member of file handle to TRUE */
- fh->io_allowed[index] = 1;
- /* Increment io usrs member of channel object to 1 */
- common->io_usrs = 1;
- /* Store type of memory requested in channel object */
- common->memory = reqbuf->memory;
- INIT_LIST_HEAD(&common->dma_queue);
- /* Allocate buffers */
- return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-static int vpif_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *tbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (common->fmt.type != tbuf->type)
- return -EINVAL;
-
- return vb2_querybuf(&common->buffer_queue, tbuf);
-}
-
-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;
-
- if (!buf || !priv)
- return -EINVAL;
-
- 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]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- return vb2_qbuf(&common->buffer_queue, buf);
-}
-
 static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  int ret = 0;
 
  if (!(std_id & VPIF_V4L2_STD))
  return -EINVAL;
 
- if (common->started) {
- vpif_err("streaming in progress\n");
+ if (vb2_is_streaming(&common->buffer_queue)) {
+ vpif_err("Streaming in progress\n");
  return -EBUSY;
  }
 
@@ -1096,123 +831,18 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  *std = ch->video.stdid;
  return 0;
 }
 
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- return vb2_dqbuf(&common->buffer_queue, p,
- (file->f_flags & O_NONBLOCK));
-}
-
-static int vpif_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
- int ret = 0;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- vpif_err("buffer type not supported\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- /* If Streaming is already started, return error */
- if (common->started) {
- vpif_err("channel->started\n");
- return -EBUSY;
- }
-
- if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
- && oth_ch->common[VPIF_VIDEO_INDEX].started &&
- ch->vpifparams.std_info.ycmux_mode == 0)
- || ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
- && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
- vpif_err("other channel is using\n");
- return -EBUSY;
- }
-
- ret = vpif_check_format(ch, &common->fmt.fmt.pix);
- if (ret < 0)
- return ret;
-
- /* Call vb2_streamon to start streaming in videobuf2 */
- ret = vb2_streamon(&common->buffer_queue, buftype);
- if (ret < 0) {
- vpif_err("vb2_streamon\n");
- return ret;
- }
-
- return ret;
-}
-
-static int vpif_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_display_config *vpif_config_data =
- vpif_dev->platform_data;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- vpif_err("buffer type not supported\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- if (!common->started) {
- vpif_err("channel->started\n");
- return -EINVAL;
- }
-
- if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- /* disable channel */
- if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- if (vpif_config_data->
- chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
- channel2_clipping_enable(0);
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- if (vpif_config_data->
- chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
- channel3_clipping_enable(0);
- enable_channel3(0);
- channel3_intr_enable(0);
- }
- }
-
- common->started = 0;
- return vb2_streamoff(&common->buffer_queue, buftype);
-}
-
 static int vpif_cropcap(struct file *file, void *priv,
  struct v4l2_cropcap *crop)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
  return -EINVAL;
@@ -1231,8 +861,8 @@ static int vpif_enum_output(struct file *file, void *fh,
 
  struct vpif_display_config *config = vpif_dev->platform_data;
  struct vpif_display_chan_config *chan_cfg;
- struct vpif_fh *vpif_handler = fh;
- struct channel_obj *ch = vpif_handler->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  chan_cfg = &config->chan_config[ch->channel_id];
  if (output->index >= chan_cfg->output_count) {
@@ -1327,8 +957,8 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 {
  struct vpif_display_config *config = vpif_dev->platform_data;
  struct vpif_display_chan_config *chan_cfg;
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
  chan_cfg = &config->chan_config[ch->channel_id];
@@ -1336,7 +966,7 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
  if (i >= chan_cfg->output_count)
  return -EINVAL;
 
- if (common->started) {
+ if (vb2_is_streaming(&common->buffer_queue)) {
  vpif_err("Streaming in progress\n");
  return -EBUSY;
  }
@@ -1346,32 +976,14 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 
 static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
 
  *i = ch->output_idx;
 
  return 0;
 }
 
-static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- *p = v4l2_prio_max(&ch->prio);
-
- return 0;
-}
-
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
 /**
  * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
  * @file: file ptr
@@ -1382,8 +994,8 @@ static int
 vpif_enum_dv_timings(struct file *file, void *priv,
      struct v4l2_enum_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  int ret;
 
  ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
@@ -1401,14 +1013,18 @@ vpif_enum_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
  struct v4l2_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
+ struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
  struct vpif_params *vpifparams = &ch->vpifparams;
  struct vpif_channel_config_params *std_info = &vpifparams->std_info;
  struct video_obj *vid_ch = &ch->video;
  struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
  int ret;
 
+ if (vb2_is_streaming(&common->buffer_queue))
+ return -EBUSY;
+
  if (timings->type != V4L2_DV_BT_656_1120) {
  vpif_dbg(2, debug, "Timing type not defined\n");
  return -EINVAL;
@@ -1490,8 +1106,8 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
  struct v4l2_dv_timings *timings)
 {
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
+ struct video_device *vdev = video_devdata(file);
+ struct channel_obj *ch = video_get_drvdata(vdev);
  struct video_obj *vid_ch = &ch->video;
 
  *timings = vid_ch->dv_timings;
@@ -1516,47 +1132,45 @@ static int vpif_log_status(struct file *filep, void *priv)
 
 /* vpif display ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
- .vidioc_querycap         = vpif_querycap,
- .vidioc_g_priority = vpif_g_priority,
- .vidioc_s_priority = vpif_s_priority,
+ .vidioc_querycap = vpif_querycap,
  .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out   = vpif_g_fmt_vid_out,
- .vidioc_s_fmt_vid_out   = vpif_s_fmt_vid_out,
- .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
- .vidioc_reqbufs         = vpif_reqbufs,
- .vidioc_querybuf         = vpif_querybuf,
- .vidioc_qbuf             = vpif_qbuf,
- .vidioc_dqbuf           = vpif_dqbuf,
- .vidioc_streamon         = vpif_streamon,
- .vidioc_streamoff       = vpif_streamoff,
- .vidioc_s_std           = vpif_s_std,
+ .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out,
+ .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ .vidioc_s_std = vpif_s_std,
  .vidioc_g_std = vpif_g_std,
+
  .vidioc_enum_output = vpif_enum_output,
  .vidioc_s_output = vpif_s_output,
  .vidioc_g_output = vpif_g_output,
- .vidioc_cropcap         = vpif_cropcap,
- .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
- .vidioc_s_dv_timings            = vpif_s_dv_timings,
- .vidioc_g_dv_timings            = vpif_g_dv_timings,
+ .vidioc_cropcap = vpif_cropcap,
+
+ .vidioc_enum_dv_timings = vpif_enum_dv_timings,
+ .vidioc_s_dv_timings = vpif_s_dv_timings,
+ .vidioc_g_dv_timings = vpif_g_dv_timings,
+
  .vidioc_log_status = vpif_log_status,
 };
 
 static const struct v4l2_file_operations vpif_fops = {
  .owner = THIS_MODULE,
- .open = vpif_open,
- .release = vpif_release,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
  .unlocked_ioctl = video_ioctl2,
- .mmap = vpif_mmap,
- .poll = vpif_poll
+ .mmap = vb2_fop_mmap,
+ .poll = vb2_fop_poll,
 };
 
-static struct video_device vpif_video_template = {
- .name = "vpif",
- .fops = &vpif_fops,
- .ioctl_ops = &vpif_ioctl_ops,
-};
-
-/*Configure the channels, buffer sizei, request irq */
+/* Configure the channels, buffer size */
 static int initialize_vpif(void)
 {
  int free_channel_objects_index;
@@ -1638,18 +1252,17 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 static int vpif_probe_complete(void)
 {
  struct common_obj *common;
+ struct video_device *vdev;
  struct channel_obj *ch;
+ struct vb2_queue *q;
  int j, err, k;
 
  for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
  ch = vpif_obj.dev[j];
  /* Initialize field of the channel objects */
- atomic_set(&ch->usrs, 0);
  for (k = 0; k < VPIF_NUMOBJECTS; k++) {
  ch->common[k].numbuffers = 0;
  common = &ch->common[k];
- common->io_usrs = 0;
- common->started = 0;
  spin_lock_init(&common->irqlock);
  mutex_init(&common->lock);
  common->numbuffers = 0;
@@ -1663,9 +1276,10 @@ static int vpif_probe_complete(void)
  memset(&common->fmt, 0, sizeof(common->fmt));
  common->numbuffers = config_params.numbuffers[k];
  }
- ch->initialized = 0;
+
  if (vpif_obj.config->subdev_count)
  ch->sd = vpif_obj.sd[0];
+
  ch->channel_id = j;
  if (j < 2)
  ch->common[VPIF_VIDEO_INDEX].numbuffers =
@@ -1675,26 +1289,64 @@ static int vpif_probe_complete(void)
 
  memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
 
- /* Initialize prio member of channel object */
- v4l2_prio_init(&ch->prio);
  ch->common[VPIF_VIDEO_INDEX].fmt.type =
  V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ch->video_dev->lock = &common->lock;
- video_set_drvdata(ch->video_dev, ch);
 
  /* select output 0 */
  err = vpif_set_output(vpif_obj.config, ch, 0);
  if (err)
  goto probe_out;
 
+ /* Initialize vb2 queue */
+ q = &common->buffer_queue;
+ q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ q->io_modes = VB2_MMAP | VB2_USERPTR;
+ q->drv_priv = ch;
+ q->ops = &video_qops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct vpif_disp_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->min_buffers_needed = 3;
+ q->lock = &common->lock;
+ q->gfp_flags = GFP_DMA32;
+
+ err = vb2_queue_init(q);
+ if (err) {
+ vpif_err("vpif_display: vb2_queue_init() failed\n");
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
+ goto probe_out;
+ }
+
+ common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
+ if (IS_ERR(common->alloc_ctx)) {
+ vpif_err("Failed to get the context\n");
+ err = PTR_ERR(common->alloc_ctx);
+ goto probe_out;
+ }
+
+ INIT_LIST_HEAD(&common->dma_queue);
+
+ /* Initialize the video_device structure */
+ vdev = ch->video_dev;
+ strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+ vdev->release = video_device_release;
+ vdev->fops = &vpif_fops;
+ vdev->ioctl_ops = &vpif_ioctl_ops;
+ vdev->lock = &common->lock;
+ vdev->queue = q;
+ vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+ vdev->vfl_dir = VFL_DIR_TX;
+ set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+ video_set_drvdata(vdev, ch);
+
  /* register video device */
+ err = video_register_device(vdev,
+    VFL_TYPE_GRABBER, (j ? 3 : 2));
+ if (err < 0)
+ goto probe_out;
  vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
  (int)ch, (int)&ch->video_dev);
 
- err = video_register_device(ch->video_dev,
-  VFL_TYPE_GRABBER, (j ? 3 : 2));
- if (err < 0)
- goto probe_out;
  }
 
  return 0;
@@ -1702,6 +1354,9 @@ static int vpif_probe_complete(void)
 probe_out:
  for (k = 0; k < j; k++) {
  ch = vpif_obj.dev[k];
+ common = &ch->common[k];
+
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
  video_unregister_device(ch->video_dev);
  video_device_release(ch->video_dev);
  ch->video_dev = NULL;
@@ -1746,7 +1401,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
  while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
  err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
- IRQF_SHARED, "VPIF_Display",
+ IRQF_SHARED, VPIF_DRIVER_NAME,
  (void *)(&vpif_obj.dev[res_idx]->
  channel_id));
  if (err) {
@@ -1772,15 +1427,6 @@ static __init int vpif_probe(struct platform_device *pdev)
  goto vpif_unregister;
  }
 
- /* Initialize field of video device */
- *vfd = vpif_video_template;
- vfd->v4l2_dev = &vpif_obj.v4l2_dev;
- vfd->release = video_device_release;
- vfd->vfl_dir = VFL_DIR_TX;
- snprintf(vfd->name, sizeof(vfd->name),
- "VPIF_Display_DRIVER_V%s",
- VPIF_DISPLAY_VERSION);
-
  /* Set video_dev to the video device */
  ch->video_dev = vfd;
  }
@@ -1867,6 +1513,7 @@ vpif_unregister:
  */
 static int vpif_remove(struct platform_device *device)
 {
+ struct common_obj *common;
  struct channel_obj *ch;
  int i;
 
@@ -1877,9 +1524,11 @@ static int vpif_remove(struct platform_device *device)
  for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
+ common = &ch->common[i];
  /* Unregister video device */
  video_unregister_device(ch->video_dev);
 
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
  ch->video_dev = NULL;
  kfree(vpif_obj.dev[i]);
  }
@@ -1887,7 +1536,7 @@ static int vpif_remove(struct platform_device *device)
  return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int vpif_suspend(struct device *dev)
 {
  struct common_obj *common;
@@ -1898,18 +1547,19 @@ static int vpif_suspend(struct device *dev)
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
  common = &ch->common[VPIF_VIDEO_INDEX];
+
+ if (!vb2_is_streaming(&common->buffer_queue))
+ continue;
+
  mutex_lock(&common->lock);
- if (atomic_read(&ch->usrs) && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
- common->started == 2) {
- enable_channel3(0);
- channel3_intr_enable(0);
- }
+ /* Disable channel */
+ if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+ enable_channel2(0);
+ channel2_intr_enable(0);
+ }
+ if (ch->channel_id == VPIF_CHANNEL3_VIDEO) {
+ enable_channel3(0);
+ channel3_intr_enable(0);
  }
  mutex_unlock(&common->lock);
  }
@@ -1928,40 +1578,34 @@ static int vpif_resume(struct device *dev)
  /* Get the pointer to the channel object */
  ch = vpif_obj.dev[i];
  common = &ch->common[VPIF_VIDEO_INDEX];
+
+ if (!vb2_is_streaming(&common->buffer_queue))
+ continue;
+
  mutex_lock(&common->lock);
- if (atomic_read(&ch->usrs) && common->io_usrs) {
- /* Enable channel */
- if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
- enable_channel2(1);
- channel2_intr_enable(1);
- }
- if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
- common->started == 2) {
- enable_channel3(1);
- channel3_intr_enable(1);
- }
+ /* Enable channel */
+ if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+ enable_channel2(1);
+ channel2_intr_enable(1);
+ }
+ if (ch->channel_id == VPIF_CHANNEL3_VIDEO) {
+ enable_channel3(1);
+ channel3_intr_enable(1);
  }
  mutex_unlock(&common->lock);
  }
 
  return 0;
 }
-
-static const struct dev_pm_ops vpif_pm = {
- .suspend        = vpif_suspend,
- .resume         = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_pm)
-#else
-#define vpif_pm_ops NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
 static __refdata struct platform_driver vpif_driver = {
  .driver = {
- .name = "vpif_display",
+ .name = VPIF_DRIVER_NAME,
  .owner = THIS_MODULE,
- .pm = vpif_pm_ops,
+ .pm = &vpif_pm_ops,
  },
  .probe = vpif_probe,
  .remove = vpif_remove,
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index 4d0485b..72f9b4f 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -67,17 +67,11 @@ struct vpif_disp_buffer {
 };
 
 struct common_obj {
- /* Buffer specific parameters */
- u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
- * storing frames */
  u32 numbuffers; /* number of buffers */
  struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current
  * vb2_buffer */
  struct vpif_disp_buffer *next_frm; /* Pointer pointing to next
  * vb2_buffer */
- enum v4l2_memory memory; /* This field keeps track of
- * type of buffer exchange
- * method user has selected */
  struct v4l2_format fmt; /* Used to store the format */
  struct vb2_queue buffer_queue; /* Buffer queue used in
  * video-buf */
@@ -90,10 +84,6 @@ struct common_obj {
  /* channel specific parameters */
  struct mutex lock; /* lock used to access this
  * structure */
- u32 io_usrs; /* number of users performing
- * IO */
- u8 started; /* Indicates whether streaming
- * started */
  u32 ytop_off; /* offset of Y top from the
  * starting of the buffer */
  u32 ybtm_off; /* offset of Y bottom from the
@@ -103,7 +93,7 @@ struct common_obj {
  u32 cbtm_off; /* offset of C bottom from the
  * starting of the buffer */
  /* Function pointer to set the addresses */
- void (*set_addr) (unsigned long, unsigned long,
+ void (*set_addr)(unsigned long, unsigned long,
  unsigned long, unsigned long);
  u32 height;
  u32 width;
@@ -113,14 +103,8 @@ struct channel_obj {
  /* V4l2 specific parameters */
  struct video_device *video_dev; /* Identifies video device for
  * this channel */
- struct v4l2_prio_state prio; /* Used to keep track of state of
- * the priority */
- atomic_t usrs; /* number of open instances of
- * the channel */
  u32 field_id; /* Indicates id of the field
  * which is being displayed */
- u8 initialized; /* flag to indicate whether
- * encoder is initialized */
  u32 output_idx; /* Current output index */
  struct v4l2_subdev *sd; /* Current output subdev(may be NULL) */
 
@@ -130,19 +114,6 @@ struct channel_obj {
  struct video_obj video;
 };
 
-/* File handle structure */
-struct vpif_fh {
- struct channel_obj *channel; /* pointer to channel object for
- * opened device */
- u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
- * is doing IO */
- enum v4l2_priority prio; /* Used to keep track priority of
- * this instance */
- u8 initialized; /* Used to keep track of whether this
- * file handle has initialized
- * channel or not */
-};
-
 /* vpif device structure */
 struct vpif_device {
  struct v4l2_device v4l2_dev;
--
1.7.9.5

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] media: davinci: vpif capture: upgrade the driver with v4l offerings

Hans Verkuil
In reply to this post by Lad, Prabhakar
Hi Prabhakar,

This looks really nice!

I'll do a full review on Friday, but in the meantime can you post the output
of 'v4l2-compliance -s' using the latest v4l2-compliance version? I've made
some commits today, so you need to do a git pull of v4l-utils.git.

I also have a small comment below:

On 03/31/2014 04:52 PM, Lad, Prabhakar wrote:

> From: "Lad, Prabhakar" <[hidden email]>
>
> This patch upgrades the vpif display driver with
> v4l helpers, this patch does the following,
>
> 1: initialize the vb2 queue and context at the time of probe
> and removes context at remove() callback.
> 2: uses vb2_ioctl_*() helpers.
> 3: uses vb2_fop_*() helpers.
> 4: uses SIMPLE_DEV_PM_OPS.
> 5: uses vb2_ioctl_*() helpers.
> 6: vidioc_g/s_priority is now handled by v4l core.
> 7: removed driver specific fh and now using one provided by v4l.
> 8: fixes checkpatch warnings.
>
> Signed-off-by: Lad, Prabhakar <[hidden email]>
> ---
>  drivers/media/platform/davinci/vpif_capture.c |  916 ++++++-------------------
>  drivers/media/platform/davinci/vpif_capture.h |   32 +-
>  2 files changed, 229 insertions(+), 719 deletions(-)
>
> diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
> index 8dea0b8..76c15b3 100644
> --- a/drivers/media/platform/davinci/vpif_capture.c
> +++ b/drivers/media/platform/davinci/vpif_capture.c

...

>  static int vpif_buffer_init(struct vb2_buffer *vb)
>  {
> - struct vpif_cap_buffer *buf = container_of(vb,
> - struct vpif_cap_buffer, vb);
> + struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
>  
>   INIT_LIST_HEAD(&buf->list);
>  
>   return 0;
>  }

Is this really necessary? I think vpif_buffer_init can just be removed.
Ditto for vpif_display.c.

Regards,

        Hans
_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] media: davinci: vpif capture: upgrade the driver with v4l offerings

Lad, Prabhakar
Hi Hans,

On Mon, Mar 31, 2014 at 8:34 PM, Hans Verkuil <[hidden email]> wrote:
> Hi Prabhakar,
>
> This looks really nice!
>
Writing a video driver has become really easy with almost 90% of work
done by v4l core itself :)

> I'll do a full review on Friday, but in the meantime can you post the output
OK.

> of 'v4l2-compliance -s' using the latest v4l2-compliance version? I've made
> some commits today, so you need to do a git pull of v4l-utils.git.
>
I had compilation failures for v4l2-compliance following is the patch
fixing that, (I am
facing some issues in cross compilation once done I'll post the o/p of it)

--------------X------------X-------------------

>From 14029f4ca57be5f2b0ec053d375655ca5a60f698 Mon Sep 17 00:00:00 2001
From: "Lad, Prabhakar" <[hidden email]>
Date: Mon, 31 Mar 2014 22:24:33 +0530
Subject: [PATCH] v4l-utils: v4l-compliance: fix compilation

this patch fixes following build error,

In file included from v4l2-compliance.h:31,
                 from v4l2-compliance.cpp:37:
./cv4l-helpers.h:9: error: a class-key must be used when declaring a friend
./cv4l-helpers.h:9: error: friend declaration does not name a class or function
./cv4l-helpers.h: In member function 'int cv4l_buffer::querybuf(const
cv4l_queue&, unsigned int)':
./cv4l-helpers.h:103: error: 'v4l_fd* cv4l_queue::fd' is protected
./cv4l-helpers.h:213: error: within this context
./cv4l-helpers.h: In member function 'int cv4l_buffer::dqbuf(const
cv4l_queue&)':
./cv4l-helpers.h:103: error: 'v4l_fd* cv4l_queue::fd' is protected
./cv4l-helpers.h:221: error: within this context
./cv4l-helpers.h: In member function 'int cv4l_buffer::qbuf(const cv4l_queue&)':
./cv4l-helpers.h:103: error: 'v4l_fd* cv4l_queue::fd' is protected
./cv4l-helpers.h:229: error: within this context
./cv4l-helpers.h: In member function 'int
cv4l_buffer::prepare_buf(const cv4l_queue&)':
./cv4l-helpers.h:103: error: 'v4l_fd* cv4l_queue::fd' is protected
./cv4l-helpers.h:237: error: within this context
v4l2-compliance.cpp: In function 'void v4l_fd_test_init(v4l_fd*, int)':
v4l2-compliance.cpp:132: error: invalid conversion from 'void*
(*)(void*, size_t, int, int, int, int64_t)' to 'void* (*)(void*,
size_t, int, int, int, off_t)'

Signed-off-by: Lad, Prabhakar <[hidden email]>
---
 utils/v4l2-compliance/cv4l-helpers.h    |    2 +-
 utils/v4l2-compliance/v4l2-compliance.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/utils/v4l2-compliance/cv4l-helpers.h
b/utils/v4l2-compliance/cv4l-helpers.h
index 2423ef9..e2729a6 100644
--- a/utils/v4l2-compliance/cv4l-helpers.h
+++ b/utils/v4l2-compliance/cv4l-helpers.h
@@ -6,7 +6,7 @@
 class cv4l_buffer;

 class cv4l_queue : v4l_queue {
-    friend cv4l_buffer;
+    friend class cv4l_buffer;
 public:
     cv4l_queue(v4l_fd *_fd, unsigned type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
                 unsigned memory = V4L2_MEMORY_MMAP)
diff --git a/utils/v4l2-compliance/v4l2-compliance.h
b/utils/v4l2-compliance/v4l2-compliance.h
index f2f7072..b6d4dae 100644
--- a/utils/v4l2-compliance/v4l2-compliance.h
+++ b/utils/v4l2-compliance/v4l2-compliance.h
@@ -137,7 +137,7 @@ static inline int test_ioctl(int fd, unsigned long cmd, ...)
 }

 static inline void *test_mmap(void *start, size_t length, int prot, int flags,
-        int fd, int64_t offset)
+        int fd, off_t offset)
 {
      return wrapper ? v4l2_mmap(start, length, prot, flags, fd, offset) :
         mmap(start, length, prot, flags, fd, offset);
--
1.7.9.5


> I also have a small comment below:
>
> On 03/31/2014 04:52 PM, Lad, Prabhakar wrote:
>> From: "Lad, Prabhakar" <[hidden email]>
>>
>> This patch upgrades the vpif display driver with
>> v4l helpers, this patch does the following,
>>
>> 1: initialize the vb2 queue and context at the time of probe
>> and removes context at remove() callback.
>> 2: uses vb2_ioctl_*() helpers.
>> 3: uses vb2_fop_*() helpers.
>> 4: uses SIMPLE_DEV_PM_OPS.
>> 5: uses vb2_ioctl_*() helpers.
>> 6: vidioc_g/s_priority is now handled by v4l core.
>> 7: removed driver specific fh and now using one provided by v4l.
>> 8: fixes checkpatch warnings.
>>
>> Signed-off-by: Lad, Prabhakar <[hidden email]>
>> ---
>>  drivers/media/platform/davinci/vpif_capture.c |  916 ++++++-------------------
>>  drivers/media/platform/davinci/vpif_capture.h |   32 +-
>>  2 files changed, 229 insertions(+), 719 deletions(-)
>>
>> diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
>> index 8dea0b8..76c15b3 100644
>> --- a/drivers/media/platform/davinci/vpif_capture.c
>> +++ b/drivers/media/platform/davinci/vpif_capture.c
>
> ...
>
>>  static int vpif_buffer_init(struct vb2_buffer *vb)
>>  {
>> -     struct vpif_cap_buffer *buf = container_of(vb,
>> -                                     struct vpif_cap_buffer, vb);
>> +     struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
>>
>>       INIT_LIST_HEAD(&buf->list);
>>
>>       return 0;
>>  }
>
> Is this really necessary? I think vpif_buffer_init can just be removed.
> Ditto for vpif_display.c.
>
Yes can be dropped, will remove in next version.

Thanks,
--Prabhakar Lad
_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] media: davinci: vpif capture: upgrade the driver with v4l offerings

Hans Verkuil
On 03/31/2014 07:24 PM, Prabhakar Lad wrote:
> Hi Hans,
>
> On Mon, Mar 31, 2014 at 8:34 PM, Hans Verkuil <[hidden email]> wrote:
>> Hi Prabhakar,
>>
>> This looks really nice!
>>
> Writing a video driver has become really easy with almost 90% of work
> done by v4l core itself :)

That was the idea!

>> I'll do a full review on Friday, but in the meantime can you post the output
> OK.
>
>> of 'v4l2-compliance -s' using the latest v4l2-compliance version? I've made
>> some commits today, so you need to do a git pull of v4l-utils.git.
>>
> I had compilation failures for v4l2-compliance following is the patch
> fixing that, (I am
> facing some issues in cross compilation once done I'll post the o/p of it)

I fixed the 'friend' issue (weird that it didn't fail with my g++) and the other
issue was already fixed yesterday.

Regards,

        Hans
_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source