aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2011-06-13 17:55:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:53:31 -0400
commit77068d36d8b9e9902a89b4bb01011d41926f5420 (patch)
tree4fde4974ce56e52acac5c7c8d873d300e946adcc /drivers
parent523f46d6aba9dcb0a2d0fc474ca884e93a7cf198 (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.c50
-rw-r--r--drivers/media/video/v4l2-event.c34
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
581static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) 581static 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}
2029EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); 2027EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
2030 2028
2031void v4l2_ctrl_add_fh(struct v4l2_ctrl_handler *hdl, 2029void 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}
2049EXPORT_SYMBOL(v4l2_ctrl_add_fh); 2044EXPORT_SYMBOL(v4l2_ctrl_add_event);
2050 2045
2051void v4l2_ctrl_del_fh(struct v4l2_ctrl *ctrl, struct v4l2_fh *fh) 2046void 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}
2065EXPORT_SYMBOL(v4l2_ctrl_del_fh); 2053EXPORT_SYMBOL(v4l2_ctrl_del_event);
2066 2054
2067int v4l2_ctrl_subscribe_fh(struct v4l2_fh *fh, 2055int 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);