Discussion:
[PATCH 00/15] media: davinci: vpbe enhancements
Lad, Prabhakar
2014-10-12 20:40:30 UTC
Permalink
This patch series adds following support:-
1: moves the vb2 queue init to probe.
2: uses vb2_fop_* helpers.
3: adds support for VB2_DMABUF.
4: adds support for VIDIOC_CREATE_BUFS and VIDIOC_EXPBUF.
5: Uses fh provided by v4l core.
6: And some cleanups.

Lad, Prabhakar (15):
media: davinci: vpbe: initialize vb2 queue and DMA context in probe
media: davinci: vpbe: drop buf_init() callback
media: davinci: vpbe: use vb2_ops_wait_prepare/finish helper functions
media: davinci: vpbe: drop buf_cleanup() callback
media: davinci: vpbe: improve vpbe_buffer_prepare() callback
media: davinci: vpbe: use vb2_fop_mmap/poll
media: davinci: vpbe: use fh handling provided by v4l
media: davinci: vpbe: use vb2_ioctl_* helpers
media: davinci: vpbe: add support for VB2_DMABUF
media: davinci: vpbe: add support for VIDIOC_CREATE_BUFS
media: davinci: vpbe: add support for VIDIOC_EXPBUF
media: davinci: vpbe: use helpers provided by core if streaming is
started
media: davinci: vpbe: drop unused member memory from vpbe_layer
media: davinci: vpbe: group v4l2_ioctl_ops
media: davinci: vpbe: return -ENODATA for *dv_timings/*_std calls

drivers/media/platform/davinci/vpbe.c | 18 +-
drivers/media/platform/davinci/vpbe_display.c | 607 ++++++--------------------
include/media/davinci/vpbe_display.h | 19 -
3 files changed, 159 insertions(+), 485 deletions(-)
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:33 UTC
Permalink
this patch makes use of vb2_ops_wait_prepare/finish helper functions.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 20 +++-----------------
1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index e2bda17..6f9599d 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -308,20 +308,6 @@ static void vpbe_buf_cleanup(struct vb2_buffer *vb)
spin_unlock_irqrestore(&layer->irqlock, flags);
}

-static void vpbe_wait_prepare(struct vb2_queue *vq)
-{
- struct vpbe_layer *layer = vb2_get_drv_priv(vq);
-
- mutex_unlock(&layer->opslock);
-}
-
-static void vpbe_wait_finish(struct vb2_queue *vq)
-{
- struct vpbe_layer *layer = vb2_get_drv_priv(vq);
-
- mutex_lock(&layer->opslock);
-}
-
static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct vpbe_layer *layer = vb2_get_drv_priv(vq);
@@ -394,8 +380,8 @@ static void vpbe_stop_streaming(struct vb2_queue *vq)

static struct vb2_ops video_qops = {
.queue_setup = vpbe_buffer_queue_setup,
- .wait_prepare = vpbe_wait_prepare,
- .wait_finish = vpbe_wait_finish,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
.buf_prepare = vpbe_buffer_prepare,
.start_streaming = vpbe_start_streaming,
.stop_streaming = vpbe_stop_streaming,
@@ -1749,7 +1735,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 1;
-
+ q->lock = &disp_dev->dev[i]->opslock;
err = vb2_queue_init(q);
if (err) {
v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:34 UTC
Permalink
this patch drops buf_cleanup() callback as this callback
is never called with buffer state active.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 24 ------------------------
1 file changed, 24 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 6f9599d..491b832 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -285,29 +285,6 @@ 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);
@@ -385,7 +362,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,
};
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:31 UTC
Permalink
this patch moves the initialization of vb2 queue and the DMA
context to probe() and clean up in remove() callback respectively.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg-***@public.gmane.org>
---
drivers/media/platform/davinci/vpbe_display.c | 128 ++++++++++++--------------
1 file changed, 60 insertions(+), 68 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 73496d9..ff9eac4 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -207,10 +207,9 @@ static irqreturn_t venc_isr(int irq, void *arg)
*/
static int vpbe_buffer_prepare(struct vb2_buffer *vb)
{
- struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_queue *q = vb->vb2_queue;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+ struct vpbe_layer *layer = vb2_get_drv_priv(q);
+ struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
unsigned long addr;

v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -247,9 +246,8 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,

{
/* Get the file handle object and layer object */
- struct vpbe_fh *fh = vb2_get_drv_priv(vq);
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+ struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;

v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");

@@ -271,12 +269,11 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static void vpbe_buffer_queue(struct vb2_buffer *vb)
{
/* Get the file handle object and layer object */
- struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
struct vpbe_disp_buffer *buf = container_of(vb,
struct vpbe_disp_buffer, vb);
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp = fh->disp_dev;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
+ struct vpbe_display *disp = layer->disp_dev;
+ struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
unsigned long flags;

v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -296,9 +293,8 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb)
static void vpbe_buf_cleanup(struct vb2_buffer *vb)
{
/* Get the file handle object and layer object */
- struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+ 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;
@@ -314,16 +310,14 @@ static void vpbe_buf_cleanup(struct vb2_buffer *vb)

static void vpbe_wait_prepare(struct vb2_queue *vq)
{
- struct vpbe_fh *fh = vb2_get_drv_priv(vq);
- struct vpbe_layer *layer = fh->layer;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vq);

mutex_unlock(&layer->opslock);
}

static void vpbe_wait_finish(struct vb2_queue *vq)
{
- struct vpbe_fh *fh = vb2_get_drv_priv(vq);
- struct vpbe_layer *layer = fh->layer;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vq);

mutex_lock(&layer->opslock);
}
@@ -339,8 +333,7 @@ static int vpbe_buffer_init(struct vb2_buffer *vb)

static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
{
- struct vpbe_fh *fh = vb2_get_drv_priv(vq);
- struct vpbe_layer *layer = fh->layer;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vq);
int ret;

/* Get the next frame from the buffer queue */
@@ -354,7 +347,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
layer->field_id = 0;

/* Set parameters in OSD and VENC */
- ret = vpbe_set_osd_display_params(fh->disp_dev, layer);
+ ret = vpbe_set_osd_display_params(layer->disp_dev, layer);
if (ret < 0) {
struct vpbe_disp_buffer *buf, *tmp;

@@ -379,9 +372,8 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)

static void vpbe_stop_streaming(struct vb2_queue *vq)
{
- struct vpbe_fh *fh = vb2_get_drv_priv(vq);
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp = fh->disp_dev;
+ struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+ struct vpbe_display *disp = layer->disp_dev;
unsigned long flags;

if (!vb2_is_streaming(vq))
@@ -1380,8 +1372,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
struct vpbe_fh *fh = file->private_data;
struct vpbe_layer *layer = fh->layer;
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- struct vb2_queue *q;
- int ret;
+
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");

if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
@@ -1394,39 +1385,14 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n");
return -EBUSY;
}
- /* Initialize videobuf queue as per the buffer type */
- layer->alloc_ctx = vb2_dma_contig_init_ctx(vpbe_dev->pdev);
- if (IS_ERR(layer->alloc_ctx)) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Failed to get the context\n");
- return PTR_ERR(layer->alloc_ctx);
- }
- q = &layer->buffer_queue;
- memset(q, 0, sizeof(*q));
- 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 vpbe_disp_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->min_buffers_needed = 1;
-
- ret = vb2_queue_init(q);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev, "vb2_queue_init() failed\n");
- vb2_dma_contig_cleanup_ctx(layer->alloc_ctx);
- return ret;
- }
/* 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;
- /* Initialize buffer queue */
- INIT_LIST_HEAD(&layer->dma_queue);
/* Allocate buffers */
- return vb2_reqbufs(q, req_buf);
+ return vb2_reqbufs(&layer->buffer_queue, req_buf);
}

