aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c151
-rw-r--r--drivers/media/video/em28xx/em28xx.h2
2 files changed, 80 insertions, 73 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 18b8568c634c..bc495a11dc2d 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -126,8 +126,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
126 126
127static struct usb_driver em28xx_usb_driver; 127static struct usb_driver em28xx_usb_driver;
128 128
129static DEFINE_MUTEX(em28xx_sysfs_lock);
130static DECLARE_RWSEM(em28xx_disconnect);
131 129
132/********************* v4l2 interface ******************************************/ 130/********************* v4l2 interface ******************************************/
133 131
@@ -253,22 +251,18 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
253 em28xx_videodbg("open minor=%d type=%s users=%d\n", 251 em28xx_videodbg("open minor=%d type=%s users=%d\n",
254 minor,v4l2_type_names[dev->type],dev->users); 252 minor,v4l2_type_names[dev->type],dev->users);
255 253
256 if (!down_read_trylock(&em28xx_disconnect)) 254 mutex_lock(&dev->lock);
257 return -ERESTARTSYS;
258 255
259 if (dev->users) { 256 if (dev->users) {
260 em28xx_warn("this driver can be opened only once\n"); 257 em28xx_warn("this driver can be opened only once\n");
261 up_read(&em28xx_disconnect); 258 mutex_unlock(&dev->lock);
262 return -EBUSY; 259 return -EBUSY;
263 } 260 }
264 261
265 mutex_init(&dev->fileop_lock); /* to 1 == available */
266 spin_lock_init(&dev->queue_lock); 262 spin_lock_init(&dev->queue_lock);
267 init_waitqueue_head(&dev->wait_frame); 263 init_waitqueue_head(&dev->wait_frame);
268 init_waitqueue_head(&dev->wait_stream); 264 init_waitqueue_head(&dev->wait_stream);
269 265
270 mutex_lock(&dev->lock);
271
272 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 266 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
273 em28xx_set_alternate(dev); 267 em28xx_set_alternate(dev);
274 268
@@ -306,7 +300,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
306 300
307err: 301err:
308 mutex_unlock(&dev->lock); 302 mutex_unlock(&dev->lock);
309 up_read(&em28xx_disconnect);
310 return errCode; 303 return errCode;
311} 304}
312 305
@@ -317,7 +310,6 @@ err:
317*/ 310*/
318static void em28xx_release_resources(struct em28xx *dev) 311static void em28xx_release_resources(struct em28xx *dev)
319{ 312{
320 mutex_lock(&em28xx_sysfs_lock);
321 313
322 /*FIXME: I2C IR should be disconnected */ 314 /*FIXME: I2C IR should be disconnected */
323 315
@@ -329,7 +321,6 @@ static void em28xx_release_resources(struct em28xx *dev)
329 video_unregister_device(dev->vbi_dev); 321 video_unregister_device(dev->vbi_dev);
330 em28xx_i2c_unregister(dev); 322 em28xx_i2c_unregister(dev);
331 usb_put_dev(dev->udev); 323 usb_put_dev(dev->udev);
332 mutex_unlock(&em28xx_sysfs_lock);
333 324
334 325
335 /* Mark device as unused */ 326 /* Mark device as unused */
@@ -389,6 +380,8 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
389 int ret = 0; 380 int ret = 0;
390 struct em28xx *dev = filp->private_data; 381 struct em28xx *dev = filp->private_data;
391 382
383 mutex_lock(&dev->lock);
384
392 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 385 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
393 em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); 386 em28xx_videodbg("V4l2_Buf_type_videocapture is set\n");
394 } 387 }
@@ -396,47 +389,46 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
396 em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); 389 em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n");
397 em28xx_videodbg("not supported yet! ...\n"); 390 em28xx_videodbg("not supported yet! ...\n");
398 if (copy_to_user(buf, "", 1)) { 391 if (copy_to_user(buf, "", 1)) {
399 mutex_unlock(&dev->fileop_lock); 392 mutex_unlock(&dev->lock);
400 return -EFAULT; 393 return -EFAULT;
401 } 394 }
395 mutex_unlock(&dev->lock);
402 return (1); 396 return (1);
403 } 397 }
404 if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 398 if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
405 em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n"); 399 em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n");
406 em28xx_videodbg("not supported yet! ...\n"); 400 em28xx_videodbg("not supported yet! ...\n");
407 if (copy_to_user(buf, "", 1)) { 401 if (copy_to_user(buf, "", 1)) {
408 mutex_unlock(&dev->fileop_lock); 402 mutex_unlock(&dev->lock);
409 return -EFAULT; 403 return -EFAULT;
410 } 404 }
405 mutex_unlock(&dev->lock);
411 return (1); 406 return (1);
412 } 407 }
413 408
414 if (mutex_lock_interruptible(&dev->fileop_lock))
415 return -ERESTARTSYS;
416
417 if (dev->state & DEV_DISCONNECTED) { 409 if (dev->state & DEV_DISCONNECTED) {
418 em28xx_videodbg("device not present\n"); 410 em28xx_videodbg("device not present\n");
419 mutex_unlock(&dev->fileop_lock); 411 mutex_unlock(&dev->lock);
420 return -ENODEV; 412 return -ENODEV;
421 } 413 }
422 414
423 if (dev->state & DEV_MISCONFIGURED) { 415 if (dev->state & DEV_MISCONFIGURED) {
424 em28xx_videodbg("device misconfigured; close and open it again\n"); 416 em28xx_videodbg("device misconfigured; close and open it again\n");
425 mutex_unlock(&dev->fileop_lock); 417 mutex_unlock(&dev->lock);
426 return -EIO; 418 return -EIO;
427 } 419 }
428 420
429 if (dev->io == IO_MMAP) { 421 if (dev->io == IO_MMAP) {
430 em28xx_videodbg ("IO method is set to mmap; close and open" 422 em28xx_videodbg ("IO method is set to mmap; close and open"
431 " the device again to choose the read method\n"); 423 " the device again to choose the read method\n");
432 mutex_unlock(&dev->fileop_lock); 424 mutex_unlock(&dev->lock);
433 return -EINVAL; 425 return -EINVAL;
434 } 426 }
435 427
436 if (dev->io == IO_NONE) { 428 if (dev->io == IO_NONE) {
437 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { 429 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
438 em28xx_errdev("read failed, not enough memory\n"); 430 em28xx_errdev("read failed, not enough memory\n");
439 mutex_unlock(&dev->fileop_lock); 431 mutex_unlock(&dev->lock);
440 return -ENOMEM; 432 return -ENOMEM;
441 } 433 }
442 dev->io = IO_READ; 434 dev->io = IO_READ;
@@ -445,13 +437,13 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
445 } 437 }
446 438
447 if (!count) { 439 if (!count) {
448 mutex_unlock(&dev->fileop_lock); 440 mutex_unlock(&dev->lock);
449 return 0; 441 return 0;
450 } 442 }
451 443
452 if (list_empty(&dev->outqueue)) { 444 if (list_empty(&dev->outqueue)) {
453 if (filp->f_flags & O_NONBLOCK) { 445 if (filp->f_flags & O_NONBLOCK) {
454 mutex_unlock(&dev->fileop_lock); 446 mutex_unlock(&dev->lock);
455 return -EAGAIN; 447 return -EAGAIN;
456 } 448 }
457 ret = wait_event_interruptible 449 ret = wait_event_interruptible
@@ -459,11 +451,11 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
459 (!list_empty(&dev->outqueue)) || 451 (!list_empty(&dev->outqueue)) ||
460 (dev->state & DEV_DISCONNECTED)); 452 (dev->state & DEV_DISCONNECTED));
461 if (ret) { 453 if (ret) {
462 mutex_unlock(&dev->fileop_lock); 454 mutex_unlock(&dev->lock);
463 return ret; 455 return ret;
464 } 456 }
465 if (dev->state & DEV_DISCONNECTED) { 457 if (dev->state & DEV_DISCONNECTED) {
466 mutex_unlock(&dev->fileop_lock); 458 mutex_unlock(&dev->lock);
467 return -ENODEV; 459 return -ENODEV;
468 } 460 }
469 } 461 }
@@ -482,12 +474,12 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
482 count = f->buf.length; 474 count = f->buf.length;
483 475
484 if (copy_to_user(buf, f->bufmem, count)) { 476 if (copy_to_user(buf, f->bufmem, count)) {
485 mutex_unlock(&dev->fileop_lock); 477 mutex_unlock(&dev->lock);
486 return -EFAULT; 478 return -EFAULT;
487 } 479 }
488 *f_pos += count; 480 *f_pos += count;
489 481
490 mutex_unlock(&dev->fileop_lock); 482 mutex_unlock(&dev->lock);
491 483
492 return count; 484 return count;
493} 485}
@@ -501,8 +493,7 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
501 unsigned int mask = 0; 493 unsigned int mask = 0;
502 struct em28xx *dev = filp->private_data; 494 struct em28xx *dev = filp->private_data;
503 495
504 if (mutex_lock_interruptible(&dev->fileop_lock)) 496 mutex_lock(&dev->lock);
505 return POLLERR;
506 497
507 if (dev->state & DEV_DISCONNECTED) { 498 if (dev->state & DEV_DISCONNECTED) {
508 em28xx_videodbg("device not present\n"); 499 em28xx_videodbg("device not present\n");
@@ -527,13 +518,13 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
527 if (!list_empty(&dev->outqueue)) 518 if (!list_empty(&dev->outqueue))
528 mask |= POLLIN | POLLRDNORM; 519 mask |= POLLIN | POLLRDNORM;
529 520
530 mutex_unlock(&dev->fileop_lock); 521 mutex_unlock(&dev->lock);
531 522
532 return mask; 523 return mask;
533 } 524 }
534 } 525 }
535 526
536 mutex_unlock(&dev->fileop_lock); 527 mutex_unlock(&dev->lock);
537 return POLLERR; 528 return POLLERR;
538} 529}
539 530
@@ -575,25 +566,24 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
575 566
576 struct em28xx *dev = filp->private_data; 567 struct em28xx *dev = filp->private_data;
577 568
578 if (mutex_lock_interruptible(&dev->fileop_lock)) 569 mutex_lock(&dev->lock);
579 return -ERESTARTSYS;
580 570
581 if (dev->state & DEV_DISCONNECTED) { 571 if (dev->state & DEV_DISCONNECTED) {
582 em28xx_videodbg("mmap: device not present\n"); 572 em28xx_videodbg("mmap: device not present\n");
583 mutex_unlock(&dev->fileop_lock); 573 mutex_unlock(&dev->lock);
584 return -ENODEV; 574 return -ENODEV;
585 } 575 }
586 576
587 if (dev->state & DEV_MISCONFIGURED) { 577 if (dev->state & DEV_MISCONFIGURED) {
588 em28xx_videodbg ("mmap: Device is misconfigured; close and " 578 em28xx_videodbg ("mmap: Device is misconfigured; close and "
589 "open it again\n"); 579 "open it again\n");
590 mutex_unlock(&dev->fileop_lock); 580 mutex_unlock(&dev->lock);
591 return -EIO; 581 return -EIO;
592 } 582 }
593 583
594 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || 584 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
595 size != PAGE_ALIGN(dev->frame[0].buf.length)) { 585 size != PAGE_ALIGN(dev->frame[0].buf.length)) {
596 mutex_unlock(&dev->fileop_lock); 586 mutex_unlock(&dev->lock);
597 return -EINVAL; 587 return -EINVAL;
598 } 588 }
599 589
@@ -603,7 +593,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
603 } 593 }
604 if (i == dev->num_frames) { 594 if (i == dev->num_frames) {
605 em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); 595 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
606 mutex_unlock(&dev->fileop_lock); 596 mutex_unlock(&dev->lock);
607 return -EINVAL; 597 return -EINVAL;
608 } 598 }
609 599
@@ -615,7 +605,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
615 while (size > 0) { /* size is page-aligned */ 605 while (size > 0) { /* size is page-aligned */
616 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { 606 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
617 em28xx_videodbg("mmap: vm_insert_page failed\n"); 607 em28xx_videodbg("mmap: vm_insert_page failed\n");
618 mutex_unlock(&dev->fileop_lock); 608 mutex_unlock(&dev->lock);
619 return -EAGAIN; 609 return -EAGAIN;
620 } 610 }
621 start += PAGE_SIZE; 611 start += PAGE_SIZE;
@@ -627,7 +617,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
627 vma->vm_private_data = &dev->frame[i]; 617 vma->vm_private_data = &dev->frame[i];
628 618
629 em28xx_vm_open(vma); 619 em28xx_vm_open(vma);
630 mutex_unlock(&dev->fileop_lock); 620 mutex_unlock(&dev->lock);
631 return 0; 621 return 0;
632} 622}
633 623
@@ -1084,7 +1074,9 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1084 } 1074 }
1085 } 1075 }
1086 } 1076 }
1077 mutex_lock(&dev->lock);
1087 em28xx_i2c_call_clients(dev,cmd,qc); 1078 em28xx_i2c_call_clients(dev,cmd,qc);
1079 mutex_unlock(&dev->lock);
1088 if (qc->type) 1080 if (qc->type)
1089 return 0; 1081 return 0;
1090 else 1082 else
@@ -1098,7 +1090,9 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1098 if (!dev->has_msp34xx) 1090 if (!dev->has_msp34xx)
1099 retval=em28xx_get_ctrl(dev, ctrl); 1091 retval=em28xx_get_ctrl(dev, ctrl);
1100 if (retval==-EINVAL) { 1092 if (retval==-EINVAL) {
1093 mutex_lock(&dev->lock);
1101 em28xx_i2c_call_clients(dev,cmd,arg); 1094 em28xx_i2c_call_clients(dev,cmd,arg);
1095 mutex_unlock(&dev->lock);
1102 return 0; 1096 return 0;
1103 } else return retval; 1097 } else return retval;
1104 } 1098 }
@@ -1106,21 +1100,26 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1106 { 1100 {
1107 struct v4l2_control *ctrl = arg; 1101 struct v4l2_control *ctrl = arg;
1108 u8 i; 1102 u8 i;
1103 mutex_lock(&dev->lock);
1109 1104
1110 if (!dev->has_msp34xx){ 1105 if (!dev->has_msp34xx){
1111 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 1106 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1112 if (ctrl->id == em28xx_qctrl[i].id) { 1107 if (ctrl->id == em28xx_qctrl[i].id) {
1108 int retval=-EINVAL;
1113 if (ctrl->value < 1109 if (ctrl->value <
1114 em28xx_qctrl[i].minimum 1110 em28xx_qctrl[i].minimum
1115 || ctrl->value > 1111 || ctrl->value >
1116 em28xx_qctrl[i].maximum) 1112 em28xx_qctrl[i].maximum)
1117 return -ERANGE; 1113 return -ERANGE;
1118 return em28xx_set_ctrl(dev, ctrl); 1114 retval = em28xx_set_ctrl(dev, ctrl);
1115 mutex_unlock(&dev->lock);
1116 return retval;
1119 } 1117 }
1120 } 1118 }
1121 } 1119 }
1122 1120
1123 em28xx_i2c_call_clients(dev,cmd,arg); 1121 em28xx_i2c_call_clients(dev,cmd,arg);
1122 mutex_unlock(&dev->lock);
1124 return 0; 1123 return 0;
1125 } 1124 }
1126 /* --- tuner ioctls ------------------------------------------ */ 1125 /* --- tuner ioctls ------------------------------------------ */
@@ -1220,12 +1219,16 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1220 || dev->io != IO_MMAP) 1219 || dev->io != IO_MMAP)
1221 return -EINVAL; 1220 return -EINVAL;
1222 1221
1222 mutex_lock(&dev->lock);
1223 if (dev->stream == STREAM_ON) { 1223 if (dev->stream == STREAM_ON) {
1224 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); 1224 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1225 if ((ret = em28xx_stream_interrupt(dev))) 1225 if ((ret = em28xx_stream_interrupt(dev))){
1226 mutex_unlock(&dev->lock);
1226 return ret; 1227 return ret;
1228 }
1227 } 1229 }
1228 em28xx_empty_framequeues(dev); 1230 em28xx_empty_framequeues(dev);
1231 mutex_unlock(&dev->lock);
1229 1232
1230 return 0; 1233 return 0;
1231 } 1234 }
@@ -1291,11 +1294,23 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1291 return 0; 1294 return 0;
1292 } 1295 }
1293 case VIDIOC_G_FMT: 1296 case VIDIOC_G_FMT:
1294 return em28xx_get_fmt(dev, (struct v4l2_format *) arg); 1297 {
1298 int retval;
1299 mutex_lock(&dev->lock);
1300 retval = em28xx_get_fmt(dev, (struct v4l2_format *) arg);
1301 mutex_unlock(&dev->lock);
1302 return retval;
1295 1303
1304 }
1296 case VIDIOC_TRY_FMT: 1305 case VIDIOC_TRY_FMT:
1297 case VIDIOC_S_FMT: 1306 case VIDIOC_S_FMT:
1298 return em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg); 1307 {
1308 int retval;
1309 mutex_lock(&dev->lock);
1310 retval = em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg);
1311 mutex_unlock(&dev->lock);
1312 return retval;
1313 }
1299 1314
1300 case VIDIOC_REQBUFS: 1315 case VIDIOC_REQBUFS:
1301 { 1316 {
@@ -1320,10 +1335,13 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1320 return -EINVAL; 1335 return -EINVAL;
1321 } 1336 }
1322 1337
1338 mutex_lock(&dev->lock);
1323 if (dev->stream == STREAM_ON) { 1339 if (dev->stream == STREAM_ON) {
1324 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); 1340 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1325 if ((ret = em28xx_stream_interrupt(dev))) 1341 if ((ret = em28xx_stream_interrupt(dev))){
1342 mutex_unlock(&dev->lock);
1326 return ret; 1343 return ret;
1344 }
1327 } 1345 }
1328 1346
1329 em28xx_empty_framequeues(dev); 1347 em28xx_empty_framequeues(dev);
@@ -1338,6 +1356,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1338 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", 1356 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1339 rb->count); 1357 rb->count);
1340 dev->io = rb->count ? IO_MMAP : IO_NONE; 1358 dev->io = rb->count ? IO_MMAP : IO_NONE;
1359 mutex_unlock(&dev->lock);
1341 return 0; 1360 return 0;
1342 } 1361 }
1343 case VIDIOC_QUERYBUF: 1362 case VIDIOC_QUERYBUF:
@@ -1439,26 +1458,19 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1439 int ret = 0; 1458 int ret = 0;
1440 struct em28xx *dev = filp->private_data; 1459 struct em28xx *dev = filp->private_data;
1441 1460
1442 if (mutex_lock_interruptible(&dev->fileop_lock))
1443 return -ERESTARTSYS;
1444
1445 if (dev->state & DEV_DISCONNECTED) { 1461 if (dev->state & DEV_DISCONNECTED) {
1446 em28xx_errdev("v4l2 ioctl: device not present\n"); 1462 em28xx_errdev("v4l2 ioctl: device not present\n");
1447 mutex_unlock(&dev->fileop_lock);
1448 return -ENODEV; 1463 return -ENODEV;
1449 } 1464 }
1450 1465
1451 if (dev->state & DEV_MISCONFIGURED) { 1466 if (dev->state & DEV_MISCONFIGURED) {
1452 em28xx_errdev 1467 em28xx_errdev
1453 ("v4l2 ioctl: device is misconfigured; close and open it again\n"); 1468 ("v4l2 ioctl: device is misconfigured; close and open it again\n");
1454 mutex_unlock(&dev->fileop_lock);
1455 return -EIO; 1469 return -EIO;
1456 } 1470 }
1457 1471
1458 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl); 1472 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
1459 1473
1460 mutex_unlock(&dev->fileop_lock);
1461
1462 return ret; 1474 return ret;
1463} 1475}
1464 1476
@@ -1519,8 +1531,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1519 return -ENOMEM; 1531 return -ENOMEM;
1520 } 1532 }
1521 1533
1522 mutex_lock(&dev->lock);
1523
1524 /* register i2c bus */ 1534 /* register i2c bus */
1525 em28xx_i2c_register(dev); 1535 em28xx_i2c_register(dev);
1526 1536
@@ -1530,8 +1540,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1530 /* configure the device */ 1540 /* configure the device */
1531 em28xx_config_i2c(dev); 1541 em28xx_config_i2c(dev);
1532 1542
1533 mutex_unlock(&dev->lock);
1534
1535 for (i = 0; i < TVNORMS; i++) 1543 for (i = 0; i < TVNORMS; i++)
1536 if (em28xx_boards[dev->model].norm == tvnorms[i].mode) 1544 if (em28xx_boards[dev->model].norm == tvnorms[i].mode)
1537 break; 1545 break;
@@ -1599,8 +1607,18 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1599 1607
1600 list_add_tail(&dev->devlist,&em28xx_devlist); 1608 list_add_tail(&dev->devlist,&em28xx_devlist);
1601 1609
1610
1611 if (dev->has_msp34xx) {
1612 /* Send a reset to other chips via gpio */
1613 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1614 msleep(3);
1615 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1616 msleep(3);
1617
1618 }
1619 video_mux(dev, 0);
1620
1602 /* register v4l2 device */ 1621 /* register v4l2 device */
1603 mutex_lock(&dev->lock);
1604 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, 1622 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
1605 video_nr[dev->devno]))) { 1623 video_nr[dev->devno]))) {
1606 em28xx_errdev("unable to register video device (error=%i).\n", 1624 em28xx_errdev("unable to register video device (error=%i).\n",
@@ -1627,18 +1645,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1627 printk("registered VBI\n"); 1645 printk("registered VBI\n");
1628 } 1646 }
1629 1647
1630 if (dev->has_msp34xx) {
1631 /* Send a reset to other chips via gpio */
1632 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1633 msleep(3);
1634 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1635 msleep(3);
1636
1637 }
1638 video_mux(dev, 0);
1639
1640 mutex_unlock(&dev->lock);
1641
1642 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", 1648 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
1643 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, 1649 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
1644 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); 1650 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
@@ -1762,18 +1768,19 @@ static int em28xx_usb_probe(struct usb_interface *interface,
1762 */ 1768 */
1763static void em28xx_usb_disconnect(struct usb_interface *interface) 1769static void em28xx_usb_disconnect(struct usb_interface *interface)
1764{ 1770{
1765 struct em28xx *dev = usb_get_intfdata(interface); 1771 struct em28xx *dev;
1772
1773 dev = usb_get_intfdata(interface);
1766 usb_set_intfdata(interface, NULL); 1774 usb_set_intfdata(interface, NULL);
1767 1775
1768 if (!dev) 1776 if (!dev)
1769 return; 1777 return;
1770 1778
1771 down_write(&em28xx_disconnect); 1779 em28xx_info("disconnecting %s\n", dev->vdev->name);
1772 1780
1781 /* wait until all current v4l2 io is finished then deallocate resources */
1773 mutex_lock(&dev->lock); 1782 mutex_lock(&dev->lock);
1774 1783
1775 em28xx_info("disconnecting %s\n", dev->vdev->name);
1776
1777 wake_up_interruptible_all(&dev->open); 1784 wake_up_interruptible_all(&dev->open);
1778 1785
1779 if (dev->users) { 1786 if (dev->users) {
@@ -1792,6 +1799,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
1792 em28xx_release_resources(dev); 1799 em28xx_release_resources(dev);
1793 } 1800 }
1794 1801
1802
1795 mutex_unlock(&dev->lock); 1803 mutex_unlock(&dev->lock);
1796 1804
1797 if (!dev->users) { 1805 if (!dev->users) {
@@ -1799,7 +1807,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
1799 kfree(dev); 1807 kfree(dev);
1800 } 1808 }
1801 1809
1802 up_write(&em28xx_disconnect);
1803} 1810}
1804 1811
1805static struct usb_driver em28xx_usb_driver = { 1812static struct usb_driver em28xx_usb_driver = {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 209f6f9d5581..65670ae2945b 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -265,7 +265,7 @@ struct em28xx {
265 enum em28xx_stream_state stream; 265 enum em28xx_stream_state stream;
266 enum em28xx_io_method io; 266 enum em28xx_io_method io;
267 /* locks */ 267 /* locks */
268 struct mutex lock, fileop_lock; 268 struct mutex lock;
269 spinlock_t queue_lock; 269 spinlock_t queue_lock;
270 struct list_head inqueue, outqueue; 270 struct list_head inqueue, outqueue;
271 wait_queue_head_t open, wait_frame, wait_stream; 271 wait_queue_head_t open, wait_frame, wait_stream;