diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 4 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 4 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/ispccdc.c | 3 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/ispstat.c | 3 | ||||
-rw-r--r-- | drivers/media/video/v4l2-ctrls.c | 18 | ||||
-rw-r--r-- | drivers/media/video/v4l2-event.c | 88 | ||||
-rw-r--r-- | drivers/media/video/v4l2-fh.c | 4 | ||||
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 7 | ||||
-rw-r--r-- | drivers/media/video/vivi.c | 2 |
9 files changed, 38 insertions, 95 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index d4275d2460cb..38f052257f46 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -966,10 +966,6 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) return -ENOMEM; } v4l2_fh_init(&item->fh, s->vdev); - if (s->type == IVTV_DEC_STREAM_TYPE_YUV || - s->type == IVTV_DEC_STREAM_TYPE_MPG) { - res = v4l2_event_alloc(&item->fh, 60); - } if (res < 0) { v4l2_fh_exit(&item->fh); kfree(item); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index ff75d07097b2..3e5c090af112 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1450,13 +1450,11 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti switch (sub->type) { case V4L2_EVENT_VSYNC: case V4L2_EVENT_EOS: - break; case V4L2_EVENT_CTRL: - return v4l2_ctrl_subscribe_fh(fh, sub, 0); + return v4l2_event_subscribe(fh, sub, 0); default: return -EINVAL; } - return v4l2_event_subscribe(fh, sub); } static int ivtv_log_status(struct file *file, void *fh) diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index 39d501bda636..67662470661d 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c @@ -1691,7 +1691,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, if (sub->type != V4L2_EVENT_OMAP3ISP_HS_VS) return -EINVAL; - return v4l2_event_subscribe(fh, sub); + return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS); } static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, @@ -2162,7 +2162,6 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, ccdc); sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; - sd->nevents = OMAP3ISP_CCDC_NEVENTS; pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c index b44cb685236a..808065948ac1 100644 --- a/drivers/media/video/omap3isp/ispstat.c +++ b/drivers/media/video/omap3isp/ispstat.c @@ -1032,7 +1032,6 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name, snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name); subdev->grp_id = 1 << 16; /* group ID for isp subdevs */ subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; - subdev->nevents = STAT_NEVENTS; v4l2_set_subdevdata(subdev, stat); stat->pad.flags = MEDIA_PAD_FL_SINK; @@ -1050,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, if (sub->type != stat->event_type) return -EINVAL; - return v4l2_event_subscribe(fh, sub); + return v4l2_event_subscribe(fh, sub, STAT_NEVENTS); } int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index b63fe2a17fce..a37e5bff4342 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -1011,7 +1011,6 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl, insertion is an O(1) operation. */ if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) { list_add_tail(&new_ref->node, &hdl->ctrl_refs); - hdl->nr_of_refs++; goto insert_in_hash; } @@ -2051,20 +2050,3 @@ void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, v4l2_ctrl_unlock(ctrl); } EXPORT_SYMBOL(v4l2_ctrl_del_event); - -int v4l2_ctrl_subscribe_fh(struct v4l2_fh *fh, - struct v4l2_event_subscription *sub, unsigned n) -{ - struct v4l2_ctrl_handler *hdl = fh->ctrl_handler; - int ret = 0; - - if (!ret) { - if (hdl->nr_of_refs * 2 > n) - n = hdl->nr_of_refs * 2; - ret = v4l2_event_alloc(fh, n); - } - if (!ret) - ret = v4l2_event_subscribe(fh, sub); - return ret; -} -EXPORT_SYMBOL(v4l2_ctrl_subscribe_fh); diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index dc68f6085697..9e325dd3ce27 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c @@ -30,44 +30,11 @@ #include <linux/sched.h> #include <linux/slab.h> -static void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); - -int v4l2_event_alloc(struct v4l2_fh *fh, unsigned int n) -{ - unsigned long flags; - - while (fh->nallocated < n) { - struct v4l2_kevent *kev; - - kev = kzalloc(sizeof(*kev), GFP_KERNEL); - if (kev == NULL) - return -ENOMEM; - - spin_lock_irqsave(&fh->vdev->fh_lock, flags); - list_add_tail(&kev->list, &fh->free); - fh->nallocated++; - spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); - } - - return 0; -} -EXPORT_SYMBOL_GPL(v4l2_event_alloc); - -#define list_kfree(list, type, member) \ - while (!list_empty(list)) { \ - type *hi; \ - hi = list_first_entry(list, type, member); \ - list_del(&hi->member); \ - kfree(hi); \ - } - -void v4l2_event_free(struct v4l2_fh *fh) +static unsigned sev_pos(const struct v4l2_subscribed_event *sev, unsigned idx) { - list_kfree(&fh->free, struct v4l2_kevent, list); - list_kfree(&fh->available, struct v4l2_kevent, list); - v4l2_event_unsubscribe_all(fh); + idx += sev->first; + return idx >= sev->elems ? idx - sev->elems : idx; } -EXPORT_SYMBOL_GPL(v4l2_event_free); static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event) { @@ -84,11 +51,13 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event) WARN_ON(fh->navailable == 0); kev = list_first_entry(&fh->available, struct v4l2_kevent, list); - list_move(&kev->list, &fh->free); + list_del(&kev->list); fh->navailable--; kev->event.pending = fh->navailable; *event = kev->event; + kev->sev->first = sev_pos(kev->sev, 1); + kev->sev->in_use--; spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); @@ -154,17 +123,24 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e fh->sequence++; /* Do we have any free events? */ - if (list_empty(&fh->free)) - return; + if (sev->in_use == sev->elems) { + /* no, remove the oldest one */ + kev = sev->events + sev_pos(sev, 0); + list_del(&kev->list); + sev->in_use--; + sev->first = sev_pos(sev, 1); + fh->navailable--; + } /* Take one and fill it. */ - kev = list_first_entry(&fh->free, struct v4l2_kevent, list); + kev = sev->events + sev_pos(sev, sev->in_use); kev->event.type = ev->type; kev->event.u = ev->u; kev->event.id = ev->id; kev->event.timestamp = *ts; kev->event.sequence = fh->sequence; - list_move_tail(&kev->list, &fh->available); + sev->in_use++; + list_add_tail(&kev->list, &fh->available); fh->navailable++; @@ -209,38 +185,39 @@ int v4l2_event_pending(struct v4l2_fh *fh) EXPORT_SYMBOL_GPL(v4l2_event_pending); int v4l2_event_subscribe(struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + struct v4l2_event_subscription *sub, unsigned elems) { struct v4l2_subscribed_event *sev, *found_ev; struct v4l2_ctrl *ctrl = NULL; unsigned long flags; + unsigned i; + 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), GFP_KERNEL); + sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL); if (!sev) return -ENOMEM; + for (i = 0; i < elems; i++) + sev->events[i].sev = sev; + sev->type = sub->type; + sev->id = sub->id; + sev->flags = sub->flags; + sev->fh = fh; + sev->elems = elems; spin_lock_irqsave(&fh->vdev->fh_lock, flags); - found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); - if (!found_ev) { - INIT_LIST_HEAD(&sev->list); - sev->type = sub->type; - sev->id = sub->id; - sev->fh = fh; - sev->flags = sub->flags; - + if (!found_ev) list_add(&sev->list, &fh->subscribed); - } - spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); - /* v4l2_ctrl_add_fh uses a mutex, so do this outside the spin lock */ + /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */ if (found_ev) kfree(sev); else if (ctrl) @@ -250,7 +227,7 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, } EXPORT_SYMBOL_GPL(v4l2_event_subscribe); -static void v4l2_event_unsubscribe_all(struct v4l2_fh *fh) +void v4l2_event_unsubscribe_all(struct v4l2_fh *fh) { struct v4l2_event_subscription sub; struct v4l2_subscribed_event *sev; @@ -271,6 +248,7 @@ static void v4l2_event_unsubscribe_all(struct v4l2_fh *fh) v4l2_event_unsubscribe(fh, &sub); } while (sev); } +EXPORT_SYMBOL_GPL(v4l2_event_unsubscribe_all); int v4l2_event_unsubscribe(struct v4l2_fh *fh, struct v4l2_event_subscription *sub) diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c index 333b8c8f40d6..122822d2b8b2 100644 --- a/drivers/media/video/v4l2-fh.c +++ b/drivers/media/video/v4l2-fh.c @@ -37,9 +37,7 @@ void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) INIT_LIST_HEAD(&fh->list); set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); fh->prio = V4L2_PRIORITY_UNSET; - init_waitqueue_head(&fh->wait); - INIT_LIST_HEAD(&fh->free); INIT_LIST_HEAD(&fh->available); INIT_LIST_HEAD(&fh->subscribed); fh->sequence = -1; @@ -88,7 +86,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh) { if (fh->vdev == NULL) return; - v4l2_event_free(fh); + v4l2_event_unsubscribe_all(fh); fh->vdev = NULL; } EXPORT_SYMBOL_GPL(v4l2_fh_exit); diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 3b67a8584916..b7967c9dc4ae 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -76,13 +76,6 @@ static int subdev_open(struct file *file) } v4l2_fh_init(&subdev_fh->vfh, vdev); - - if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { - ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents); - if (ret) - goto err; - } - v4l2_fh_add(&subdev_fh->vfh); file->private_data = &subdev_fh->vfh; #if defined(CONFIG_MEDIA_CONTROLLER) diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 1b90713b44c5..cc1cf6b17183 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -993,7 +993,7 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh, { switch (sub->type) { case V4L2_EVENT_CTRL: - return v4l2_ctrl_subscribe_fh(fh, sub, 0); + return v4l2_event_subscribe(fh, sub, 0); default: return -EINVAL; } |