Merge tag 'vfio-v3.19-rc1' of git://github.com/awilliam/linux-vfio
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / davinci / vpbe_display.c
index 6f9599deb355d3acfe3ef8b85fc7c9e3964871f8..c4ab46f5bd92d80e8a54b943694766f2ee5c4b1b 100644 (file)
@@ -152,8 +152,8 @@ static irqreturn_t venc_isr(int irq, void *arg)
 
        for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
                layer = disp_dev->dev[i];
-               /* If streaming is started in this layer */
-               if (!layer->started)
+
+               if (!vb2_start_streaming_called(&layer->buffer_queue))
                        continue;
 
                if (layer->layer_first_int) {
@@ -215,22 +215,15 @@ static int vpbe_buffer_prepare(struct vb2_buffer *vb)
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
                                "vpbe_buffer_prepare\n");
 
-       if (vb->state != VB2_BUF_STATE_ACTIVE &&
-               vb->state != VB2_BUF_STATE_PREPARED) {
-               vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
-               if (vb2_plane_vaddr(vb, 0) &&
-               vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-                       return -EINVAL;
+       vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
+       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+               return -EINVAL;
 
-               addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-               if (q->streaming) {
-                       if (!IS_ALIGNED(addr, 8)) {
-                               v4l2_err(&vpbe_dev->v4l2_dev,
-                                       "buffer_prepare:offset is \
-                                       not aligned to 32 bytes\n");
-                               return -EINVAL;
-                       }
-               }
+       addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+       if (!IS_ALIGNED(addr, 8)) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                        "buffer_prepare:offset is not aligned to 32 bytes\n");
+               return -EINVAL;
        }
        return 0;
 }
@@ -251,12 +244,15 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
 
+       if (fmt && fmt->fmt.pix.sizeimage < layer->pix_fmt.sizeimage)
+               return -EINVAL;
+
        /* Store number of buffers allocated in numbuffer member */
-       if (*nbuffers < VPBE_DEFAULT_NUM_BUFS)
-               *nbuffers = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
+       if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS)
+               *nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers;
 
        *nplanes = 1;
-       sizes[0] = layer->pix_fmt.sizeimage;
+       sizes[0] = fmt ? fmt->fmt.pix.sizeimage : layer->pix_fmt.sizeimage;
        alloc_ctxs[0] = layer->alloc_ctx;
 
        return 0;
@@ -285,34 +281,14 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb)
        spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
 }
 
-/*
- * vpbe_buf_cleanup()
- * This function is called from the vb2 layer to free memory allocated to
- * the buffers
- */
-static void vpbe_buf_cleanup(struct vb2_buffer *vb)
-{
-       /* Get the file handle object and layer object */
-       struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       struct vpbe_disp_buffer *buf = container_of(vb,
-                                       struct vpbe_disp_buffer, vb);
-       unsigned long flags;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "vpbe_buf_cleanup\n");
-
-       spin_lock_irqsave(&layer->irqlock, flags);
-       if (vb->state == VB2_BUF_STATE_ACTIVE)
-               list_del_init(&buf->list);
-       spin_unlock_irqrestore(&layer->irqlock, flags);
-}
-
 static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
        struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
        int ret;
 
+        osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
+
        /* Get the next frame from the buffer queue */
        layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
                                struct vpbe_disp_buffer, list);
@@ -341,7 +317,6 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
         * if request format is yuv420 semiplanar, need to
         * enable both video windows
         */
-       layer->started = 1;
        layer->layer_first_int = 1;
 
        return ret;
