diff options
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-video.c')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-video.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 7be2e7349ef7..26d2a4fe74f1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
38 | #include <media/v4l2-event.h> | ||
38 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/msp3400.h> | 40 | #include <media/msp3400.h> |
40 | #include <media/tuner.h> | 41 | #include <media/tuner.h> |
@@ -1871,6 +1872,7 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1871 | fh->radio = radio; | 1872 | fh->radio = radio; |
1872 | fh->type = fh_type; | 1873 | fh->type = fh_type; |
1873 | filp->private_data = fh; | 1874 | filp->private_data = fh; |
1875 | v4l2_fh_init(&fh->fh, vdev); | ||
1874 | 1876 | ||
1875 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1877 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1876 | dev->width = norm_maxw(dev); | 1878 | dev->width = norm_maxw(dev); |
@@ -1926,6 +1928,7 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1926 | fh, &dev->lock); | 1928 | fh, &dev->lock); |
1927 | } | 1929 | } |
1928 | mutex_unlock(&dev->lock); | 1930 | mutex_unlock(&dev->lock); |
1931 | v4l2_fh_add(&fh->fh); | ||
1929 | 1932 | ||
1930 | return errCode; | 1933 | return errCode; |
1931 | } | 1934 | } |
@@ -2020,12 +2023,15 @@ static int cx231xx_close(struct file *filp) | |||
2020 | else | 2023 | else |
2021 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); | 2024 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); |
2022 | 2025 | ||
2026 | v4l2_fh_del(&fh->fh); | ||
2027 | v4l2_fh_exit(&fh->fh); | ||
2023 | kfree(fh); | 2028 | kfree(fh); |
2024 | dev->users--; | 2029 | dev->users--; |
2025 | wake_up_interruptible_nr(&dev->open, 1); | 2030 | wake_up_interruptible_nr(&dev->open, 1); |
2026 | return 0; | 2031 | return 0; |
2027 | } | 2032 | } |
2028 | 2033 | ||
2034 | v4l2_fh_del(&fh->fh); | ||
2029 | dev->users--; | 2035 | dev->users--; |
2030 | if (!dev->users) { | 2036 | if (!dev->users) { |
2031 | videobuf_stop(&fh->vb_vidq); | 2037 | videobuf_stop(&fh->vb_vidq); |
@@ -2052,6 +2058,7 @@ static int cx231xx_close(struct file *filp) | |||
2052 | /* set alternate 0 */ | 2058 | /* set alternate 0 */ |
2053 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); | 2059 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); |
2054 | } | 2060 | } |
2061 | v4l2_fh_exit(&fh->fh); | ||
2055 | kfree(fh); | 2062 | kfree(fh); |
2056 | wake_up_interruptible_nr(&dev->open, 1); | 2063 | wake_up_interruptible_nr(&dev->open, 1); |
2057 | return 0; | 2064 | return 0; |
@@ -2108,29 +2115,37 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
2108 | */ | 2115 | */ |
2109 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) | 2116 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) |
2110 | { | 2117 | { |
2118 | unsigned long req_events = poll_requested_events(wait); | ||
2111 | struct cx231xx_fh *fh = filp->private_data; | 2119 | struct cx231xx_fh *fh = filp->private_data; |
2112 | struct cx231xx *dev = fh->dev; | 2120 | struct cx231xx *dev = fh->dev; |
2121 | unsigned res = 0; | ||
2113 | int rc; | 2122 | int rc; |
2114 | 2123 | ||
2115 | rc = check_dev(dev); | 2124 | rc = check_dev(dev); |
2116 | if (rc < 0) | 2125 | if (rc < 0) |
2117 | return rc; | 2126 | return POLLERR; |
2118 | 2127 | ||
2119 | rc = res_get(fh); | 2128 | rc = res_get(fh); |
2120 | 2129 | ||
2121 | if (unlikely(rc < 0)) | 2130 | if (unlikely(rc < 0)) |
2122 | return POLLERR; | 2131 | return POLLERR; |
2123 | 2132 | ||
2133 | if (v4l2_event_pending(&fh->fh)) | ||
2134 | res |= POLLPRI; | ||
2135 | else | ||
2136 | poll_wait(filp, &fh->fh.wait, wait); | ||
2137 | |||
2138 | if (!(req_events & (POLLIN | POLLRDNORM))) | ||
2139 | return res; | ||
2140 | |||
2124 | if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || | 2141 | if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || |
2125 | (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { | 2142 | (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { |
2126 | unsigned int res; | ||
2127 | |||
2128 | mutex_lock(&dev->lock); | 2143 | mutex_lock(&dev->lock); |
2129 | res = videobuf_poll_stream(filp, &fh->vb_vidq, wait); | 2144 | res |= videobuf_poll_stream(filp, &fh->vb_vidq, wait); |
2130 | mutex_unlock(&dev->lock); | 2145 | mutex_unlock(&dev->lock); |
2131 | return res; | 2146 | return res; |
2132 | } | 2147 | } |
2133 | return POLLERR; | 2148 | return res | POLLERR; |
2134 | } | 2149 | } |
2135 | 2150 | ||
2136 | /* | 2151 | /* |
@@ -2204,6 +2219,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2204 | .vidioc_g_register = vidioc_g_register, | 2219 | .vidioc_g_register = vidioc_g_register, |
2205 | .vidioc_s_register = vidioc_s_register, | 2220 | .vidioc_s_register = vidioc_s_register, |
2206 | #endif | 2221 | #endif |
2222 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
2223 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
2207 | }; | 2224 | }; |
2208 | 2225 | ||
2209 | static struct video_device cx231xx_vbi_template; | 2226 | static struct video_device cx231xx_vbi_template; |
@@ -2220,6 +2237,7 @@ static const struct v4l2_file_operations radio_fops = { | |||
2220 | .owner = THIS_MODULE, | 2237 | .owner = THIS_MODULE, |
2221 | .open = cx231xx_v4l2_open, | 2238 | .open = cx231xx_v4l2_open, |
2222 | .release = cx231xx_v4l2_close, | 2239 | .release = cx231xx_v4l2_close, |
2240 | .poll = v4l2_ctrl_poll, | ||
2223 | .ioctl = video_ioctl2, | 2241 | .ioctl = video_ioctl2, |
2224 | }; | 2242 | }; |
2225 | 2243 | ||
@@ -2234,6 +2252,8 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
2234 | .vidioc_g_register = vidioc_g_register, | 2252 | .vidioc_g_register = vidioc_g_register, |
2235 | .vidioc_s_register = vidioc_s_register, | 2253 | .vidioc_s_register = vidioc_s_register, |
2236 | #endif | 2254 | #endif |
2255 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
2256 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
2237 | }; | 2257 | }; |
2238 | 2258 | ||
2239 | static struct video_device cx231xx_radio_template = { | 2259 | static struct video_device cx231xx_radio_template = { |
@@ -2259,6 +2279,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | |||
2259 | vfd->release = video_device_release; | 2279 | vfd->release = video_device_release; |
2260 | vfd->debug = video_debug; | 2280 | vfd->debug = video_debug; |
2261 | vfd->lock = &dev->lock; | 2281 | vfd->lock = &dev->lock; |
2282 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
2262 | 2283 | ||
2263 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 2284 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
2264 | 2285 | ||