diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2015-03-09 12:33:55 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 21:34:55 -0400 |
commit | 635d62f073247e71b51167a01b84f08ff4ca000c (patch) | |
tree | 9c23e9119ff1e41b7c4580ea6cd0cbdac94a17f2 /drivers/media/pci/ivtv/ivtv-streams.c | |
parent | b3226f961aa91eb94971939400c7506e7dcc86c0 (diff) |
[media] ivtv: embed video_device
Embed the video_device struct to simplify the error handling and in
order to (eventually) get rid of video_device_alloc/release.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/pci/ivtv/ivtv-streams.c')
-rw-r--r-- | drivers/media/pci/ivtv/ivtv-streams.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c index f0a1cc472313..cfb61f23d8ed 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.c +++ b/drivers/media/pci/ivtv/ivtv-streams.c | |||
@@ -159,11 +159,9 @@ static struct { | |||
159 | static void ivtv_stream_init(struct ivtv *itv, int type) | 159 | static void ivtv_stream_init(struct ivtv *itv, int type) |
160 | { | 160 | { |
161 | struct ivtv_stream *s = &itv->streams[type]; | 161 | struct ivtv_stream *s = &itv->streams[type]; |
162 | struct video_device *vdev = s->vdev; | ||
163 | 162 | ||
164 | /* we need to keep vdev, so restore it afterwards */ | 163 | /* we need to keep vdev, so restore it afterwards */ |
165 | memset(s, 0, sizeof(*s)); | 164 | memset(s, 0, sizeof(*s)); |
166 | s->vdev = vdev; | ||
167 | 165 | ||
168 | /* initialize ivtv_stream fields */ | 166 | /* initialize ivtv_stream fields */ |
169 | s->itv = itv; | 167 | s->itv = itv; |
@@ -194,10 +192,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
194 | int num_offset = ivtv_stream_info[type].num_offset; | 192 | int num_offset = ivtv_stream_info[type].num_offset; |
195 | int num = itv->instance + ivtv_first_minor + num_offset; | 193 | int num = itv->instance + ivtv_first_minor + num_offset; |
196 | 194 | ||
197 | /* These four fields are always initialized. If vdev == NULL, then | 195 | /* These four fields are always initialized. If vdev.v4l2_dev == NULL, then |
198 | this stream is not in use. In that case no other fields but these | 196 | this stream is not in use. In that case no other fields but these |
199 | four can be used. */ | 197 | four can be used. */ |
200 | s->vdev = NULL; | 198 | s->vdev.v4l2_dev = NULL; |
201 | s->itv = itv; | 199 | s->itv = itv; |
202 | s->type = type; | 200 | s->type = type; |
203 | s->name = ivtv_stream_info[type].name; | 201 | s->name = ivtv_stream_info[type].name; |
@@ -218,40 +216,33 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
218 | 216 | ||
219 | ivtv_stream_init(itv, type); | 217 | ivtv_stream_init(itv, type); |
220 | 218 | ||
221 | /* allocate and initialize the v4l2 video device structure */ | 219 | snprintf(s->vdev.name, sizeof(s->vdev.name), "%s %s", |
222 | s->vdev = video_device_alloc(); | ||
223 | if (s->vdev == NULL) { | ||
224 | IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); | ||
225 | return -ENOMEM; | ||
226 | } | ||
227 | |||
228 | snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", | ||
229 | itv->v4l2_dev.name, s->name); | 220 | itv->v4l2_dev.name, s->name); |
230 | 221 | ||
231 | s->vdev->num = num; | 222 | s->vdev.num = num; |
232 | s->vdev->v4l2_dev = &itv->v4l2_dev; | 223 | s->vdev.v4l2_dev = &itv->v4l2_dev; |
233 | if (ivtv_stream_info[type].v4l2_caps & | 224 | if (ivtv_stream_info[type].v4l2_caps & |
234 | (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT)) | 225 | (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT)) |
235 | s->vdev->vfl_dir = VFL_DIR_TX; | 226 | s->vdev.vfl_dir = VFL_DIR_TX; |
236 | s->vdev->fops = ivtv_stream_info[type].fops; | 227 | s->vdev.fops = ivtv_stream_info[type].fops; |
237 | s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; | 228 | s->vdev.ctrl_handler = itv->v4l2_dev.ctrl_handler; |
238 | s->vdev->release = video_device_release; | 229 | s->vdev.release = video_device_release_empty; |
239 | s->vdev->tvnorms = V4L2_STD_ALL; | 230 | s->vdev.tvnorms = V4L2_STD_ALL; |
240 | s->vdev->lock = &itv->serialize_lock; | 231 | s->vdev.lock = &itv->serialize_lock; |
241 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { | 232 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { |
242 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_AUDIO); | 233 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_AUDIO); |
243 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_AUDIO); | 234 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_AUDIO); |
244 | v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMAUDIO); | 235 | v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMAUDIO); |
245 | v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMINPUT); | 236 | v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMINPUT); |
246 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_INPUT); | 237 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_INPUT); |
247 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_INPUT); | 238 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_INPUT); |
248 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_FREQUENCY); | 239 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_FREQUENCY); |
249 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_FREQUENCY); | 240 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_FREQUENCY); |
250 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_TUNER); | 241 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_TUNER); |
251 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER); | 242 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_TUNER); |
252 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD); | 243 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_STD); |
253 | } | 244 | } |
254 | ivtv_set_funcs(s->vdev); | 245 | ivtv_set_funcs(&s->vdev); |
255 | return 0; | 246 | return 0; |
256 | } | 247 | } |
257 | 248 | ||
@@ -266,7 +257,7 @@ int ivtv_streams_setup(struct ivtv *itv) | |||
266 | if (ivtv_prep_dev(itv, type)) | 257 | if (ivtv_prep_dev(itv, type)) |
267 | break; | 258 | break; |
268 | 259 | ||
269 | if (itv->streams[type].vdev == NULL) | 260 | if (itv->streams[type].vdev.v4l2_dev == NULL) |
270 | continue; | 261 | continue; |
271 | 262 | ||
272 | /* Allocate Stream */ | 263 | /* Allocate Stream */ |
@@ -277,7 +268,7 @@ int ivtv_streams_setup(struct ivtv *itv) | |||
277 | return 0; | 268 | return 0; |
278 | 269 | ||
279 | /* One or more streams could not be initialized. Clean 'em all up. */ | 270 | /* One or more streams could not be initialized. Clean 'em all up. */ |
280 | ivtv_streams_cleanup(itv, 0); | 271 | ivtv_streams_cleanup(itv); |
281 | return -ENOMEM; | 272 | return -ENOMEM; |
282 | } | 273 | } |
283 | 274 | ||
@@ -288,28 +279,26 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
288 | const char *name; | 279 | const char *name; |
289 | int num; | 280 | int num; |
290 | 281 | ||
291 | if (s->vdev == NULL) | 282 | if (s->vdev.v4l2_dev == NULL) |
292 | return 0; | 283 | return 0; |
293 | 284 | ||
294 | num = s->vdev->num; | 285 | num = s->vdev.num; |
295 | /* card number + user defined offset + device offset */ | 286 | /* card number + user defined offset + device offset */ |
296 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { | 287 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { |
297 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; | 288 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; |
298 | 289 | ||
299 | if (s_mpg->vdev) | 290 | if (s_mpg->vdev.v4l2_dev) |
300 | num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; | 291 | num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset; |
301 | } | 292 | } |
302 | video_set_drvdata(s->vdev, s); | 293 | video_set_drvdata(&s->vdev, s); |
303 | 294 | ||
304 | /* Register device. First try the desired minor, then any free one. */ | 295 | /* Register device. First try the desired minor, then any free one. */ |
305 | if (video_register_device_no_warn(s->vdev, vfl_type, num)) { | 296 | if (video_register_device_no_warn(&s->vdev, vfl_type, num)) { |
306 | IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", | 297 | IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", |
307 | s->name, num); | 298 | s->name, num); |
308 | video_device_release(s->vdev); | ||
309 | s->vdev = NULL; | ||
310 | return -ENOMEM; | 299 | return -ENOMEM; |
311 | } | 300 | } |
312 | name = video_device_node_name(s->vdev); | 301 | name = video_device_node_name(&s->vdev); |
313 | 302 | ||
314 | switch (vfl_type) { | 303 | switch (vfl_type) { |
315 | case VFL_TYPE_GRABBER: | 304 | case VFL_TYPE_GRABBER: |
@@ -346,29 +335,25 @@ int ivtv_streams_register(struct ivtv *itv) | |||
346 | return 0; | 335 | return 0; |
347 | 336 | ||
348 | /* One or more streams could not be initialized. Clean 'em all up. */ | 337 | /* One or more streams could not be initialized. Clean 'em all up. */ |
349 | ivtv_streams_cleanup(itv, 1); | 338 | ivtv_streams_cleanup(itv); |
350 | return -ENOMEM; | 339 | return -ENOMEM; |
351 | } | 340 | } |
352 | 341 | ||
353 | /* Unregister v4l2 devices */ | 342 | /* Unregister v4l2 devices */ |
354 | void ivtv_streams_cleanup(struct ivtv *itv, int unregister) | 343 | void ivtv_streams_cleanup(struct ivtv *itv) |
355 | { | 344 | { |
356 | int type; | 345 | int type; |
357 | 346 | ||
358 | /* Teardown all streams */ | 347 | /* Teardown all streams */ |
359 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { | 348 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { |
360 | struct video_device *vdev = itv->streams[type].vdev; | 349 | struct video_device *vdev = &itv->streams[type].vdev; |
361 | 350 | ||
362 | itv->streams[type].vdev = NULL; | 351 | if (vdev->v4l2_dev == NULL) |
363 | if (vdev == NULL) | ||
364 | continue; | 352 | continue; |
365 | 353 | ||
354 | video_unregister_device(vdev); | ||
366 | ivtv_stream_free(&itv->streams[type]); | 355 | ivtv_stream_free(&itv->streams[type]); |
367 | /* Unregister or release device */ | 356 | itv->streams[type].vdev.v4l2_dev = NULL; |
368 | if (unregister) | ||
369 | video_unregister_device(vdev); | ||
370 | else | ||
371 | video_device_release(vdev); | ||
372 | } | 357 | } |
373 | } | 358 | } |
374 | 359 | ||
@@ -492,7 +477,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
492 | int captype = 0, subtype = 0; | 477 | int captype = 0, subtype = 0; |
493 | int enable_passthrough = 0; | 478 | int enable_passthrough = 0; |
494 | 479 | ||
495 | if (s->vdev == NULL) | 480 | if (s->vdev.v4l2_dev == NULL) |
496 | return -EINVAL; | 481 | return -EINVAL; |
497 | 482 | ||
498 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); | 483 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); |
@@ -661,7 +646,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
661 | u16 width; | 646 | u16 width; |
662 | u16 height; | 647 | u16 height; |
663 | 648 | ||
664 | if (s->vdev == NULL) | 649 | if (s->vdev.v4l2_dev == NULL) |
665 | return -EINVAL; | 650 | return -EINVAL; |
666 | 651 | ||
667 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); | 652 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); |
@@ -723,7 +708,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) | |||
723 | struct ivtv *itv = s->itv; | 708 | struct ivtv *itv = s->itv; |
724 | int rc; | 709 | int rc; |
725 | 710 | ||
726 | if (s->vdev == NULL) | 711 | if (s->vdev.v4l2_dev == NULL) |
727 | return -EINVAL; | 712 | return -EINVAL; |
728 | 713 | ||
729 | if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) | 714 | if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) |
@@ -778,7 +763,7 @@ void ivtv_stop_all_captures(struct ivtv *itv) | |||
778 | for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { | 763 | for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { |
779 | struct ivtv_stream *s = &itv->streams[i]; | 764 | struct ivtv_stream *s = &itv->streams[i]; |
780 | 765 | ||
781 | if (s->vdev == NULL) | 766 | if (s->vdev.v4l2_dev == NULL) |
782 | continue; | 767 | continue; |
783 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 768 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
784 | ivtv_stop_v4l2_encode_stream(s, 0); | 769 | ivtv_stop_v4l2_encode_stream(s, 0); |
@@ -793,7 +778,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
793 | int cap_type; | 778 | int cap_type; |
794 | int stopmode; | 779 | int stopmode; |
795 | 780 | ||
796 | if (s->vdev == NULL) | 781 | if (s->vdev.v4l2_dev == NULL) |
797 | return -EINVAL; | 782 | return -EINVAL; |
798 | 783 | ||
799 | /* This function assumes that you are allowed to stop the capture | 784 | /* This function assumes that you are allowed to stop the capture |
@@ -917,7 +902,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
917 | }; | 902 | }; |
918 | struct ivtv *itv = s->itv; | 903 | struct ivtv *itv = s->itv; |
919 | 904 | ||
920 | if (s->vdev == NULL) | 905 | if (s->vdev.v4l2_dev == NULL) |
921 | return -EINVAL; | 906 | return -EINVAL; |
922 | 907 | ||
923 | if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) | 908 | if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) |
@@ -969,7 +954,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
969 | 954 | ||
970 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); | 955 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); |
971 | wake_up(&itv->event_waitq); | 956 | wake_up(&itv->event_waitq); |
972 | v4l2_event_queue(s->vdev, &ev); | 957 | v4l2_event_queue(&s->vdev, &ev); |
973 | 958 | ||
974 | /* wake up wait queues */ | 959 | /* wake up wait queues */ |
975 | wake_up(&s->waitq); | 960 | wake_up(&s->waitq); |
@@ -982,7 +967,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) | |||
982 | struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; | 967 | struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; |
983 | struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | 968 | struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; |
984 | 969 | ||
985 | if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) | 970 | if (yuv_stream->vdev.v4l2_dev == NULL || dec_stream->vdev.v4l2_dev == NULL) |
986 | return -EINVAL; | 971 | return -EINVAL; |
987 | 972 | ||
988 | IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); | 973 | IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); |