aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-subdev.c
diff options
context:
space:
mode:
authorStanimir Varbanov <svarbanov@mm-sol.com>2010-05-21 05:04:24 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 03:53:26 -0400
commit7cd5a16b22af7dc92190a60f336b6854a6fcb99d (patch)
treecce6aabf2417030946c5605fa11e83c902431192 /drivers/media/video/v4l2-subdev.c
parentdacdde78b39e49edf2f7af85be4b613978280b26 (diff)
[media] v4l: Create v4l2 subdev file handle structure
Used for storing subdev information per file handle and hold V4L2 file handle. Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com> Signed-off-by: Antti Koskipaa <akoskipa@gmail.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/v4l2-subdev.c')
-rw-r--r--drivers/media/video/v4l2-subdev.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 85573638aa1e..6cef6ad3c9ce 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -31,36 +31,66 @@
31#include <media/v4l2-fh.h> 31#include <media/v4l2-fh.h>
32#include <media/v4l2-event.h> 32#include <media/v4l2-event.h>
33 33
34static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
35{
36#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
37 /* Allocate try format and crop in the same memory block */
38 fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
39 * sd->entity.num_pads, GFP_KERNEL);
40 if (fh->try_fmt == NULL)
41 return -ENOMEM;
42
43 fh->try_crop = (struct v4l2_rect *)
44 (fh->try_fmt + sd->entity.num_pads);
45#endif
46 return 0;
47}
48
49static void subdev_fh_free(struct v4l2_subdev_fh *fh)
50{
51#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
52 kfree(fh->try_fmt);
53 fh->try_fmt = NULL;
54 fh->try_crop = NULL;
55#endif
56}
57
34static int subdev_open(struct file *file) 58static int subdev_open(struct file *file)
35{ 59{
36 struct video_device *vdev = video_devdata(file); 60 struct video_device *vdev = video_devdata(file);
37 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 61 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
62 struct v4l2_subdev_fh *subdev_fh;
38#if defined(CONFIG_MEDIA_CONTROLLER) 63#if defined(CONFIG_MEDIA_CONTROLLER)
39 struct media_entity *entity; 64 struct media_entity *entity;
40#endif 65#endif
41 struct v4l2_fh *vfh = NULL;
42 int ret; 66 int ret;
43 67
44 if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { 68 subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
45 vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); 69 if (subdev_fh == NULL)
46 if (vfh == NULL) 70 return -ENOMEM;
47 return -ENOMEM;
48 71
49 ret = v4l2_fh_init(vfh, vdev); 72 ret = subdev_fh_init(subdev_fh, sd);
50 if (ret) 73 if (ret) {
51 goto err; 74 kfree(subdev_fh);
75 return ret;
76 }
77
78 ret = v4l2_fh_init(&subdev_fh->vfh, vdev);
79 if (ret)
80 goto err;
52 81
53 ret = v4l2_event_init(vfh); 82 if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) {
83 ret = v4l2_event_init(&subdev_fh->vfh);
54 if (ret) 84 if (ret)
55 goto err; 85 goto err;
56 86
57 ret = v4l2_event_alloc(vfh, sd->nevents); 87 ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents);
58 if (ret) 88 if (ret)
59 goto err; 89 goto err;
60
61 v4l2_fh_add(vfh);
62 file->private_data = vfh;
63 } 90 }
91
92 v4l2_fh_add(&subdev_fh->vfh);
93 file->private_data = &subdev_fh->vfh;
64#if defined(CONFIG_MEDIA_CONTROLLER) 94#if defined(CONFIG_MEDIA_CONTROLLER)
65 if (sd->v4l2_dev->mdev) { 95 if (sd->v4l2_dev->mdev) {
66 entity = media_entity_get(&sd->entity); 96 entity = media_entity_get(&sd->entity);
@@ -70,14 +100,14 @@ static int subdev_open(struct file *file)
70 } 100 }
71 } 101 }
72#endif 102#endif
103
73 return 0; 104 return 0;
74 105
75err: 106err:
76 if (vfh != NULL) { 107 v4l2_fh_del(&subdev_fh->vfh);
77 v4l2_fh_del(vfh); 108 v4l2_fh_exit(&subdev_fh->vfh);
78 v4l2_fh_exit(vfh); 109 subdev_fh_free(subdev_fh);
79 kfree(vfh); 110 kfree(subdev_fh);
80 }
81 111
82 return ret; 112 return ret;
83} 113}
@@ -89,16 +119,17 @@ static int subdev_close(struct file *file)
89 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 119 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
90#endif 120#endif
91 struct v4l2_fh *vfh = file->private_data; 121 struct v4l2_fh *vfh = file->private_data;
122 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
92 123
93#if defined(CONFIG_MEDIA_CONTROLLER) 124#if defined(CONFIG_MEDIA_CONTROLLER)
94 if (sd->v4l2_dev->mdev) 125 if (sd->v4l2_dev->mdev)
95 media_entity_put(&sd->entity); 126 media_entity_put(&sd->entity);
96#endif 127#endif
97 if (vfh != NULL) { 128 v4l2_fh_del(vfh);
98 v4l2_fh_del(vfh); 129 v4l2_fh_exit(vfh);
99 v4l2_fh_exit(vfh); 130 subdev_fh_free(subdev_fh);
100 kfree(vfh); 131 kfree(subdev_fh);
101 } 132 file->private_data = NULL;
102 133
103 return 0; 134 return 0;
104} 135}
@@ -107,7 +138,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
107{ 138{
108 struct video_device *vdev = video_devdata(file); 139 struct video_device *vdev = video_devdata(file);
109 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 140 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
110 struct v4l2_fh *fh = file->private_data; 141 struct v4l2_fh *vfh = file->private_data;
111 142
112 switch (cmd) { 143 switch (cmd) {
113 case VIDIOC_QUERYCTRL: 144 case VIDIOC_QUERYCTRL:
@@ -135,13 +166,13 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
135 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) 166 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
136 return -ENOIOCTLCMD; 167 return -ENOIOCTLCMD;
137 168
138 return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); 169 return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
139 170
140 case VIDIOC_SUBSCRIBE_EVENT: 171 case VIDIOC_SUBSCRIBE_EVENT:
141 return v4l2_subdev_call(sd, core, subscribe_event, fh, arg); 172 return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
142 173
143 case VIDIOC_UNSUBSCRIBE_EVENT: 174 case VIDIOC_UNSUBSCRIBE_EVENT:
144 return v4l2_subdev_call(sd, core, unsubscribe_event, fh, arg); 175 return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
145 176
146 default: 177 default:
147 return -ENOIOCTLCMD; 178 return -ENOIOCTLCMD;