/*
@@ -1551,9 +1517,6 @@ static int vpbe_display_release(struct file *file)
osd_device->ops.disable_layer(osd_device,
layer->layer_info.id);
layer->started = 0;
- /* Free buffers allocated */
- vb2_queue_release(&layer->buffer_queue);
- vb2_dma_contig_cleanup_ctx(&layer->buffer_queue);
}

/* Decrement layer usrs counter */
@@ -1724,9 +1687,10 @@ static int register_device(struct vpbe_layer *vpbe_display_layer,
*/
static int vpbe_display_probe(struct platform_device *pdev)
{
- struct vpbe_layer *vpbe_display_layer;
struct vpbe_display *disp_dev;
+ struct v4l2_device *v4l2_dev;
struct resource *res = NULL;
+ struct vb2_queue *q;
int k;
int i;
int err;
@@ -1748,13 +1712,14 @@ static int vpbe_display_probe(struct platform_device *pdev)
vpbe_device_get);
if (err < 0)
return err;
+
+ v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
/* Initialize the vpbe display controller */
if (NULL != disp_dev->vpbe_dev->ops.initialize) {
err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
disp_dev->vpbe_dev);
if (err) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Error initing vpbe\n");
+ v4l2_err(v4l2_dev, "Error initing vpbe\n");
err = -ENOMEM;
goto probe_out;
}
@@ -1769,8 +1734,7 @@ static int vpbe_display_probe(struct platform_device *pdev)

