[RFCv4 20/21] media: vivid: add request support for the video capture device

From: Alexandre Courbot
Date: Mon Feb 19 2018 - 23:46:29 EST


Allow to use requests with the video capture device.

Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxxxx>
---
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