From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: linux-media@vger.kernel.org, Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [PATCHv18 14/35] v4l2-ctrls: add core request support
Date: Tue, 14 Aug 2018 16:27:26 -0300 [thread overview]
Message-ID: <20180814162726.4591885a@coco.lan> (raw)
In-Reply-To: <20180814142047.93856-15-hverkuil@xs4all.nl>
Em Tue, 14 Aug 2018 16:20:26 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> Integrate the request support. This adds the v4l2_ctrl_request_complete
> and v4l2_ctrl_request_setup functions to complete a request and (as a
> helper function) to apply a request to the hardware.
>
> It takes care of queuing requests and correctly chaining control values
> in the request queue.
>
> Note that when a request is marked completed it will copy control values
> to the internal request state. This can be optimized in the future since
> this is sub-optimal when dealing with large compound and/or array controls.
>
> For the initial 'stateless codec' use-case the current implementation is
> sufficient.
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> ---
> drivers/media/v4l2-core/v4l2-ctrls.c | 336 ++++++++++++++++++++++++++-
> include/media/v4l2-ctrls.h | 51 ++++
> 2 files changed, 381 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index c20e74ba48ab..89e7bfee108f 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -1668,6 +1668,13 @@ static int new_to_user(struct v4l2_ext_control *c,
> return ptr_to_user(c, ctrl, ctrl->p_new);
> }
>
> +/* Helper function: copy the request value back to the caller */
> +static int req_to_user(struct v4l2_ext_control *c,
> + struct v4l2_ctrl_ref *ref)
> +{
> + return ptr_to_user(c, ref->ctrl, ref->p_req);
> +}
> +
> /* Helper function: copy the initial control value back to the caller */
> static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
> {
> @@ -1787,6 +1794,26 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
> ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
> }
>
> +/* Copy the new value to the request value */
> +static void new_to_req(struct v4l2_ctrl_ref *ref)
> +{
> + if (!ref)
> + return;
> + ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
> + ref->req = ref;
> +}
> +
> +/* Copy the request value to the new value */
> +static void req_to_new(struct v4l2_ctrl_ref *ref)
> +{
> + if (!ref)
> + return;
> + if (ref->req)
> + ptr_to_ptr(ref->ctrl, ref->req->p_req, ref->ctrl->p_new);
> + else
> + ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new);
> +}
> +
> /* Return non-zero if one or more of the controls in the cluster has a new
> value that differs from the current value. */
> static int cluster_changed(struct v4l2_ctrl *master)
> @@ -1896,6 +1923,9 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
> lockdep_set_class_and_name(hdl->lock, key, name);
> INIT_LIST_HEAD(&hdl->ctrls);
> INIT_LIST_HEAD(&hdl->ctrl_refs);
> + INIT_LIST_HEAD(&hdl->requests);
> + INIT_LIST_HEAD(&hdl->requests_queued);
> + hdl->request_is_queued = false;
> hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
> hdl->buckets = kvmalloc_array(hdl->nr_of_buckets,
> sizeof(hdl->buckets[0]),
> @@ -1916,6 +1946,14 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
> if (hdl == NULL || hdl->buckets == NULL)
> return;
>
> + if (!hdl->req_obj.req && !list_empty(&hdl->requests)) {
> + struct v4l2_ctrl_handler *req, *next_req;
> +
> + list_for_each_entry_safe(req, next_req, &hdl->requests, requests) {
> + media_request_object_unbind(&req->req_obj);
> + media_request_object_put(&req->req_obj);
> + }
> + }
> mutex_lock(hdl->lock);
> /* Free all nodes */
> list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
> @@ -2837,6 +2875,123 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
> }
> EXPORT_SYMBOL(v4l2_querymenu);
>
> +static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
> + const struct v4l2_ctrl_handler *from)
> +{
> + struct v4l2_ctrl_ref *ref;
> + int err;
> +
> + if (WARN_ON(!hdl || hdl == from))
> + return -EINVAL;
> +
> + if (hdl->error)
> + return hdl->error;
> +
> + WARN_ON(hdl->lock != &hdl->_lock);
> +
> + mutex_lock(from->lock);
> + list_for_each_entry(ref, &from->ctrl_refs, node) {
> + struct v4l2_ctrl *ctrl = ref->ctrl;
> + struct v4l2_ctrl_ref *new_ref;
> +
> + /* Skip refs inherited from other devices */
> + if (ref->from_other_dev)
> + continue;
> + /* And buttons */
> + if (ctrl->type == V4L2_CTRL_TYPE_BUTTON)
> + continue;
> + err = handler_new_ref(hdl, ctrl, &new_ref, false, true);
> + if (err)
> + break;
> + }
> + mutex_unlock(from->lock);
> + return err;
> +}
> +
> +static void v4l2_ctrl_request_queue(struct media_request_object *obj)
> +{
> + struct v4l2_ctrl_handler *hdl =
> + container_of(obj, struct v4l2_ctrl_handler, req_obj);
> + struct v4l2_ctrl_handler *main_hdl = obj->priv;
> + struct v4l2_ctrl_handler *prev_hdl = NULL;
> + struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL;
> +
> + if (list_empty(&main_hdl->requests_queued))
> + goto queue;
> +
> + prev_hdl = list_last_entry(&main_hdl->requests_queued,
> + struct v4l2_ctrl_handler, requests_queued);
> + /*
> + * Note: prev_hdl and hdl must contain the same list of control
> + * references, so if any differences are detected then that is a
> + * driver bug and the WARN_ON is triggered.
> + */
> + mutex_lock(prev_hdl->lock);
> + ref_ctrl_prev = list_first_entry(&prev_hdl->ctrl_refs,
> + struct v4l2_ctrl_ref, node);
> + list_for_each_entry(ref_ctrl, &hdl->ctrl_refs, node) {
> + if (ref_ctrl->req)
> + continue;
> + while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) {
> + /* Should never happen, but just in case... */
> + if (list_is_last(&ref_ctrl_prev->node,
> + &prev_hdl->ctrl_refs))
> + break;
> + ref_ctrl_prev = list_next_entry(ref_ctrl_prev, node);
> + }
> + if (WARN_ON(ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id))
> + break;
> + ref_ctrl->req = ref_ctrl_prev->req;
> + }
> + mutex_unlock(prev_hdl->lock);
> +queue:
> + list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
> + hdl->request_is_queued = true;
> +}
> +
> +static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
> +{
> + struct v4l2_ctrl_handler *hdl =
> + container_of(obj, struct v4l2_ctrl_handler, req_obj);
> +
> + list_del_init(&hdl->requests);
> + if (hdl->request_is_queued) {
> + list_del_init(&hdl->requests_queued);
> + hdl->request_is_queued = false;
> + }
> +}
> +
> +static void v4l2_ctrl_request_release(struct media_request_object *obj)
> +{
> + struct v4l2_ctrl_handler *hdl =
> + container_of(obj, struct v4l2_ctrl_handler, req_obj);
> +
> + v4l2_ctrl_handler_free(hdl);
> + kfree(hdl);
> +}
> +
> +static const struct media_request_object_ops req_ops = {
> + .queue = v4l2_ctrl_request_queue,
> + .unbind = v4l2_ctrl_request_unbind,
> + .release = v4l2_ctrl_request_release,
> +};
> +
> +static int v4l2_ctrl_request_bind(struct media_request *req,
> + struct v4l2_ctrl_handler *hdl,
> + struct v4l2_ctrl_handler *from)
> +{
> + int ret;
> +
> + ret = v4l2_ctrl_request_clone(hdl, from);
> +
> + if (!ret) {
> + ret = media_request_object_bind(req, &req_ops,
> + from, false, &hdl->req_obj);
> + if (!ret)
> + list_add_tail(&hdl->requests, &from->requests);
> + }
> + return ret;
> +}
>
> /* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
>
> @@ -2898,6 +3053,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
>
> if (cs->which &&
> cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
> + cs->which != V4L2_CTRL_WHICH_REQUEST_VAL &&
> V4L2_CTRL_ID2WHICH(id) != cs->which)
> return -EINVAL;
>
> @@ -2977,13 +3133,12 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
> whether there are any controls at all. */
> static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
> {
> - if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL)
> + if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL ||
> + which == V4L2_CTRL_WHICH_REQUEST_VAL)
> return 0;
> return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
> }
>
> -
> -
> /* Get extended controls. Allocates the helpers array if needed. */
> int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
> {
> @@ -3049,8 +3204,12 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
> u32 idx = i;
>
> do {
> - ret = ctrl_to_user(cs->controls + idx,
> - helpers[idx].ref->ctrl);
> + if (helpers[idx].ref->req)
> + ret = req_to_user(cs->controls + idx,
> + helpers[idx].ref->req);
> + else
> + ret = ctrl_to_user(cs->controls + idx,
> + helpers[idx].ref->ctrl);
> idx = helpers[idx].next;
> } while (!ret && idx);
> }
> @@ -3336,7 +3495,16 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
> } while (!ret && idx);
>
> if (!ret)
> - ret = try_or_set_cluster(fh, master, set, 0);
> + ret = try_or_set_cluster(fh, master,
> + !hdl->req_obj.req && set, 0);
> + if (!ret && hdl->req_obj.req && set) {
> + for (j = 0; j < master->ncontrols; j++) {
> + struct v4l2_ctrl_ref *ref =
> + find_ref(hdl, master->cluster[j]->id);
> +
> + new_to_req(ref);
> + }
> + }
>
> /* Copy the new values back to userspace. */
> if (!ret) {
> @@ -3463,6 +3631,162 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
> }
> EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
>
> +void v4l2_ctrl_request_complete(struct media_request *req,
> + struct v4l2_ctrl_handler *main_hdl)
> +{
> + struct media_request_object *obj;
> + struct v4l2_ctrl_handler *hdl;
> + struct v4l2_ctrl_ref *ref;
> +
> + if (!req || !main_hdl)
> + return;
> +
> + /*
> + * Note that it is valid if nothing was found. It means
> + * that this request doesn't have any controls and so just
> + * wants to leave the controls unchanged.
> + */
> + obj = media_request_object_find(req, &req_ops, main_hdl);
> + if (!obj)
> + return;
> + hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
> +
> + list_for_each_entry(ref, &hdl->ctrl_refs, node) {
> + struct v4l2_ctrl *ctrl = ref->ctrl;
> + struct v4l2_ctrl *master = ctrl->cluster[0];
> + unsigned int i;
> +
> + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
> + ref->req = ref;
> +
> + v4l2_ctrl_lock(master);
> + /* g_volatile_ctrl will update the current control values */
> + for (i = 0; i < master->ncontrols; i++)
> + cur_to_new(master->cluster[i]);
> + call_op(master, g_volatile_ctrl);
> + new_to_req(ref);
> + v4l2_ctrl_unlock(master);
> + continue;
> + }
> + if (ref->req == ref)
> + continue;
> +
> + v4l2_ctrl_lock(ctrl);
> + if (ref->req)
> + ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req);
> + else
> + ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req);
> + v4l2_ctrl_unlock(ctrl);
> + }
> +
> + WARN_ON(!hdl->request_is_queued);
> + list_del_init(&hdl->requests_queued);
> + hdl->request_is_queued = false;
> + media_request_object_complete(obj);
> + media_request_object_put(obj);
> +}
> +EXPORT_SYMBOL(v4l2_ctrl_request_complete);
> +
> +void v4l2_ctrl_request_setup(struct media_request *req,
> + struct v4l2_ctrl_handler *main_hdl)
> +{
> + struct media_request_object *obj;
> + struct v4l2_ctrl_handler *hdl;
> + struct v4l2_ctrl_ref *ref;
> +
> + if (!req || !main_hdl)
> + return;
> +
> + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
> + return;
> +
> + /*
> + * Note that it is valid if nothing was found. It means
> + * that this request doesn't have any controls and so just
> + * wants to leave the controls unchanged.
> + */
> + obj = media_request_object_find(req, &req_ops, main_hdl);
> + if (!obj)
> + return;
> + if (obj->completed) {
> + media_request_object_put(obj);
> + return;
> + }
> + hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
> +
> + list_for_each_entry(ref, &hdl->ctrl_refs, node)
> + ref->req_done = false;
> +
> + list_for_each_entry(ref, &hdl->ctrl_refs, node) {
> + struct v4l2_ctrl *ctrl = ref->ctrl;
> + struct v4l2_ctrl *master = ctrl->cluster[0];
> + bool have_new_data = false;
> + int i;
> +
> + /*
> + * Skip if this control was already handled by a cluster.
> + * Skip button controls and read-only controls.
> + */
> + if (ref->req_done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
> + (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
> + continue;
> +
> + v4l2_ctrl_lock(master);
> + for (i = 0; i < master->ncontrols; i++) {
> + if (master->cluster[i]) {
> + struct v4l2_ctrl_ref *r =
> + find_ref(hdl, master->cluster[i]->id);
> +
> + if (r->req && r == r->req) {
> + have_new_data = true;
> + break;
> + }
> + }
> + }
> + if (!have_new_data) {
> + v4l2_ctrl_unlock(master);
> + continue;
> + }
> +
> + for (i = 0; i < master->ncontrols; i++) {
> + if (master->cluster[i]) {
> + struct v4l2_ctrl_ref *r =
> + find_ref(hdl, master->cluster[i]->id);
> +
> + req_to_new(r);
> + master->cluster[i]->is_new = 1;
> + r->req_done = true;
> + }
> + }
> + /*
> + * For volatile autoclusters that are currently in auto mode
> + * we need to discover if it will be set to manual mode.
> + * If so, then we have to copy the current volatile values
> + * first since those will become the new manual values (which
> + * may be overwritten by explicit new values from this set
> + * of controls).
> + */
> + if (master->is_auto && master->has_volatiles &&
> + !is_cur_manual(master)) {
> + s32 new_auto_val = *master->p_new.p_s32;
> +
> + /*
> + * If the new value == the manual value, then copy
> + * the current volatile values.
> + */
> + if (new_auto_val == master->manual_mode_value)
> + update_from_auto_cluster(master);
> + }
> +
> + try_or_set_cluster(NULL, master, true, 0);
> +
> + v4l2_ctrl_unlock(master);
> + }
> +
> + media_request_object_put(obj);
> +}
> +EXPORT_SYMBOL(v4l2_ctrl_request_setup);
> +
> void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
> {
> if (ctrl == NULL)
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index 3f4e062d4e3d..ed784e98c293 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -250,6 +250,12 @@ struct v4l2_ctrl {
> * ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``.
> * @from_other_dev: If true, then @ctrl was defined in another
> * device than the &struct v4l2_ctrl_handler.
> + * @req_done: Internal flag: if the control handler containing this control
> + * reference is bound to a media request, then this is set when
> + * the control has been applied. This prevents applying controls
> + * from a cluster with multiple controls twice (when the first
> + * control of a cluster is applied, they all are).
> + * @req: If set, this refers to another request that sets this control.
> * @p_req: If the control handler containing this control reference
> * is bound to a media request, then this points to the
> * value of the control that should be applied when the request
> @@ -266,6 +272,8 @@ struct v4l2_ctrl_ref {
> struct v4l2_ctrl *ctrl;
> struct v4l2_ctrl_helper *helper;
> bool from_other_dev;
> + bool req_done;
> + struct v4l2_ctrl_ref *req;
> union v4l2_ctrl_ptr p_req;
> };
>
> @@ -290,6 +298,15 @@ struct v4l2_ctrl_ref {
> * @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
> * @nr_of_buckets: Total number of buckets in the array.
> * @error: The error code of the first failed control addition.
> + * @request_is_queued: True if the request was queued.
> + * @requests: List to keep track of open control handler request objects.
> + * For the parent control handler (@req_obj.req == NULL) this
> + * is the list header. When the parent control handler is
> + * removed, it has to unbind and put all these requests since
> + * they refer to the parent.
> + * @requests_queued: List of the queued requests. This determines the order
> + * in which these controls are applied. Once the request is
> + * completed it is removed from this list.
> * @req_obj: The &struct media_request_object, used to link into a
> * &struct media_request. This request object has a refcount.
> */
> @@ -304,6 +321,9 @@ struct v4l2_ctrl_handler {
> void *notify_priv;
> u16 nr_of_buckets;
> int error;
> + bool request_is_queued;
> + struct list_head requests;
> + struct list_head requests_queued;
> struct media_request_object req_obj;
> };
>
> @@ -1062,6 +1082,37 @@ int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
> */
> __poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
>
> +/**
> + * v4l2_ctrl_request_setup - helper function to apply control values in a request
> + *
> + * @req: The request
> + * @parent: The parent control handler ('priv' in media_request_object_find())
> + *
> + * This is a helper function to call the control handler's s_ctrl callback with
> + * the control values contained in the request. Do note that this approach of
> + * applying control values in a request is only applicable to memory-to-memory
> + * devices.
> + */
> +void v4l2_ctrl_request_setup(struct media_request *req,
> + struct v4l2_ctrl_handler *parent);
> +
> +/**
> + * v4l2_ctrl_request_complete - Complete a control handler request object
> + *
> + * @req: The request
> + * @parent: The parent control handler ('priv' in media_request_object_find())
> + *
> + * This function is to be called on each control handler that may have had a
> + * request object associated with it, i.e. control handlers of a driver that
> + * supports requests.
> + *
> + * The function first obtains the values of any volatile controls in the control
> + * handler and attach them to the request. Then, the function completes the
> + * request object.
> + */
> +void v4l2_ctrl_request_complete(struct media_request *req,
> + struct v4l2_ctrl_handler *hdl);
> +
> /* Helpers for ioctl_ops */
>
> /**
Thanks,
Mauro
next prev parent reply other threads:[~2018-08-14 22:16 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-14 14:20 [PATCHv18 00/35] Request API Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 01/35] Documentation: v4l: document request API Hans Verkuil
2018-08-14 19:16 ` Mauro Carvalho Chehab
2018-08-15 16:14 ` Laurent Pinchart
2018-08-16 9:58 ` Hans Verkuil
2018-08-16 10:16 ` Hans Verkuil
2018-08-16 10:28 ` Mauro Carvalho Chehab
2018-11-12 19:06 ` Thomas Gleixner
2018-11-18 13:52 ` Mauro Carvalho Chehab
2018-11-23 9:51 ` Mauro Carvalho Chehab
2018-11-23 10:38 ` Thomas Gleixner
2018-11-23 12:29 ` Mauro Carvalho Chehab
2018-11-23 12:44 ` Thomas Gleixner
2018-11-27 18:54 ` Mauro Carvalho Chehab
2018-11-26 3:27 ` Tomasz Figa
2018-08-14 14:20 ` [PATCHv18 02/35] uapi/linux/media.h: add " Hans Verkuil
2018-08-14 19:17 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 03/35] media-request: implement media requests Hans Verkuil
2018-08-14 19:20 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 04/35] media: doc: Add media-request.h header to documentation build Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 05/35] media-request: add media_request_get_by_fd Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 06/35] media-request: add media_request_object_find Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 07/35] v4l2-device.h: add v4l2_device_supports_requests() helper Hans Verkuil
2018-08-24 10:21 ` Sakari Ailus
2018-08-14 14:20 ` [PATCHv18 08/35] v4l2-dev: lock req_queue_mutex Hans Verkuil
2018-08-14 19:22 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 09/35] videodev2.h: add request_fd field to v4l2_ext_controls Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 10/35] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 11/35] v4l2-ctrls: prepare internal structs for request API Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 12/35] v4l2-ctrls: alloc memory for p_req Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 13/35] v4l2-ctrls: use ref in helper instead of ctrl Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 14/35] v4l2-ctrls: add core request support Hans Verkuil
2018-08-14 19:27 ` Mauro Carvalho Chehab [this message]
2018-08-14 14:20 ` [PATCHv18 15/35] v4l2-ctrls: support g/s_ext_ctrls for requests Hans Verkuil
2018-08-14 19:33 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 16/35] v4l2-ctrls: add v4l2_ctrl_request_hdl_find/put/ctrl_find functions Hans Verkuil
2018-08-14 19:34 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 17/35] videobuf2-v4l2: move __fill_v4l2_buffer() function Hans Verkuil
2018-08-14 19:36 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 18/35] videobuf2-v4l2: replace if by switch in __fill_vb2_buffer() Hans Verkuil
2018-08-15 11:51 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 19/35] vb2: store userspace data in vb2_v4l2_buffer Hans Verkuil
2018-08-14 19:47 ` Mauro Carvalho Chehab
2018-08-15 11:54 ` Hans Verkuil
2018-08-15 12:28 ` Mauro Carvalho Chehab
2018-08-15 12:33 ` Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 20/35] davinci_vpfe: remove bogus vb2->state check Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 21/35] vb2: drop VB2_BUF_STATE_PREPARED, use bool prepared/synced instead Hans Verkuil
2018-08-14 19:50 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 22/35] videodev2.h: Add request_fd field to v4l2_buffer Hans Verkuil
2018-08-25 12:58 ` Sakari Ailus
2018-08-14 14:20 ` [PATCHv18 23/35] vb2: add init_buffer buffer op Hans Verkuil
2018-08-25 12:58 ` Sakari Ailus
2018-08-14 14:20 ` [PATCHv18 24/35] videobuf2-core: embed media_request_object Hans Verkuil
2018-08-14 19:53 ` Mauro Carvalho Chehab
2018-08-25 13:01 ` Sakari Ailus
2018-08-14 14:20 ` [PATCHv18 25/35] videobuf2-core: integrate with media requests Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 26/35] videobuf2-v4l2: " Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 27/35] videobuf2-core: add request helper functions Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 28/35] videobuf2-v4l2: add vb2_request_queue/validate helpers Hans Verkuil
2018-08-14 19:54 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 29/35] videobuf2-core: add uses_requests/qbuf flags Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 30/35] videobuf2-v4l2: refuse qbuf if queue uses requests or vv Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 31/35] v4l2-mem2mem: add vb2_m2m_request_queue Hans Verkuil
2018-08-14 19:56 ` Mauro Carvalho Chehab
2018-08-14 14:20 ` [PATCHv18 32/35] vim2m: use workqueue Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 33/35] vim2m: support requests Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 34/35] vivid: add mc Hans Verkuil
2018-08-14 14:20 ` [PATCHv18 35/35] vivid: add request support Hans Verkuil
2018-08-14 20:01 ` [PATCHv18 00/35] Request API Mauro Carvalho Chehab
2018-08-14 20:04 ` Mauro Carvalho Chehab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180814162726.4591885a@coco.lan \
--to=mchehab+samsung@kernel.org \
--cc=hans.verkuil@cisco.com \
--cc=hverkuil@xs4all.nl \
--cc=linux-media@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.