res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Unable to get VENC interrupt resource\n");
+ v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n");
err = -ENODEV;
goto probe_out;
}
@@ -1779,30 +1743,57 @@ static int vpbe_display_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
VPBE_DISPLAY_DRIVER, disp_dev);
if (err) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Unable to request interrupt\n");
+ v4l2_err(v4l2_dev, "VPBE IRQ request failed\n");
goto probe_out;
}

for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+ /* initialize vb2 queue */
+ 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->drv_priv = disp_dev->dev[i];
+ q->ops = &video_qops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->min_buffers_needed = 1;
+
+ err = vb2_queue_init(q);
+ if (err) {
+ v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
+ goto probe_out;
+ }
+
+ disp_dev->dev[i]->alloc_ctx =
+ vb2_dma_contig_init_ctx(disp_dev->vpbe_dev->pdev);
+ if (IS_ERR(disp_dev->dev[i]->alloc_ctx)) {
+ v4l2_err(v4l2_dev, "Failed to get the context\n");
+ err = PTR_ERR(disp_dev->dev[i]->alloc_ctx);
+ goto probe_out;
+ }
+
+ INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue);
+
if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
err = -ENODEV;
goto probe_out;
}
}

- printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n");
+ v4l2_dbg(1, debug, v4l2_dev,
+ "Successfully completed the probing of vpbe v4l2 device\n");
+
return 0;

probe_out:
for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
- /* Get the pointer to the layer object */
- vpbe_display_layer = disp_dev->dev[k];
/* Unregister video device */
- if (vpbe_display_layer) {
- video_unregister_device(
- &vpbe_display_layer->video_dev);
- kfree(disp_dev->dev[k]);
+ if (disp_dev->dev[k] != NULL) {
+ vb2_dma_contig_cleanup_ctx(disp_dev->dev[k]->alloc_ctx);
+ video_unregister_device(&disp_dev->dev[k]->video_dev);
+ kfree(disp_dev->dev[k]);
}
}
return err;
@@ -1828,6 +1819,7 @@ static int vpbe_display_remove(struct platform_device *pdev)
for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
/* Get the pointer to the layer object */
vpbe_display_layer = disp_dev->dev[i];
+ vb2_dma_contig_cleanup_ctx(vpbe_display_layer->alloc_ctx);
/* Unregister video device */
video_unregister_device(&vpbe_display_layer->video_dev);
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:38 UTC
Permalink
this patch adds support for using vb2_ioctl_* helpers.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 178 ++------------------------
1 file changed, 14 insertions(+), 164 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 970242c..76450aa 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -281,8 +281,11 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb)
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);
@@ -320,12 +323,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) {
@@ -1144,164 +1150,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_layer *layer = video_drvdata(file);
- struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
- struct osd_state *osd_device = layer->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 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_layer *layer = video_drvdata(file);
- struct vpbe_display *disp_dev = layer->disp_dev;
- struct vpbe_device *vpbe_dev = layer->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 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_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_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 (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_layer *layer = video_drvdata(file);
- struct vpbe_device *vpbe_dev = layer->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;
- }
-
- return vb2_qbuf(&layer->buffer_queue, p);
-}
-
-static int vpbe_display_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- 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_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_layer *layer = video_drvdata(file);
- struct vpbe_device *vpbe_dev = layer->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;
- }
- /* 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_open()
* It creates object of file handle structure and stores it in private_data
@@ -1405,12 +1253,14 @@ 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_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_cropcap = vpbe_display_cropcap,
.vidioc_g_crop = vpbe_display_g_crop,
.vidioc_s_crop = vpbe_display_s_crop,
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:37 UTC
Permalink
this patch converts the driver to use fh handling provided by the
v4l core instead of driver doing it.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 189 +++++++++-----------------
include/media/davinci/vpbe_display.h | 11 --
2 files changed, 65 insertions(+), 135 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index fc3bdb6..970242c 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -628,8 +628,8 @@ 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;
@@ -646,9 +646,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;
@@ -715,11 +714,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,
@@ -743,8 +741,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");

@@ -761,9 +759,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",
@@ -783,9 +780,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,
@@ -815,9 +811,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;
@@ -904,9 +899,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");
@@ -930,9 +925,8 @@ 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");
@@ -965,8 +959,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");

@@ -988,8 +982,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");
@@ -1016,9 +1010,8 @@ 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");
@@ -1047,8 +1040,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 */
@@ -1067,8 +1060,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");
@@ -1097,9 +1090,8 @@ 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");
@@ -1135,8 +1127,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");

