diff options
-rw-r--r-- | drivers/media/usb/au0828/au0828-video.c | 42 | ||||
-rw-r--r-- | drivers/media/usb/au0828/au0828.h | 4 |
2 files changed, 37 insertions, 9 deletions
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index afb600f9daa6..97397a660af7 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -35,6 +35,7 @@ #include <linux/suspend.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-event.h> #include <media/v4l2-chip-ident.h> #include <media/tuner.h> #include "au0828.h" @@ -988,6 +989,7 @@ static int au0828_v4l2_open(struct file *filp) fh->type = type; fh->dev = dev; + v4l2_fh_init(&fh->fh, vdev); filp->private_data = fh; if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { @@ -1031,6 +1033,7 @@ static int au0828_v4l2_open(struct file *filp) V4L2_FIELD_SEQ_TB, sizeof(struct au0828_buffer), fh, &dev->lock); + v4l2_fh_add(&fh->fh); return ret; } @@ -1040,6 +1043,8 @@ static int au0828_v4l2_close(struct file *filp) struct au0828_fh *fh = filp->private_data; struct au0828_dev *dev = fh->dev; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); if (res_check(fh, AU0828_RESOURCE_VIDEO)) { /* Cancel timeout thread in case they didn't call streamoff */ dev->vid_timeout_running = 0; @@ -1061,6 +1066,7 @@ static int au0828_v4l2_close(struct file *filp) if (dev->users == 1) { if (dev->dev_state & DEV_DISCONNECTED) { au0828_analog_unregister(dev); + kfree(fh); kfree(dev); return 0; } @@ -1128,23 +1134,27 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait) { struct au0828_fh *fh = filp->private_data; struct au0828_dev *dev = fh->dev; - int rc; + unsigned long req_events = poll_requested_events(wait); + unsigned int res; - rc = check_dev(dev); - if (rc < 0) - return rc; + if (check_dev(dev) < 0) + return POLLERR; + + res = v4l2_ctrl_poll(filp, wait); + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (!res_get(fh, AU0828_RESOURCE_VIDEO)) return POLLERR; - return videobuf_poll_stream(filp, &fh->vb_vidq, wait); - } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + return res | videobuf_poll_stream(filp, &fh->vb_vidq, wait); + } + if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { if (!res_get(fh, AU0828_RESOURCE_VBI)) return POLLERR; - return videobuf_poll_stream(filp, &fh->vb_vbiq, wait); - } else { - return POLLERR; + return res | videobuf_poll_stream(filp, &fh->vb_vbiq, wait); } + return POLLERR; } static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) @@ -1761,6 +1771,15 @@ static int vidioc_s_register(struct file *file, void *priv, } #endif +static int vidioc_log_status(struct file *file, void *fh) +{ + struct video_device *vdev = video_devdata(file); + + v4l2_ctrl_log_status(file, fh); + v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status); + return 0; +} + static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb) { @@ -1884,6 +1903,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_register = vidioc_s_register, #endif .vidioc_g_chip_ident = vidioc_g_chip_ident, + .vidioc_log_status = vidioc_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static const struct video_device au0828_video_template = { @@ -1980,12 +2002,14 @@ int au0828_analog_register(struct au0828_dev *dev, *dev->vdev = au0828_video_template; dev->vdev->v4l2_dev = &dev->v4l2_dev; dev->vdev->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags); strcpy(dev->vdev->name, "au0828a video"); /* Setup the VBI device */ *dev->vbi_dev = au0828_video_template; dev->vbi_dev->v4l2_dev = &dev->v4l2_dev; dev->vbi_dev->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags); strcpy(dev->vbi_dev->name, "au0828a vbi"); /* Register the v4l2 device */ diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 803af10f5130..ad400482b2f3 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -29,6 +29,7 @@ #include <media/videobuf-vmalloc.h> #include <media/v4l2-device.h> #include <media/v4l2-ctrls.h> +#include <media/v4l2-fh.h> /* DVB */ #include "demux.h" @@ -119,6 +120,9 @@ enum au0828_dev_state { }; struct au0828_fh { + /* must be the first field of this struct! */ + struct v4l2_fh fh; + struct au0828_dev *dev; unsigned int resources; |