@@ -350,12 +325,15 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
 static void vpbe_stop_streaming(struct vb2_queue *vq)
 {
        struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
        struct vpbe_display *disp = layer->disp_dev;
        unsigned long flags;
 
        if (!vb2_is_streaming(vq))
                return;
 
+       osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
+
        /* release all active buffers */
        spin_lock_irqsave(&disp->dma_queue_lock, flags);
        if (layer->cur_frm == layer->next_frm) {
@@ -385,7 +363,6 @@ static struct vb2_ops video_qops = {
        .buf_prepare = vpbe_buffer_prepare,
        .start_streaming = vpbe_start_streaming,
        .stop_streaming = vpbe_stop_streaming,
-       .buf_cleanup = vpbe_buf_cleanup,
        .buf_queue = vpbe_buffer_queue,
 };
 
@@ -659,10 +636,9 @@ static int vpbe_try_format(struct vpbe_display *disp_dev,
 static int vpbe_display_querycap(struct file *file, void  *priv,
                               struct v4l2_capability *cap)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
-       cap->version = VPBE_DISPLAY_VERSION_CODE;
        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",
@@ -677,9 +653,8 @@ static int vpbe_display_querycap(struct file *file, void  *priv,
 static int vpbe_display_s_crop(struct file *file, void *priv,
                             const struct v4l2_crop *crop)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_display *disp_dev = fh->disp_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
        struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
        struct osd_layer_config *cfg = &layer->layer_info.config;
        struct osd_state *osd_device = disp_dev->osd_device;
@@ -746,11 +721,10 @@ static int vpbe_display_s_crop(struct file *file, void *priv,
 static int vpbe_display_g_crop(struct file *file, void *priv,
                             struct v4l2_crop *crop)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
+       struct vpbe_layer *layer = video_drvdata(file);
        struct osd_layer_config *cfg = &layer->layer_info.config;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       struct osd_state *osd_device = fh->disp_dev->osd_device;
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
        struct v4l2_rect *rect = &crop->c;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -774,8 +748,8 @@ static int vpbe_display_g_crop(struct file *file, void *priv,
 static int vpbe_display_cropcap(struct file *file, void *priv,
                              struct v4l2_cropcap *cropcap)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
 
@@ -792,9 +766,8 @@ static int vpbe_display_cropcap(struct file *file, void *priv,
 static int vpbe_display_g_fmt(struct file *file, void *priv,
                                struct v4l2_format *fmt)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
                        "VIDIOC_G_FMT, layer id = %d\n",
@@ -814,9 +787,8 @@ static int vpbe_display_g_fmt(struct file *file, void *priv,
 static int vpbe_display_enum_fmt(struct file *file, void  *priv,
                                   struct v4l2_fmtdesc *fmt)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        unsigned int index = 0;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -846,9 +818,8 @@ static int vpbe_display_enum_fmt(struct file *file, void  *priv,
 static int vpbe_display_s_fmt(struct file *file, void *priv,
                                struct v4l2_format *fmt)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_display *disp_dev = fh->disp_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
        struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
        struct osd_layer_config *cfg  = &layer->layer_info.config;
        struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
@@ -859,11 +830,9 @@ static int vpbe_display_s_fmt(struct file *file, void *priv,
                        "VIDIOC_S_FMT, layer id = %d\n",
                        layer->device_id);
 
-       /* If streaming is started, return error */
-       if (layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
+       if (vb2_is_busy(&layer->buffer_queue))
                return -EBUSY;
-       }
+
        if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
                v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
                return -EINVAL;
@@ -935,9 +904,9 @@ static int vpbe_display_s_fmt(struct file *file, void *priv,
 static int vpbe_display_try_fmt(struct file *file, void *priv,
                                  struct v4l2_format *fmt)
 {
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_display *disp_dev = fh->disp_dev;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
@@ -961,18 +930,15 @@ static int vpbe_display_try_fmt(struct file *file, void *priv,
 static int vpbe_display_s_std(struct file *file, void *priv,
                                v4l2_std_id std_id)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
 
-       /* If streaming is started, return error */
-       if (layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
+       if (vb2_is_busy(&layer->buffer_queue))
                return -EBUSY;
-       }
+
        if (NULL != vpbe_dev->ops.s_std) {
                ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
                if (ret) {
@@ -996,8 +962,8 @@ static int vpbe_display_s_std(struct file *file, void *priv,
 static int vpbe_display_g_std(struct file *file, void *priv,
                                v4l2_std_id *std_id)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
 
@@ -1019,8 +985,8 @@ static int vpbe_display_g_std(struct file *file, void *priv,
 static int vpbe_display_enum_output(struct file *file, void *priv,
                                    struct v4l2_output *output)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
@@ -1047,17 +1013,15 @@ static int vpbe_display_enum_output(struct file *file, void *priv,
 static int vpbe_display_s_output(struct file *file, void *priv,
                                unsigned int i)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
-       /* If streaming is started, return error */
-       if (layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
+
+       if (vb2_is_busy(&layer->buffer_queue))
                return -EBUSY;
-       }
+
        if (NULL == vpbe_dev->ops.set_output)
                return -EINVAL;
 
@@ -1078,8 +1042,8 @@ static int vpbe_display_s_output(struct file *file, void *priv,
 static int vpbe_display_g_output(struct file *file, void *priv,
                                unsigned int *i)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
        /* Get the standard from the current encoder */
@@ -1098,8 +1062,8 @@ static int
 vpbe_display_enum_dv_timings(struct file *file, void *priv,
                        struct v4l2_enum_dv_timings *timings)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
@@ -1128,19 +1092,14 @@ static int
 vpbe_display_s_dv_timings(struct file *file, void *priv,
                                struct v4l2_dv_timings *timings)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
        int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
 
-
-       /* If streaming is started, return error */
-       if (layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
+       if (vb2_is_busy(&layer->buffer_queue))
                return -EBUSY;
-       }
 
        /* Set the given standard in the encoder */
        if (!vpbe_dev->ops.s_dv_timings)
@@ -1166,8 +1125,8 @@ static int
 vpbe_display_g_dv_timings(struct file *file, void *priv,
                                struct v4l2_dv_timings *dv_timings)
 {
-       struct vpbe_fh *fh = priv;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
 
@@ -1183,233 +1142,6 @@ vpbe_display_g_dv_timings(struct file *file, void *priv,
        return 0;
 }
 
-static int vpbe_display_streamoff(struct file *file, void *priv,
-                               enum v4l2_buf_type buf_type)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       struct osd_state *osd_device = fh->disp_dev->osd_device;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "VIDIOC_STREAMOFF,layer id = %d\n",
-                       layer->device_id);
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-
-       /* If io is allowed for this file handle, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
-               return -EACCES;
-       }
-
-       /* If streaming is not started, return error */
-       if (!layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer"
-                       " id = %d\n", layer->device_id);
-               return -EINVAL;
-       }
-
-       osd_device->ops.disable_layer(osd_device,
-                       layer->layer_info.id);
-       layer->started = 0;
-       ret = vb2_streamoff(&layer->buffer_queue, buf_type);
-
-       return ret;
-}
-
-static int vpbe_display_streamon(struct file *file, void *priv,
-                        enum v4l2_buf_type buf_type)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_display *disp_dev = fh->disp_dev;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       struct osd_state *osd_device = disp_dev->osd_device;
-       int ret;
-
-       osd_device->ops.disable_layer(osd_device,
-                       layer->layer_info.id);
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_STREAMON, layerid=%d\n",
-                                               layer->device_id);
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-
-       /* If file handle is not allowed IO, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
-               return -EACCES;
-       }
-       /* If Streaming is already started, return error */
-       if (layer->started) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n");
-               return -EBUSY;
-       }
-
-       /*
-        * Call vb2_streamon to start streaming
-        * in videobuf
-        */
-       ret = vb2_streamon(&layer->buffer_queue, buf_type);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-               "error in vb2_streamon\n");
-               return ret;
-       }
-       return ret;
-}
-
-static int vpbe_display_dqbuf(struct file *file, void *priv,
-                     struct v4l2_buffer *buf)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "VIDIOC_DQBUF, layer id = %d\n",
-               layer->device_id);
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-       /* If this file handle is not allowed to do IO, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
-               return -EACCES;
-       }
-       if (file->f_flags & O_NONBLOCK)
-               /* Call videobuf_dqbuf for non blocking mode */
-               ret = vb2_dqbuf(&layer->buffer_queue, buf, 1);
-       else
-               /* Call videobuf_dqbuf for blocking mode */
-               ret = vb2_dqbuf(&layer->buffer_queue, buf, 0);
-
-       return ret;
-}
-
-static int vpbe_display_qbuf(struct file *file, void *priv,
-                    struct v4l2_buffer *p)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "VIDIOC_QBUF, layer id = %d\n",
-               layer->device_id);
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != p->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-
-       /* If this file handle is not allowed to do IO, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
-               return -EACCES;
-       }
-
-       return vb2_qbuf(&layer->buffer_queue, p);
-}
-
-static int vpbe_display_querybuf(struct file *file, void *priv,
-                        struct v4l2_buffer *buf)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "VIDIOC_QUERYBUF, layer id = %d\n",
-               layer->device_id);
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-       /* Call vb2_querybuf to get information */
-       return vb2_querybuf(&layer->buffer_queue, buf);
-}
-
-static int vpbe_display_reqbufs(struct file *file, void *priv,
-                       struct v4l2_requestbuffers *req_buf)
-{
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-
-       /* If io users of the layer is not zero, return error */
-       if (0 != layer->io_usrs) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n");
-               return -EBUSY;
-       }
-       /* Set io allowed member of file handle to TRUE */
-       fh->io_allowed = 1;
-       /* Increment io usrs member of layer object to 1 */
-       layer->io_usrs = 1;
-       /* Store type of memory requested in layer object */
-       layer->memory = req_buf->memory;
-       /* Allocate buffers */
-       return vb2_reqbufs(&layer->buffer_queue, req_buf);
-}
-
-/*
- * vpbe_display_mmap()
- * It is used to map kernel space buffers into user spaces
- */
-static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
-{
-       /* Get the layer object and file handle object */
-       struct vpbe_fh *fh = filep->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n");
-
-       if (mutex_lock_interruptible(&layer->opslock))
-               return -ERESTARTSYS;
-       ret = vb2_mmap(&layer->buffer_queue, vma);
-       mutex_unlock(&layer->opslock);
-       return ret;
-}
-
-/* vpbe_display_poll(): It is used for select/poll system call
- */
-static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
-{
-       struct vpbe_fh *fh = filep->private_data;
-       struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       unsigned int err = 0;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
-       if (layer->started) {
-               mutex_lock(&layer->opslock);
-               err = vb2_poll(&layer->buffer_queue, filep, wait);
-               mutex_unlock(&layer->opslock);
-       }
-       return err;
-}
-
 /*
  * vpbe_display_open()
  * It creates object of file handle structure and stores it in private_data
@@ -1417,30 +1149,22 @@ static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
  */
 static int vpbe_display_open(struct file *file)
 {
-       struct vpbe_fh *fh = NULL;
        struct vpbe_layer *layer = video_drvdata(file);
-       struct video_device *vdev = video_devdata(file);
        struct vpbe_display *disp_dev = layer->disp_dev;
        struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
        struct osd_state *osd_device = disp_dev->osd_device;
        int err;
 
-       /* Allocate memory for the file handle object */
-       fh = kmalloc(sizeof(struct vpbe_fh), GFP_KERNEL);
-       if (fh == NULL) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "unable to allocate memory for file handle object\n");
-               return -ENOMEM;
+       /* creating context for file descriptor */
+       err = v4l2_fh_open(file);
+       if (err) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n");
+               return err;
        }
-       v4l2_fh_init(&fh->fh, vdev);
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "vpbe display open plane = %d\n",
-                       layer->device_id);
 
-       /* store pointer to fh in private_data member of filep */
-       file->private_data = fh;
-       fh->layer = layer;
-       fh->disp_dev = disp_dev;
+       /* leaving if layer is already initialized */
+       if (!v4l2_fh_is_singular_file(file))
+               return err;
 
        if (!layer->usrs) {
                if (mutex_lock_interruptible(&layer->opslock))
@@ -1453,15 +1177,12 @@ static int vpbe_display_open(struct file *file)
                        /* Couldn't get layer */
                        v4l2_err(&vpbe_dev->v4l2_dev,
                                "Display Manager failed to allocate layer\n");
-                       kfree(fh);
+                       v4l2_fh_release(file);
                        return -EINVAL;
                }
        }
        /* Increment layer usrs counter */
        layer->usrs++;
-       /* Set io_allowed member to false */
-       fh->io_allowed = 0;
-       v4l2_fh_add(&fh->fh);
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
                        "vpbe display device opened successfully\n");
        return 0;
@@ -1474,27 +1195,18 @@ static int vpbe_display_open(struct file *file)
  */
 static int vpbe_display_release(struct file *file)
 {
-       /* Get the layer object and file handle object */
-       struct vpbe_fh *fh = file->private_data;
-       struct vpbe_layer *layer = fh->layer;
+       struct vpbe_layer *layer = video_drvdata(file);
        struct osd_layer_config *cfg  = &layer->layer_info.config;
-       struct vpbe_display *disp_dev = fh->disp_dev;
+       struct vpbe_display *disp_dev = layer->disp_dev;
        struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
        struct osd_state *osd_device = disp_dev->osd_device;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
 
        mutex_lock(&layer->opslock);
-       /* if this instance is doing IO */
-       if (fh->io_allowed) {
-               /* Reset io_usrs member of layer object */
-               layer->io_usrs = 0;
-
-               osd_device->ops.disable_layer(osd_device,
-                               layer->layer_info.id);
-               layer->started = 0;
-       }
 
+       osd_device->ops.disable_layer(osd_device,
+                       layer->layer_info.id);
        /* Decrement layer usrs counter */
        layer->usrs--;
        /* If this file handle has initialize encoder device, reset it */
@@ -1514,14 +1226,9 @@ static int vpbe_display_release(struct file *file)
                                layer->layer_info.id);
        }
 
-       v4l2_fh_del(&fh->fh);
-       v4l2_fh_exit(&fh->fh);
-       file->private_data = NULL;
+       _vb2_fop_release(file, NULL);
        mutex_unlock(&layer->opslock);
 
-       /* Free memory allocated to file handle object */
-       kfree(fh);
-
        disp_dev->cbcr_ofst = 0;
 
        return 0;
@@ -1534,20 +1241,27 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
        .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
        .vidioc_s_fmt_vid_out    = vpbe_display_s_fmt,
        .vidioc_try_fmt_vid_out  = vpbe_display_try_fmt,
-       .vidioc_reqbufs          = vpbe_display_reqbufs,
-       .vidioc_querybuf         = vpbe_display_querybuf,
-       .vidioc_qbuf             = vpbe_display_qbuf,
-       .vidioc_dqbuf            = vpbe_display_dqbuf,
-       .vidioc_streamon         = vpbe_display_streamon,
-       .vidioc_streamoff        = vpbe_display_streamoff,
+
+       .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_expbuf           = vb2_ioctl_expbuf,
+
        .vidioc_cropcap          = vpbe_display_cropcap,
        .vidioc_g_crop           = vpbe_display_g_crop,
        .vidioc_s_crop           = vpbe_display_s_crop,
+
        .vidioc_s_std            = vpbe_display_s_std,
        .vidioc_g_std            = vpbe_display_g_std,
+
        .vidioc_enum_output      = vpbe_display_enum_output,
        .vidioc_s_output         = vpbe_display_s_output,
        .vidioc_g_output         = vpbe_display_g_output,
+
        .vidioc_s_dv_timings     = vpbe_display_s_dv_timings,
        .vidioc_g_dv_timings     = vpbe_display_g_dv_timings,
        .vidioc_enum_dv_timings  = vpbe_display_enum_dv_timings,
@@ -1558,8 +1272,8 @@ static struct v4l2_file_operations vpbe_fops = {
        .open = vpbe_display_open,
        .release = vpbe_display_release,
        .unlocked_ioctl = video_ioctl2,
-       .mmap = vpbe_display_mmap,
-       .poll = vpbe_display_poll
+       .mmap = vb2_fop_mmap,
+       .poll =  vb2_fop_poll,
 };
 
 static int vpbe_device_get(struct device *dev, void *data)
@@ -1639,6 +1353,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer,
                  (int)vpbe_display_layer,
                  (int)&vpbe_display_layer->video_dev);
 
+       vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
        err = video_register_device(&vpbe_display_layer->video_dev,
                                    VFL_TYPE_GRABBER,
                                    -1);
@@ -1728,7 +1443,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
                q = &disp_dev->dev[i]->buffer_queue;
                memset(q, 0, sizeof(*q));
                q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-               q->io_modes = VB2_MMAP | VB2_USERPTR;
+               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
                q->drv_priv = disp_dev->dev[i];
                q->ops = &video_qops;
                q->mem_ops = &vb2_dma_contig_memops;
@@ -1811,7 +1526,6 @@ static int vpbe_display_remove(struct platform_device *pdev)
 static struct platform_driver vpbe_display_driver = {
        .driver = {
                .name = VPBE_DISPLAY_DRIVER,
-               .owner = THIS_MODULE,
                .bus = &platform_bus_type,
        },
        .probe = vpbe_display_probe,