@@ -1155,10 +1147,9 @@ vpbe_display_g_dv_timings(struct file *file, void *priv,
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;
+ struct vpbe_layer *layer = video_drvdata(file);
+ struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+ struct osd_state *osd_device = layer->disp_dev->osd_device;
int ret;

v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -1170,12 +1161,6 @@ static int vpbe_display_streamoff(struct file *file, void *priv,
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"
@@ -1194,10 +1179,9 @@ static int vpbe_display_streamoff(struct file *file, void *priv,
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 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 osd_state *osd_device = disp_dev->osd_device;
int ret;

@@ -1212,11 +1196,6 @@ static int vpbe_display_streamon(struct file *file, void *priv,
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");
@@ -1239,9 +1218,8 @@ static int vpbe_display_streamon(struct file *file, void *priv,
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;
+ 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,
@@ -1252,11 +1230,6 @@ static int vpbe_display_dqbuf(struct file *file, void *priv,
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);
@@ -1270,9 +1243,8 @@ static int vpbe_display_dqbuf(struct file *file, void *priv,
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;
+ 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_QBUF, layer id = %d\n",
@@ -1283,21 +1255,14 @@ static int vpbe_display_qbuf(struct file *file, void *priv,
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;
+ 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_QUERYBUF, layer id = %d\n",
@@ -1314,9 +1279,8 @@ static int vpbe_display_querybuf(struct file *file, void *priv,
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;
+ 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, "vpbe_display_reqbufs\n");

@@ -1330,8 +1294,6 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
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 */
@@ -1347,30 +1309,22 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
*/
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))
@@ -1383,15 +1337,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;
@@ -1404,26 +1355,21 @@ 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;
+ /* 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);
+ layer->started = 0;

/* Decrement layer usrs counter */
layer->usrs--;
@@ -1444,14 +1390,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;
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
index 637749a..06ea815 100644
--- a/include/media/davinci/vpbe_display.h
+++ b/include/media/davinci/vpbe_display.h
@@ -131,17 +131,6 @@ struct vpbe_display {
struct osd_state *osd_device;
};

-/* File handle structure */
-struct vpbe_fh {
- struct v4l2_fh fh;
- /* vpbe device structure */
- struct vpbe_display *disp_dev;
- /* pointer to layer object for opened device */
- struct vpbe_layer *layer;
- /* Indicates whether this file handle is doing IO */
- unsigned char io_allowed;
-};
-
struct buf_config_params {
unsigned char min_numbuffers;
unsigned char numbuffers[VPBE_DISPLAY_MAX_DEVICES];
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:39 UTC
Permalink
Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 76450aa..c33b77e 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1450,7 +1450,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;
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:42 UTC
Permalink
this patch uses vb2_is_busy() helper to check if streaming is
actually started, instead of driver managing it.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 34 ++++++++-------------------
include/media/davinci/vpbe_display.h | 4 ----
2 files changed, 10 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 378f31b..b57fa68 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -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) {
@@ -314,7 +314,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;
@@ -829,11 +828,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;
@@ -937,11 +934,9 @@ static int vpbe_display_s_std(struct file *file, void *priv,

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) {
@@ -1021,11 +1016,10 @@ static int vpbe_display_s_output(struct file *file, void *priv,
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;

@@ -1102,12 +1096,8 @@ vpbe_display_s_dv_timings(struct file *file, void *priv,

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)
@@ -1212,13 +1202,9 @@ static int vpbe_display_release(struct file *file)
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");

mutex_lock(&layer->opslock);
- /* 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;
-
/* Decrement layer usrs counter */
layer->usrs--;
/* If this file handle has initialize encoder device, reset it */
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
index 06ea815..de0843d 100644
--- a/include/media/davinci/vpbe_display.h
+++ b/include/media/davinci/vpbe_display.h
@@ -106,12 +106,8 @@ struct vpbe_layer {
unsigned char window_enable;
/* number of open instances of the layer */
unsigned int usrs;
- /* number of users performing IO */
- unsigned int io_usrs;
/* Indicates id of the field which is being displayed */
unsigned int field_id;
- /* Indicates whether streaming started */
- unsigned char started;
/* Identifies device object */
enum vpbe_display_device_id device_id;
/* facilitation of ioctl ops lock by v4l2*/
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:45 UTC
Permalink
this patch adds support for returning -ENODATA if the current
output doesn't support it.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c
index 33b9660..49d2de0 100644
--- a/drivers/media/platform/davinci/vpbe.c
+++ b/drivers/media/platform/davinci/vpbe.c
@@ -341,7 +341,7 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,

if (!(cfg->outputs[out_index].output.capabilities &
V4L2_OUT_CAP_DV_TIMINGS))
- return -EINVAL;
+ return -ENODATA;

for (i = 0; i < output->num_modes; i++) {
if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS &&
@@ -384,6 +384,13 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
struct v4l2_dv_timings *dv_timings)
{
+ struct vpbe_config *cfg = vpbe_dev->cfg;
+ int out_index = vpbe_dev->current_out_index;
+
+ if (!(cfg->outputs[out_index].output.capabilities &
+ V4L2_OUT_CAP_DV_TIMINGS))
+ return -ENODATA;
+
if (vpbe_dev->current_timings.timings_type &
VPBE_ENC_DV_TIMINGS) {
*dv_timings = vpbe_dev->current_timings.dv_timings;
@@ -409,7 +416,7 @@ static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
int i;

if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
- return -EINVAL;
+ return -ENODATA;

for (i = 0; i < output->num_modes; i++) {
if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) {
@@ -440,7 +447,7 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)

if (!(cfg->outputs[out_index].output.capabilities &
V4L2_OUT_CAP_STD))
- return -EINVAL;
+ return -ENODATA;

ret = vpbe_get_std_info(vpbe_dev, std_id);
if (ret)
@@ -473,6 +480,11 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)
static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
{
struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
+ struct vpbe_config *cfg = vpbe_dev->cfg;
+ int out_index = vpbe_dev->current_out_index;
+
+ if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD))
+ return -ENODATA;

if (cur_timings->timings_type & VPBE_ENC_STD) {
*std_id = cur_timings->std_id;
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:32 UTC
Permalink
this patch drops the buf_init() callback as init
of buf list is not required.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg-***@public.gmane.org>
---
drivers/media/platform/davinci/vpbe_display.c | 10 ----------
1 file changed, 10 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index ff9eac4..e2bda17 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -322,15 +322,6 @@ static void vpbe_wait_finish(struct vb2_queue *vq)
mutex_lock(&layer->opslock);
}

-static int vpbe_buffer_init(struct vb2_buffer *vb)
-{
- struct vpbe_disp_buffer *buf = container_of(vb,
- struct vpbe_disp_buffer, vb);
-
- INIT_LIST_HEAD(&buf->list);
- return 0;
-}
-
static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct vpbe_layer *layer = vb2_get_drv_priv(vq);
@@ -405,7 +396,6 @@ static struct vb2_ops video_qops = {
.queue_setup = vpbe_buffer_queue_setup,
.wait_prepare = vpbe_wait_prepare,
.wait_finish = vpbe_wait_finish,
- .buf_init = vpbe_buffer_init,
.buf_prepare = vpbe_buffer_prepare,
.start_streaming = vpbe_start_streaming,
.stop_streaming = vpbe_stop_streaming,
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:44 UTC
Permalink
this patch groups the v4l2_ioctl_ops.

Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index b57fa68..17c965d 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1252,11 +1252,14 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.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,
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:43 UTC
Permalink
Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
include/media/davinci/vpbe_display.h | 4 ----
1 file changed, 4 deletions(-)

diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
index de0843d..163a02b 100644
--- a/include/media/davinci/vpbe_display.h
+++ b/include/media/davinci/vpbe_display.h
@@ -91,10 +91,6 @@ struct vpbe_layer {
/* V4l2 specific parameters */
/* Identifies video device for this layer */
struct video_device video_dev;
- /* This field keeps track of type of buffer exchange mechanism user
- * has selected
- */
- enum v4l2_memory memory;
/* Used to store pixel format */
struct v4l2_pix_format pix_fmt;
enum v4l2_field buf_field;
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:41 UTC
Permalink
Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index fd8d4f0..378f31b 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1261,6 +1261,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_expbuf = vb2_ioctl_expbuf,

.vidioc_cropcap = vpbe_display_cropcap,
.vidioc_g_crop = vpbe_display_g_crop,
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:35 UTC
Permalink
this patch improve vpbe_buffer_prepare() callback, as buf_prepare()
callback is never called with invalid state and check for
vb2_plane_vaddr(vb, 0) is dropped as payload check should
be done unconditionally.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg-***@public.gmane.org>
---
drivers/media/platform/davinci/vpbe_display.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 491b832..524e1fd 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -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;
}
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:36 UTC
Permalink
this patch teaches vpbe driver to use vb2_fop_mmap/poll helpers.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg-***@public.gmane.org>
---
drivers/media/platform/davinci/vpbe_display.c | 44 ++-------------------------
1 file changed, 3 insertions(+), 41 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 524e1fd..fc3bdb6 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1341,45 +1341,6 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
}

/*
- * 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
* member of filepointer
@@ -1527,8 +1488,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)
@@ -1608,6 +1569,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);
--
1.9.1
Lad, Prabhakar
2014-10-12 20:40:40 UTC
Permalink
Signed-off-by: Lad, Prabhakar <***@gmail.com>
---
drivers/media/platform/davinci/vpbe_display.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index c33b77e..fd8d4f0 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1260,6 +1260,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,

.vidioc_cropcap = vpbe_display_cropcap,
.vidioc_g_crop = vpbe_display_g_crop,
--
1.9.1
Hans Verkuil
2014-10-22 11:26:35 UTC
Permalink
Hi Prabhakar,

This patch series looks good, except for this one.

If you add create_bufs support, then you should also update queue_setup.

If the fmt argument to queue_setup is non-NULL, then check that the
fmt.pix.sizeimage field is >= the current format's sizeimage. If not,
return -EINVAL.

This prevents userspace from creating additional buffers that are smaller than
the minimum required size.

I'm just skipping this patch and queuing all the others for 3.19. Just post an
updated version for this one and I'll pick it up later.

Regards,

Hans
Post by Lad, Prabhakar
---
drivers/media/platform/davinci/vpbe_display.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index c33b77e..fd8d4f0 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1260,6 +1260,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
.vidioc_cropcap = vpbe_display_cropcap,
.vidioc_g_crop = vpbe_display_g_crop,
Prabhakar Lad
2014-10-22 21:48:12 UTC
Permalink
Hi Hans,
Post by Hans Verkuil
Hi Prabhakar,
This patch series looks good, except for this one.
If you add create_bufs support, then you should also update queue_setup.
If the fmt argument to queue_setup is non-NULL, then check that the
fmt.pix.sizeimage field is >= the current format's sizeimage. If not,
return -EINVAL.
This prevents userspace from creating additional buffers that are smaller than
the minimum required size.
I'm just skipping this patch and queuing all the others for 3.19. Just post an
updated version for this one and I'll pick it up later.
I fixed it and posted the patch. To avoid conflicts I have rebased the patch on
for-v3.19a branch of your tree.

Thanks,
--Prabhakar Lad

Loading...