diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2011-06-13 17:55:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:53:31 -0400 |
commit | 77068d36d8b9e9902a89b4bb01011d41926f5420 (patch) | |
tree | 4fde4974ce56e52acac5c7c8d873d300e946adcc /drivers | |
parent | 523f46d6aba9dcb0a2d0fc474ca884e93a7cf198 (diff) |
[media] v4l2-ctrls/event: remove struct v4l2_ctrl_fh, instead use v4l2_subscribed_event
The v4l2_ctrl_fh struct connected v4l2_ctrl with v4l2_fh so the control
would know which filehandles subscribed to it. However, it is much easier
to use struct v4l2_subscribed_event directly for that and get rid of that
intermediate struct.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/v4l2-ctrls.c | 50 | ||||
-rw-r--r-- | drivers/media/video/v4l2-event.c | 34 |
2 files changed, 31 insertions, 53 deletions
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index a5325611cb0e..b63fe2a17fce 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
@@ -581,15 +581,15 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change | |||
581 | static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) | 581 | static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) |
582 | { | 582 | { |
583 | struct v4l2_event ev; | 583 | struct v4l2_event ev; |
584 | struct v4l2_ctrl_fh *pos; | 584 | struct v4l2_subscribed_event *sev; |
585 | 585 | ||
586 | if (list_empty(&ctrl->fhs)) | 586 | if (list_empty(&ctrl->ev_subs)) |
587 | return; | 587 | return; |
588 | fill_event(&ev, ctrl, changes); | 588 | fill_event(&ev, ctrl, changes); |
589 | 589 | ||
590 | list_for_each_entry(pos, &ctrl->fhs, node) | 590 | list_for_each_entry(sev, &ctrl->ev_subs, node) |
591 | if (pos->fh != fh) | 591 | if (sev->fh && sev->fh != fh) |
592 | v4l2_event_queue_fh(pos->fh, &ev); | 592 | v4l2_event_queue_fh(sev->fh, &ev); |
593 | } | 593 | } |
594 | 594 | ||
595 | /* Helper function: copy the current control value back to the caller */ | 595 | /* Helper function: copy the current control value back to the caller */ |
@@ -867,7 +867,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) | |||
867 | { | 867 | { |
868 | struct v4l2_ctrl_ref *ref, *next_ref; | 868 | struct v4l2_ctrl_ref *ref, *next_ref; |
869 | struct v4l2_ctrl *ctrl, *next_ctrl; | 869 | struct v4l2_ctrl *ctrl, *next_ctrl; |
870 | struct v4l2_ctrl_fh *ctrl_fh, *next_ctrl_fh; | 870 | struct v4l2_subscribed_event *sev, *next_sev; |
871 | 871 | ||
872 | if (hdl == NULL || hdl->buckets == NULL) | 872 | if (hdl == NULL || hdl->buckets == NULL) |
873 | return; | 873 | return; |
@@ -881,10 +881,8 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) | |||
881 | /* Free all controls owned by the handler */ | 881 | /* Free all controls owned by the handler */ |
882 | list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { | 882 | list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { |
883 | list_del(&ctrl->node); | 883 | list_del(&ctrl->node); |
884 | list_for_each_entry_safe(ctrl_fh, next_ctrl_fh, &ctrl->fhs, node) { | 884 | list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) |
885 | list_del(&ctrl_fh->node); | 885 | list_del(&sev->node); |
886 | kfree(ctrl_fh); | ||
887 | } | ||
888 | kfree(ctrl); | 886 | kfree(ctrl); |
889 | } | 887 | } |
890 | kfree(hdl->buckets); | 888 | kfree(hdl->buckets); |
@@ -1084,7 +1082,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, | |||
1084 | } | 1082 | } |
1085 | 1083 | ||
1086 | INIT_LIST_HEAD(&ctrl->node); | 1084 | INIT_LIST_HEAD(&ctrl->node); |
1087 | INIT_LIST_HEAD(&ctrl->fhs); | 1085 | INIT_LIST_HEAD(&ctrl->ev_subs); |
1088 | ctrl->handler = hdl; | 1086 | ctrl->handler = hdl; |
1089 | ctrl->ops = ops; | 1087 | ctrl->ops = ops; |
1090 | ctrl->id = id; | 1088 | ctrl->id = id; |
@@ -2028,41 +2026,31 @@ int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) | |||
2028 | } | 2026 | } |
2029 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); | 2027 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); |
2030 | 2028 | ||
2031 | void v4l2_ctrl_add_fh(struct v4l2_ctrl_handler *hdl, | 2029 | void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl, |
2032 | struct v4l2_ctrl_fh *ctrl_fh, | 2030 | struct v4l2_subscribed_event *sev) |
2033 | struct v4l2_event_subscription *sub) | ||
2034 | { | 2031 | { |
2035 | struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, sub->id); | ||
2036 | |||
2037 | v4l2_ctrl_lock(ctrl); | 2032 | v4l2_ctrl_lock(ctrl); |
2038 | list_add_tail(&ctrl_fh->node, &ctrl->fhs); | 2033 | list_add_tail(&sev->node, &ctrl->ev_subs); |
2039 | if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && | 2034 | if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && |
2040 | (sub->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) { | 2035 | (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) { |
2041 | struct v4l2_event ev; | 2036 | struct v4l2_event ev; |
2042 | 2037 | ||
2043 | fill_event(&ev, ctrl, V4L2_EVENT_CTRL_CH_VALUE | | 2038 | fill_event(&ev, ctrl, V4L2_EVENT_CTRL_CH_VALUE | |
2044 | V4L2_EVENT_CTRL_CH_FLAGS); | 2039 | V4L2_EVENT_CTRL_CH_FLAGS); |
2045 | v4l2_event_queue_fh(ctrl_fh->fh, &ev); | 2040 | v4l2_event_queue_fh(sev->fh, &ev); |
2046 | } | 2041 | } |
2047 | v4l2_ctrl_unlock(ctrl); | 2042 | v4l2_ctrl_unlock(ctrl); |
2048 | } | 2043 | } |
2049 | EXPORT_SYMBOL(v4l2_ctrl_add_fh); | 2044 | EXPORT_SYMBOL(v4l2_ctrl_add_event); |
2050 | 2045 | ||
2051 | void v4l2_ctrl_del_fh(struct v4l2_ctrl *ctrl, struct v4l2_fh *fh) | 2046 | void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, |
2047 | struct v4l2_subscribed_event *sev) | ||
2052 | { | 2048 | { |
2053 | struct v4l2_ctrl_fh *pos; | ||
2054 | |||
2055 | v4l2_ctrl_lock(ctrl); | 2049 | v4l2_ctrl_lock(ctrl); |
2056 | list_for_each_entry(pos, &ctrl->fhs, node) { | 2050 | list_del(&sev->node); |
2057 | if (pos->fh == fh) { | ||
2058 | list_del(&pos->node); | ||
2059 | kfree(pos); | ||
2060 | break; | ||
2061 | } | ||
2062 | } | ||
2063 | v4l2_ctrl_unlock(ctrl); | 2051 | v4l2_ctrl_unlock(ctrl); |
2064 | } | 2052 | } |
2065 | EXPORT_SYMBOL(v4l2_ctrl_del_fh); | 2053 | EXPORT_SYMBOL(v4l2_ctrl_del_event); |
2066 | 2054 | ||
2067 | int v4l2_ctrl_subscribe_fh(struct v4l2_fh *fh, | 2055 | int v4l2_ctrl_subscribe_fh(struct v4l2_fh *fh, |
2068 | struct v4l2_event_subscription *sub, unsigned n) | 2056 | struct v4l2_event_subscription *sub, unsigned n) |
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 70fa82daaca7..dc68f6085697 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c | |||
@@ -213,7 +213,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
213 | { | 213 | { |
214 | struct v4l2_subscribed_event *sev, *found_ev; | 214 | struct v4l2_subscribed_event *sev, *found_ev; |
215 | struct v4l2_ctrl *ctrl = NULL; | 215 | struct v4l2_ctrl *ctrl = NULL; |
216 | struct v4l2_ctrl_fh *ctrl_fh = NULL; | ||
217 | unsigned long flags; | 216 | unsigned long flags; |
218 | 217 | ||
219 | if (sub->type == V4L2_EVENT_CTRL) { | 218 | if (sub->type == V4L2_EVENT_CTRL) { |
@@ -222,17 +221,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
222 | return -EINVAL; | 221 | return -EINVAL; |
223 | } | 222 | } |
224 | 223 | ||
225 | sev = kmalloc(sizeof(*sev), GFP_KERNEL); | 224 | sev = kzalloc(sizeof(*sev), GFP_KERNEL); |
226 | if (!sev) | 225 | if (!sev) |
227 | return -ENOMEM; | 226 | return -ENOMEM; |
228 | if (ctrl) { | ||
229 | ctrl_fh = kzalloc(sizeof(*ctrl_fh), GFP_KERNEL); | ||
230 | if (!ctrl_fh) { | ||
231 | kfree(sev); | ||
232 | return -ENOMEM; | ||
233 | } | ||
234 | ctrl_fh->fh = fh; | ||
235 | } | ||
236 | 227 | ||
237 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 228 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
238 | 229 | ||
@@ -241,22 +232,19 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
241 | INIT_LIST_HEAD(&sev->list); | 232 | INIT_LIST_HEAD(&sev->list); |
242 | sev->type = sub->type; | 233 | sev->type = sub->type; |
243 | sev->id = sub->id; | 234 | sev->id = sub->id; |
235 | sev->fh = fh; | ||
236 | sev->flags = sub->flags; | ||
244 | 237 | ||
245 | list_add(&sev->list, &fh->subscribed); | 238 | list_add(&sev->list, &fh->subscribed); |
246 | sev = NULL; | ||
247 | } | 239 | } |
248 | 240 | ||
249 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 241 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
250 | 242 | ||
251 | /* v4l2_ctrl_add_fh uses a mutex, so do this outside the spin lock */ | 243 | /* v4l2_ctrl_add_fh uses a mutex, so do this outside the spin lock */ |
252 | if (ctrl) { | 244 | if (found_ev) |
253 | if (found_ev) | 245 | kfree(sev); |
254 | kfree(ctrl_fh); | 246 | else if (ctrl) |
255 | else | 247 | v4l2_ctrl_add_event(ctrl, sev); |
256 | v4l2_ctrl_add_fh(fh->ctrl_handler, ctrl_fh, sub); | ||
257 | } | ||
258 | |||
259 | kfree(sev); | ||
260 | 248 | ||
261 | return 0; | 249 | return 0; |
262 | } | 250 | } |
@@ -298,15 +286,17 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
298 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 286 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
299 | 287 | ||
300 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); | 288 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); |
301 | if (sev != NULL) | 289 | if (sev != NULL) { |
302 | list_del(&sev->list); | 290 | list_del(&sev->list); |
291 | sev->fh = NULL; | ||
292 | } | ||
303 | 293 | ||
304 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 294 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
305 | if (sev->type == V4L2_EVENT_CTRL) { | 295 | if (sev && sev->type == V4L2_EVENT_CTRL) { |
306 | struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, sev->id); | 296 | struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, sev->id); |
307 | 297 | ||
308 | if (ctrl) | 298 | if (ctrl) |
309 | v4l2_ctrl_del_fh(ctrl, fh); | 299 | v4l2_ctrl_del_event(ctrl, sev); |
310 | } | 300 | } |
311 | 301 | ||
312 | kfree(sev); | 302 | kfree(sev); |