Allow to use requests with the video capture device.

Signed-off-by: Alexandre Courbot <acour...@chromium.org>
---
 drivers/media/platform/vivid/Kconfig          |  1 +
 drivers/media/platform/vivid/vivid-core.c     | 63 ++++++++++++++++++-
 drivers/media/platform/vivid/vivid-core.h     |  3 +
 .../media/platform/vivid/vivid-kthread-cap.c  | 17 +++++
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivid/Kconfig 
b/drivers/media/platform/vivid/Kconfig
index 154de92dd809..a6494dabae95 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -7,6 +7,7 @@ config VIDEO_VIVID
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
+       select MEDIA_REQUEST_API
        select VIDEOBUF2_VMALLOC
        select VIDEOBUF2_DMA_CONTIG
        select VIDEO_V4L2_TPG
diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index 82ec216f2ad8..c1cf8e7ca2c9 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -23,6 +23,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
+#include <media/v4l2-request.h>
 
 #include "vivid-core.h"
 #include "vivid-vid-common.h"
@@ -486,6 +487,33 @@ static const struct v4l2_file_operations vivid_fops = {
        .mmap           = vb2_fop_mmap,
 };
 
+static int vivid_cap_open(struct file *filp)
+{
+       struct vivid_dev *dev;
+       struct v4l2_fh *fh;
+       int ret;
+
+       ret = v4l2_fh_open(filp);
+       if (ret)
+               return ret;
+
+       dev = container_of(video_devdata(filp), struct vivid_dev, vid_cap_dev);
+       fh = filp->private_data;
+       fh->entity = &dev->vid_cap_req_entity.base;
+
+       return ret;
+}
+
+static const struct v4l2_file_operations vivid_cap_fops = {
+       .owner          = THIS_MODULE,
+       .open           = vivid_cap_open,
+       .release        = vivid_fop_release,
+       .read           = vb2_fop_read,
+       .write          = vb2_fop_write,
+       .poll           = vb2_fop_poll,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = vb2_fop_mmap,
+};
 static const struct v4l2_file_operations vivid_radio_fops = {
        .owner          = THIS_MODULE,
        .open           = v4l2_fh_open,
@@ -607,6 +635,31 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
 };
 
+struct media_request_entity_data *
+vid_cap_entity_data_alloc(struct media_request *req,
+                       struct media_request_entity *entity)
+{
+       struct vivid_dev *dev;
+
+       dev = container_of(entity, struct vivid_dev, vid_cap_req_entity.base);
+       return v4l2_request_entity_data_alloc(req, &dev->ctrl_hdl_vid_cap);
+}
+
+static int vid_cap_request_submit(struct media_request *req,
+                               struct media_request_entity_data *_data)
+{
+       struct v4l2_request_entity_data *data;
+
+       data = to_v4l2_entity_data(_data);
+       return vb2_request_submit(data);
+}
+
+static const struct media_request_entity_ops vivid_request_entity_ops = {
+       .data_alloc     = vid_cap_entity_data_alloc,
+       .data_free      = v4l2_request_entity_data_free,
+       .submit         = vid_cap_request_submit,
+};
+
 /* -----------------------------------------------------------------
        Initialization and module stuff
    ------------------------------------------------------------------*/
@@ -1057,6 +1110,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->mem_ops = vivid_mem_ops[allocator];
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 2;
+               q->allow_requests = true;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
 
@@ -1158,13 +1212,19 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                vfd = &dev->vid_cap_dev;
                snprintf(vfd->name, sizeof(vfd->name),
                         "vivid-%03d-vid-cap", inst);
-               vfd->fops = &vivid_fops;
+               vfd->fops = &vivid_cap_fops;
                vfd->ioctl_ops = &vivid_ioctl_ops;
                vfd->device_caps = dev->vid_cap_caps;
                vfd->release = video_device_release_empty;
                vfd->v4l2_dev = &dev->v4l2_dev;
                vfd->queue = &dev->vb_vid_cap_q;
                vfd->tvnorms = tvnorms_cap;
+               vfd->req_mgr = &dev->vid_cap_req_mgr.base;
+               v4l2_request_mgr_init(&dev->vid_cap_req_mgr, vfd,
+                                     &v4l2_request_ops);
+               v4l2_request_entity_init(&dev->vid_cap_req_entity,
+                                        &vivid_request_entity_ops,
+                                        vfd);
 
                /*
                 * Provide a mutex to v4l2 core. It will be used to protect
@@ -1448,6 +1508,7 @@ static int vivid_remove(struct platform_device *pdev)
                        v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
                                video_device_node_name(&dev->vid_cap_dev));
                        video_unregister_device(&dev->vid_cap_dev);
+                       v4l2_request_mgr_free(&dev->vid_cap_req_mgr);
                }
                if (dev->has_vid_out) {
                        v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
diff --git a/drivers/media/platform/vivid/vivid-core.h 
b/drivers/media/platform/vivid/vivid-core.h
index 477c80a4d44c..c8adcbb1c1d1 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -11,6 +11,7 @@
 #include <linux/fb.h>
 #include <linux/workqueue.h>
 #include <media/cec.h>
+#include <media/v4l2-request.h>
 #include <media/videobuf2-v4l2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-dev.h>
@@ -145,6 +146,8 @@ struct vivid_dev {
        struct v4l2_ctrl_handler        ctrl_hdl_fb;
        struct video_device             vid_cap_dev;
        struct v4l2_ctrl_handler        ctrl_hdl_vid_cap;
+       struct v4l2_request_mgr         vid_cap_req_mgr;
+       struct v4l2_request_entity      vid_cap_req_entity;
        struct video_device             vid_out_dev;
        struct v4l2_ctrl_handler        ctrl_hdl_vid_out;
        struct video_device             vbi_cap_dev;
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c 
b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 3fdb280c36ca..0d0866dc11b3 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -19,6 +19,7 @@
 #include <linux/random.h>
 #include <linux/v4l2-dv-timings.h>
 #include <asm/div64.h>
+#include <media/media-request.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/v4l2-ioctl.h>
@@ -703,6 +704,17 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev 
*dev, int dropped_bufs)
                goto update_mv;
 
        if (vid_cap_buf) {
+               struct media_request *req = vid_cap_buf->vb.vb2_buf.request;
+
+               /* Using request? Apply its controls */
+               if (req) {
+                       struct v4l2_request_entity_data *data;
+                       data = to_v4l2_entity_data(
+                               media_request_get_entity_data(req,
+                                               &dev->vid_cap_req_entity.base));
+                       if (!WARN_ON(IS_ERR(data)))
+                               v4l2_ctrl_request_setup(&data->ctrls);
+               }
                /* Fill buffer */
                vivid_fillbuff(dev, vid_cap_buf);
                dprintk(dev, 1, "filled buffer %d\n",
@@ -717,6 +729,11 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev 
*dev, int dropped_bufs)
                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
                dprintk(dev, 2, "vid_cap buffer %d done\n",
                                vid_cap_buf->vb.vb2_buf.index);
+               if (req)
+                       media_request_entity_complete(req,
+                                                &dev->vid_cap_req_entity.base);
+               dprintk(dev, 2, "vid_cap buffer %d request completed\n",
+                               vid_cap_buf->vb.vb2_buf.index);
        }
 
        if (vbi_cap_buf) {
-- 
2.16.1.291.g4437f3f132-goog

Reply via email to