diff options
-rw-r--r-- | drivers/media/video/v4l2-fh.c | 11 | ||||
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 50 | ||||
-rw-r--r-- | include/media/v4l2-ioctl.h | 7 |
3 files changed, 67 insertions, 1 deletions
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c index aab2fb639ef1..d78f184f40c5 100644 --- a/drivers/media/video/v4l2-fh.c +++ b/drivers/media/video/v4l2-fh.c | |||
@@ -34,7 +34,16 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) | |||
34 | INIT_LIST_HEAD(&fh->list); | 34 | INIT_LIST_HEAD(&fh->list); |
35 | set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); | 35 | set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); |
36 | 36 | ||
37 | return v4l2_event_init(fh); | 37 | /* |
38 | * fh->events only needs to be initialized if the driver | ||
39 | * supports the VIDIOC_SUBSCRIBE_EVENT ioctl. | ||
40 | */ | ||
41 | if (vdev->ioctl_ops && vdev->ioctl_ops->vidioc_subscribe_event) | ||
42 | return v4l2_event_init(fh); | ||
43 | |||
44 | fh->events = NULL; | ||
45 | |||
46 | return 0; | ||
38 | } | 47 | } |
39 | EXPORT_SYMBOL_GPL(v4l2_fh_init); | 48 | EXPORT_SYMBOL_GPL(v4l2_fh_init); |
40 | 49 | ||
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 2ceaa152a450..0eeceae50329 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #endif | 26 | #endif |
27 | #include <media/v4l2-common.h> | 27 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-ioctl.h> | 28 | #include <media/v4l2-ioctl.h> |
29 | #include <media/v4l2-fh.h> | ||
30 | #include <media/v4l2-event.h> | ||
29 | #include <media/v4l2-chip-ident.h> | 31 | #include <media/v4l2-chip-ident.h> |
30 | 32 | ||
31 | #define dbgarg(cmd, fmt, arg...) \ | 33 | #define dbgarg(cmd, fmt, arg...) \ |
@@ -1951,7 +1953,55 @@ static long __video_do_ioctl(struct file *file, | |||
1951 | } | 1953 | } |
1952 | break; | 1954 | break; |
1953 | } | 1955 | } |
1956 | case VIDIOC_DQEVENT: | ||
1957 | { | ||
1958 | struct v4l2_event *ev = arg; | ||
1959 | |||
1960 | if (!ops->vidioc_subscribe_event) | ||
1961 | break; | ||
1962 | |||
1963 | ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK); | ||
1964 | if (ret < 0) { | ||
1965 | dbgarg(cmd, "no pending events?"); | ||
1966 | break; | ||
1967 | } | ||
1968 | dbgarg(cmd, | ||
1969 | "pending=%d, type=0x%8.8x, sequence=%d, " | ||
1970 | "timestamp=%lu.%9.9lu ", | ||
1971 | ev->pending, ev->type, ev->sequence, | ||
1972 | ev->timestamp.tv_sec, ev->timestamp.tv_nsec); | ||
1973 | break; | ||
1974 | } | ||
1975 | case VIDIOC_SUBSCRIBE_EVENT: | ||
1976 | { | ||
1977 | struct v4l2_event_subscription *sub = arg; | ||
1954 | 1978 | ||
1979 | if (!ops->vidioc_subscribe_event) | ||
1980 | break; | ||
1981 | |||
1982 | ret = ops->vidioc_subscribe_event(fh, sub); | ||
1983 | if (ret < 0) { | ||
1984 | dbgarg(cmd, "failed, ret=%ld", ret); | ||
1985 | break; | ||
1986 | } | ||
1987 | dbgarg(cmd, "type=0x%8.8x", sub->type); | ||
1988 | break; | ||
1989 | } | ||
1990 | case VIDIOC_UNSUBSCRIBE_EVENT: | ||
1991 | { | ||
1992 | struct v4l2_event_subscription *sub = arg; | ||
1993 | |||
1994 | if (!ops->vidioc_unsubscribe_event) | ||
1995 | break; | ||
1996 | |||
1997 | ret = ops->vidioc_unsubscribe_event(fh, sub); | ||
1998 | if (ret < 0) { | ||
1999 | dbgarg(cmd, "failed, ret=%ld", ret); | ||
2000 | break; | ||
2001 | } | ||
2002 | dbgarg(cmd, "type=0x%8.8x", sub->type); | ||
2003 | break; | ||
2004 | } | ||
1955 | default: | 2005 | default: |
1956 | { | 2006 | { |
1957 | if (!ops->vidioc_default) | 2007 | if (!ops->vidioc_default) |
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index e8ba0f2efbae..06daa6e8e051 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | struct v4l2_fh; | ||
25 | |||
24 | struct v4l2_ioctl_ops { | 26 | struct v4l2_ioctl_ops { |
25 | /* ioctl callbacks */ | 27 | /* ioctl callbacks */ |
26 | 28 | ||
@@ -254,6 +256,11 @@ struct v4l2_ioctl_ops { | |||
254 | int (*vidioc_g_dv_timings) (struct file *file, void *fh, | 256 | int (*vidioc_g_dv_timings) (struct file *file, void *fh, |
255 | struct v4l2_dv_timings *timings); | 257 | struct v4l2_dv_timings *timings); |
256 | 258 | ||
259 | int (*vidioc_subscribe_event) (struct v4l2_fh *fh, | ||
260 | struct v4l2_event_subscription *sub); | ||
261 | int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, | ||
262 | struct v4l2_event_subscription *sub); | ||
263 | |||
257 | /* For other private ioctls */ | 264 | /* For other private ioctls */ |
258 | long (*vidioc_default) (struct file *file, void *fh, | 265 | long (*vidioc_default) (struct file *file, void *fh, |
259 | int cmd, void *arg); | 266 | int cmd, void *arg); |