[media] cx231xx: add struct v4l2_fh to get prio and event support
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 17 Sep 2012 10:31:04 +0000 (07:31 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 5 Mar 2013 17:25:59 +0000 (14:25 -0300)
Required to resolve v4l2-compliance failures.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/usb/cx231xx/cx231xx-video.c
drivers/media/usb/cx231xx/cx231xx.h

index 7be2e7349ef74b68421b69e5804b650ec504b8a8..26d2a4fe74f13cda3a3c0f70059f2f0ea4f3e920 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
@@ -1871,6 +1872,7 @@ static int cx231xx_v4l2_open(struct file *filp)
        fh->radio = radio;
        fh->type = fh_type;
        filp->private_data = fh;
+       v4l2_fh_init(&fh->fh, vdev);
 
        if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
                dev->width = norm_maxw(dev);
@@ -1926,6 +1928,7 @@ static int cx231xx_v4l2_open(struct file *filp)
                                            fh, &dev->lock);
        }
        mutex_unlock(&dev->lock);
+       v4l2_fh_add(&fh->fh);
 
        return errCode;
 }
@@ -2020,12 +2023,15 @@ static int cx231xx_close(struct file *filp)
                        else
                                cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
 
+                       v4l2_fh_del(&fh->fh);
+                       v4l2_fh_exit(&fh->fh);
                        kfree(fh);
                        dev->users--;
                        wake_up_interruptible_nr(&dev->open, 1);
                        return 0;
                }
 
+       v4l2_fh_del(&fh->fh);
        dev->users--;
        if (!dev->users) {
                videobuf_stop(&fh->vb_vidq);
@@ -2052,6 +2058,7 @@ static int cx231xx_close(struct file *filp)
                /* set alternate 0 */
                cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
        }
+       v4l2_fh_exit(&fh->fh);
        kfree(fh);
        wake_up_interruptible_nr(&dev->open, 1);
        return 0;
@@ -2108,29 +2115,37 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
  */
 static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait)
 {
+       unsigned long req_events = poll_requested_events(wait);
        struct cx231xx_fh *fh = filp->private_data;
        struct cx231xx *dev = fh->dev;
+       unsigned res = 0;
        int rc;
 
        rc = check_dev(dev);
        if (rc < 0)
-               return rc;
+               return POLLERR;
 
        rc = res_get(fh);
 
        if (unlikely(rc < 0))
                return POLLERR;
 
+       if (v4l2_event_pending(&fh->fh))
+               res |= POLLPRI;
+       else
+               poll_wait(filp, &fh->fh.wait, wait);
+
+       if (!(req_events & (POLLIN | POLLRDNORM)))
+               return res;
+
        if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
            (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) {
-               unsigned int res;
-
                mutex_lock(&dev->lock);
-               res = videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+               res |= videobuf_poll_stream(filp, &fh->vb_vidq, wait);
                mutex_unlock(&dev->lock);
                return res;
        }
-       return POLLERR;
+       return res | POLLERR;
 }
 
 /*
@@ -2204,6 +2219,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_g_register             = vidioc_g_register,
        .vidioc_s_register             = vidioc_s_register,
 #endif
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static struct video_device cx231xx_vbi_template;
@@ -2220,6 +2237,7 @@ static const struct v4l2_file_operations radio_fops = {
        .owner   = THIS_MODULE,
        .open   = cx231xx_v4l2_open,
        .release = cx231xx_v4l2_close,
+       .poll = v4l2_ctrl_poll,
        .ioctl   = video_ioctl2,
 };
 
@@ -2234,6 +2252,8 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
        .vidioc_g_register  = vidioc_g_register,
        .vidioc_s_register  = vidioc_s_register,
 #endif
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static struct video_device cx231xx_radio_template = {
@@ -2259,6 +2279,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
        vfd->release = video_device_release;
        vfd->debug = video_debug;
        vfd->lock = &dev->lock;
+       set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
 
        snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
 
index 53408ce598d19a52614c2d4048700e6130287d8d..4c83ff54a0ff045f30b28fb6ec8ee435b07cf13e 100644 (file)
@@ -34,6 +34,7 @@
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
 #include <media/rc-core.h>
 #include <media/ir-kbd-i2c.h>
 #include <media/videobuf-dvb.h>
@@ -429,6 +430,7 @@ struct cx231xx_audio {
 struct cx231xx;
 
 struct cx231xx_fh {
+       struct v4l2_fh fh;
        struct cx231xx *dev;
        unsigned int stream_on:1;       /* Locks streams */
        int radio;