aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c3
-rw-r--r--drivers/media/video/v4l2-ctrls.c41
-rw-r--r--drivers/media/video/v4l2-event.c39
-rw-r--r--include/media/v4l2-ctrls.h7
4 files changed, 39 insertions, 51 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index a7730fd4827f..70cd802c9ca8 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1468,8 +1468,9 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti
1468 switch (sub->type) { 1468 switch (sub->type) {
1469 case V4L2_EVENT_VSYNC: 1469 case V4L2_EVENT_VSYNC:
1470 case V4L2_EVENT_EOS: 1470 case V4L2_EVENT_EOS:
1471 case V4L2_EVENT_CTRL:
1472 return v4l2_event_subscribe(fh, sub, 0, NULL); 1471 return v4l2_event_subscribe(fh, sub, 0, NULL);
1472 case V4L2_EVENT_CTRL:
1473 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
1473 default: 1474 default:
1474 return -EINVAL; 1475 return -EINVAL;
1475 } 1476 }
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 91b197819fc2..ae544d870d7d 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -2424,9 +2424,13 @@ int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
2424} 2424}
2425EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); 2425EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
2426 2426
2427void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl, 2427static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev)
2428 struct v4l2_subscribed_event *sev)
2429{ 2428{
2429 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
2430
2431 if (ctrl == NULL)
2432 return -EINVAL;
2433
2430 v4l2_ctrl_lock(ctrl); 2434 v4l2_ctrl_lock(ctrl);
2431 list_add_tail(&sev->node, &ctrl->ev_subs); 2435 list_add_tail(&sev->node, &ctrl->ev_subs);
2432 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && 2436 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
@@ -2440,17 +2444,40 @@ void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
2440 v4l2_event_queue_fh(sev->fh, &ev); 2444 v4l2_event_queue_fh(sev->fh, &ev);
2441 } 2445 }
2442 v4l2_ctrl_unlock(ctrl); 2446 v4l2_ctrl_unlock(ctrl);
2447 return 0;
2443} 2448}
2444EXPORT_SYMBOL(v4l2_ctrl_add_event);
2445 2449
2446void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, 2450static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
2447 struct v4l2_subscribed_event *sev)
2448{ 2451{
2452 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
2453
2449 v4l2_ctrl_lock(ctrl); 2454 v4l2_ctrl_lock(ctrl);
2450 list_del(&sev->node); 2455 list_del(&sev->node);
2451 v4l2_ctrl_unlock(ctrl); 2456 v4l2_ctrl_unlock(ctrl);
2452} 2457}
2453EXPORT_SYMBOL(v4l2_ctrl_del_event); 2458
2459void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
2460{
2461 u32 old_changes = old->u.ctrl.changes;
2462
2463 old->u.ctrl = new->u.ctrl;
2464 old->u.ctrl.changes |= old_changes;
2465}
2466EXPORT_SYMBOL(v4l2_ctrl_replace);
2467
2468void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
2469{
2470 new->u.ctrl.changes |= old->u.ctrl.changes;
2471}
2472EXPORT_SYMBOL(v4l2_ctrl_merge);
2473
2474const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
2475 .add = v4l2_ctrl_add_event,
2476 .del = v4l2_ctrl_del_event,
2477 .replace = v4l2_ctrl_replace,
2478 .merge = v4l2_ctrl_merge,
2479};
2480EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
2454 2481
2455int v4l2_ctrl_log_status(struct file *file, void *fh) 2482int v4l2_ctrl_log_status(struct file *file, void *fh)
2456{ 2483{
@@ -2468,7 +2495,7 @@ int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
2468 struct v4l2_event_subscription *sub) 2495 struct v4l2_event_subscription *sub)
2469{ 2496{
2470 if (sub->type == V4L2_EVENT_CTRL) 2497 if (sub->type == V4L2_EVENT_CTRL)
2471 return v4l2_event_subscribe(fh, sub, 0, NULL); 2498 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
2472 return -EINVAL; 2499 return -EINVAL;
2473} 2500}
2474EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); 2501EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
index 0ba2dfa86d07..60b4e2e9c874 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -25,7 +25,6 @@
25#include <media/v4l2-dev.h> 25#include <media/v4l2-dev.h>
26#include <media/v4l2-fh.h> 26#include <media/v4l2-fh.h>
27#include <media/v4l2-event.h> 27#include <media/v4l2-event.h>
28#include <media/v4l2-ctrls.h>
29 28
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
@@ -203,30 +202,11 @@ int v4l2_event_pending(struct v4l2_fh *fh)
203} 202}
204EXPORT_SYMBOL_GPL(v4l2_event_pending); 203EXPORT_SYMBOL_GPL(v4l2_event_pending);
205 204
206static void ctrls_replace(struct v4l2_event *old, const struct v4l2_event *new)
207{
208 u32 old_changes = old->u.ctrl.changes;
209
210 old->u.ctrl = new->u.ctrl;
211 old->u.ctrl.changes |= old_changes;
212}
213
214static void ctrls_merge(const struct v4l2_event *old, struct v4l2_event *new)
215{
216 new->u.ctrl.changes |= old->u.ctrl.changes;
217}
218
219static const struct v4l2_subscribed_event_ops ctrl_ops = {
220 .replace = ctrls_replace,
221 .merge = ctrls_merge,
222};
223
224int v4l2_event_subscribe(struct v4l2_fh *fh, 205int v4l2_event_subscribe(struct v4l2_fh *fh,
225 struct v4l2_event_subscription *sub, unsigned elems, 206 struct v4l2_event_subscription *sub, unsigned elems,
226 const struct v4l2_subscribed_event_ops *ops) 207 const struct v4l2_subscribed_event_ops *ops)
227{ 208{
228 struct v4l2_subscribed_event *sev, *found_ev; 209 struct v4l2_subscribed_event *sev, *found_ev;
229 struct v4l2_ctrl *ctrl = NULL;
230 unsigned long flags; 210 unsigned long flags;
231 unsigned i; 211 unsigned i;
232 212
@@ -235,11 +215,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
235 215
236 if (elems < 1) 216 if (elems < 1)
237 elems = 1; 217 elems = 1;
238 if (sub->type == V4L2_EVENT_CTRL) {
239 ctrl = v4l2_ctrl_find(fh->ctrl_handler, sub->id);
240 if (ctrl == NULL)
241 return -EINVAL;
242 }
243 218
244 sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL); 219 sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL);
245 if (!sev) 220 if (!sev)
@@ -251,9 +226,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
251 sev->flags = sub->flags; 226 sev->flags = sub->flags;
252 sev->fh = fh; 227 sev->fh = fh;
253 sev->ops = ops; 228 sev->ops = ops;
254 if (ctrl) {
255 sev->ops = &ctrl_ops;
256 }
257 229
258 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 230 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
259 found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); 231 found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
@@ -275,10 +247,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
275 } 247 }
276 } 248 }
277 249
278 /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
279 if (ctrl)
280 v4l2_ctrl_add_event(ctrl, sev);
281
282 /* Mark as ready for use */ 250 /* Mark as ready for use */
283 sev->elems = elems; 251 sev->elems = elems;
284 252
@@ -338,13 +306,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
338 if (sev && sev->ops && sev->ops->del) 306 if (sev && sev->ops && sev->ops->del)
339 sev->ops->del(sev); 307 sev->ops->del(sev);
340 308
341 if (sev && sev->type == V4L2_EVENT_CTRL) {
342 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, sev->id);
343
344 if (ctrl)
345 v4l2_ctrl_del_event(ctrl, sev);
346 }
347
348 kfree(sev); 309 kfree(sev);
349 310
350 return 0; 311 return 0;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 8920f8210eab..c6f6b4c2c5f2 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -491,10 +491,9 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
491int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val); 491int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
492 492
493/* Internal helper functions that deal with control events. */ 493/* Internal helper functions that deal with control events. */
494void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl, 494extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
495 struct v4l2_subscribed_event *sev); 495void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
496void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, 496void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new);
497 struct v4l2_subscribed_event *sev);
498 497
499struct file; 498struct file;
500/* Can be used as a vidioc_log_status function that just dumps all controls 499/* Can be used as a vidioc_log_status function that just dumps all controls