Commit 3e366149 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab
Browse files

[media] v4l2-ctrls: Use v4l2_subscribed_event_ops



Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
[hans.verkuil@cisco.com: Fix a locking bug]
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent c53c2549
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1468,8 +1468,9 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti
	switch (sub->type) {
	case V4L2_EVENT_VSYNC:
	case V4L2_EVENT_EOS:
	case V4L2_EVENT_CTRL:
		return v4l2_event_subscribe(fh, sub, 0, NULL);
	case V4L2_EVENT_CTRL:
		return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
	default:
		return -EINVAL;
	}
+34 −7
Original line number Diff line number Diff line
@@ -2424,9 +2424,13 @@ int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
}
EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);

void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
				struct v4l2_subscribed_event *sev)
static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev)
{
	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);

	if (ctrl == NULL)
		return -EINVAL;

	v4l2_ctrl_lock(ctrl);
	list_add_tail(&sev->node, &ctrl->ev_subs);
	if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
@@ -2440,17 +2444,40 @@ void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
		v4l2_event_queue_fh(sev->fh, &ev);
	}
	v4l2_ctrl_unlock(ctrl);
	return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_add_event);

void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl,
				struct v4l2_subscribed_event *sev)
static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
{
	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);

	v4l2_ctrl_lock(ctrl);
	list_del(&sev->node);
	v4l2_ctrl_unlock(ctrl);
}
EXPORT_SYMBOL(v4l2_ctrl_del_event);

void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
{
	u32 old_changes = old->u.ctrl.changes;

	old->u.ctrl = new->u.ctrl;
	old->u.ctrl.changes |= old_changes;
}
EXPORT_SYMBOL(v4l2_ctrl_replace);

void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
{
	new->u.ctrl.changes |= old->u.ctrl.changes;
}
EXPORT_SYMBOL(v4l2_ctrl_merge);

const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
	.add = v4l2_ctrl_add_event,
	.del = v4l2_ctrl_del_event,
	.replace = v4l2_ctrl_replace,
	.merge = v4l2_ctrl_merge,
};
EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);

int v4l2_ctrl_log_status(struct file *file, void *fh)
{
@@ -2468,7 +2495,7 @@ int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
				struct v4l2_event_subscription *sub)
{
	if (sub->type == V4L2_EVENT_CTRL)
		return v4l2_event_subscribe(fh, sub, 0, NULL);
		return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
	return -EINVAL;
}
EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
+0 −39
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>

#include <linux/sched.h>
#include <linux/slab.h>
@@ -203,30 +202,11 @@ int v4l2_event_pending(struct v4l2_fh *fh)
}
EXPORT_SYMBOL_GPL(v4l2_event_pending);

static void ctrls_replace(struct v4l2_event *old, const struct v4l2_event *new)
{
	u32 old_changes = old->u.ctrl.changes;

	old->u.ctrl = new->u.ctrl;
	old->u.ctrl.changes |= old_changes;
}

static void ctrls_merge(const struct v4l2_event *old, struct v4l2_event *new)
{
	new->u.ctrl.changes |= old->u.ctrl.changes;
}

static const struct v4l2_subscribed_event_ops ctrl_ops = {
	.replace = ctrls_replace,
	.merge = ctrls_merge,
};

int v4l2_event_subscribe(struct v4l2_fh *fh,
			 struct v4l2_event_subscription *sub, unsigned elems,
			 const struct v4l2_subscribed_event_ops *ops)
{
	struct v4l2_subscribed_event *sev, *found_ev;
	struct v4l2_ctrl *ctrl = NULL;
	unsigned long flags;
	unsigned i;

@@ -235,11 +215,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,

	if (elems < 1)
		elems = 1;
	if (sub->type == V4L2_EVENT_CTRL) {
		ctrl = v4l2_ctrl_find(fh->ctrl_handler, sub->id);
		if (ctrl == NULL)
			return -EINVAL;
	}

	sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL);
	if (!sev)
@@ -251,9 +226,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
	sev->flags = sub->flags;
	sev->fh = fh;
	sev->ops = ops;
	if (ctrl) {
		sev->ops = &ctrl_ops;
	}

	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
	found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
@@ -275,10 +247,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
		}
	}

	/* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
	if (ctrl)
		v4l2_ctrl_add_event(ctrl, sev);

	/* Mark as ready for use */
	sev->elems = elems;

@@ -338,13 +306,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
	if (sev && sev->ops && sev->ops->del)
		sev->ops->del(sev);

	if (sev && sev->type == V4L2_EVENT_CTRL) {
		struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, sev->id);

		if (ctrl)
			v4l2_ctrl_del_event(ctrl, sev);
	}

	kfree(sev);

	return 0;
+3 −4
Original line number Diff line number Diff line
@@ -491,10 +491,9 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);

/* Internal helper functions that deal with control events. */
void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
		struct v4l2_subscribed_event *sev);
void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl,
		struct v4l2_subscribed_event *sev);
extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new);

struct file;
/* Can be used as a vidioc_log_status function that just dumps all controls