aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/ivtv/ivtv-streams.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2015-03-09 12:33:55 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 21:34:55 -0400
commit635d62f073247e71b51167a01b84f08ff4ca000c (patch)
tree9c23e9119ff1e41b7c4580ea6cd0cbdac94a17f2 /drivers/media/pci/ivtv/ivtv-streams.c
parentb3226f961aa91eb94971939400c7506e7dcc86c0 (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.c107
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 {
159static void ivtv_stream_init(struct ivtv *itv, int type) 159static 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 */
354void ivtv_streams_cleanup(struct ivtv *itv, int unregister) 343void 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");