diff options
Diffstat (limited to 'drivers/media/radio/radio-mr800.c')
-rw-r--r-- | drivers/media/radio/radio-mr800.c | 75 |
1 files changed, 16 insertions, 59 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 353b82855949..b540e8072e92 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -176,8 +176,6 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) | |||
176 | int retval; | 176 | int retval; |
177 | int size; | 177 | int size; |
178 | 178 | ||
179 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
180 | |||
181 | radio->buffer[0] = 0x00; | 179 | radio->buffer[0] = 0x00; |
182 | radio->buffer[1] = 0x55; | 180 | radio->buffer[1] = 0x55; |
183 | radio->buffer[2] = 0xaa; | 181 | radio->buffer[2] = 0xaa; |
@@ -207,8 +205,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) | |||
207 | int size; | 205 | int size; |
208 | unsigned short freq_send = 0x10 + (freq >> 3) / 25; | 206 | unsigned short freq_send = 0x10 + (freq >> 3) / 25; |
209 | 207 | ||
210 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
211 | |||
212 | radio->buffer[0] = 0x00; | 208 | radio->buffer[0] = 0x00; |
213 | radio->buffer[1] = 0x55; | 209 | radio->buffer[1] = 0x55; |
214 | radio->buffer[2] = 0xaa; | 210 | radio->buffer[2] = 0xaa; |
@@ -253,8 +249,6 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) | |||
253 | int retval; | 249 | int retval; |
254 | int size; | 250 | int size; |
255 | 251 | ||
256 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
257 | |||
258 | radio->buffer[0] = 0x00; | 252 | radio->buffer[0] = 0x00; |
259 | radio->buffer[1] = 0x55; | 253 | radio->buffer[1] = 0x55; |
260 | radio->buffer[2] = 0xaa; | 254 | radio->buffer[2] = 0xaa; |
@@ -290,11 +284,13 @@ static void usb_amradio_disconnect(struct usb_interface *intf) | |||
290 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 284 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
291 | 285 | ||
292 | mutex_lock(&radio->lock); | 286 | mutex_lock(&radio->lock); |
293 | radio->usbdev = NULL; | 287 | /* increase the device node's refcount */ |
294 | mutex_unlock(&radio->lock); | 288 | get_device(&radio->videodev.dev); |
295 | |||
296 | v4l2_device_disconnect(&radio->v4l2_dev); | 289 | v4l2_device_disconnect(&radio->v4l2_dev); |
297 | video_unregister_device(&radio->videodev); | 290 | video_unregister_device(&radio->videodev); |
291 | mutex_unlock(&radio->lock); | ||
292 | /* decrease the device node's refcount, allowing it to be released */ | ||
293 | put_device(&radio->videodev.dev); | ||
298 | } | 294 | } |
299 | 295 | ||
300 | /* vidioc_querycap - query device capabilities */ | 296 | /* vidioc_querycap - query device capabilities */ |
@@ -503,28 +499,18 @@ out: | |||
503 | static int usb_amradio_open(struct file *file) | 499 | static int usb_amradio_open(struct file *file) |
504 | { | 500 | { |
505 | struct amradio_device *radio = video_drvdata(file); | 501 | struct amradio_device *radio = video_drvdata(file); |
506 | int retval = 0; | 502 | int retval; |
507 | |||
508 | mutex_lock(&radio->lock); | ||
509 | |||
510 | if (!radio->usbdev) { | ||
511 | retval = -EIO; | ||
512 | goto unlock; | ||
513 | } | ||
514 | 503 | ||
515 | file->private_data = radio; | 504 | file->private_data = radio; |
516 | retval = usb_autopm_get_interface(radio->intf); | 505 | retval = usb_autopm_get_interface(radio->intf); |
517 | if (retval) | 506 | if (retval) |
518 | goto unlock; | 507 | return retval; |
519 | 508 | ||
520 | if (unlikely(!radio->initialized)) { | 509 | if (unlikely(!radio->initialized)) { |
521 | retval = usb_amradio_init(radio); | 510 | retval = usb_amradio_init(radio); |
522 | if (retval) | 511 | if (retval) |
523 | usb_autopm_put_interface(radio->intf); | 512 | usb_autopm_put_interface(radio->intf); |
524 | } | 513 | } |
525 | |||
526 | unlock: | ||
527 | mutex_unlock(&radio->lock); | ||
528 | return retval; | 514 | return retval; |
529 | } | 515 | } |
530 | 516 | ||
@@ -532,37 +518,10 @@ unlock: | |||
532 | static int usb_amradio_close(struct file *file) | 518 | static int usb_amradio_close(struct file *file) |
533 | { | 519 | { |
534 | struct amradio_device *radio = file->private_data; | 520 | struct amradio_device *radio = file->private_data; |
535 | int retval = 0; | ||
536 | |||
537 | mutex_lock(&radio->lock); | ||
538 | 521 | ||
539 | if (!radio->usbdev) | 522 | if (video_is_registered(&radio->videodev)) |
540 | retval = -EIO; | ||
541 | else | ||
542 | usb_autopm_put_interface(radio->intf); | 523 | usb_autopm_put_interface(radio->intf); |
543 | 524 | return 0; | |
544 | mutex_unlock(&radio->lock); | ||
545 | return retval; | ||
546 | } | ||
547 | |||
548 | static long usb_amradio_ioctl(struct file *file, unsigned int cmd, | ||
549 | unsigned long arg) | ||
550 | { | ||
551 | struct amradio_device *radio = file->private_data; | ||
552 | long retval = 0; | ||
553 | |||
554 | mutex_lock(&radio->lock); | ||
555 | |||
556 | if (!radio->usbdev) { | ||
557 | retval = -EIO; | ||
558 | goto unlock; | ||
559 | } | ||
560 | |||
561 | retval = video_ioctl2(file, cmd, arg); | ||
562 | |||
563 | unlock: | ||
564 | mutex_unlock(&radio->lock); | ||
565 | return retval; | ||
566 | } | 525 | } |
567 | 526 | ||
568 | /* Suspend device - stop device. Need to be checked and fixed */ | 527 | /* Suspend device - stop device. Need to be checked and fixed */ |
@@ -571,15 +530,13 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) | |||
571 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 530 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
572 | 531 | ||
573 | mutex_lock(&radio->lock); | 532 | mutex_lock(&radio->lock); |
574 | |||
575 | if (!radio->muted && radio->initialized) { | 533 | if (!radio->muted && radio->initialized) { |
576 | amradio_set_mute(radio, AMRADIO_STOP); | 534 | amradio_set_mute(radio, AMRADIO_STOP); |
577 | radio->muted = 0; | 535 | radio->muted = 0; |
578 | } | 536 | } |
537 | mutex_unlock(&radio->lock); | ||
579 | 538 | ||
580 | dev_info(&intf->dev, "going into suspend..\n"); | 539 | dev_info(&intf->dev, "going into suspend..\n"); |
581 | |||
582 | mutex_unlock(&radio->lock); | ||
583 | return 0; | 540 | return 0; |
584 | } | 541 | } |
585 | 542 | ||
@@ -589,7 +546,6 @@ static int usb_amradio_resume(struct usb_interface *intf) | |||
589 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 546 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
590 | 547 | ||
591 | mutex_lock(&radio->lock); | 548 | mutex_lock(&radio->lock); |
592 | |||
593 | if (unlikely(!radio->initialized)) | 549 | if (unlikely(!radio->initialized)) |
594 | goto unlock; | 550 | goto unlock; |
595 | 551 | ||
@@ -604,9 +560,9 @@ static int usb_amradio_resume(struct usb_interface *intf) | |||
604 | amradio_set_mute(radio, AMRADIO_START); | 560 | amradio_set_mute(radio, AMRADIO_START); |
605 | 561 | ||
606 | unlock: | 562 | unlock: |
607 | dev_info(&intf->dev, "coming out of suspend..\n"); | ||
608 | |||
609 | mutex_unlock(&radio->lock); | 563 | mutex_unlock(&radio->lock); |
564 | |||
565 | dev_info(&intf->dev, "coming out of suspend..\n"); | ||
610 | return 0; | 566 | return 0; |
611 | } | 567 | } |
612 | 568 | ||
@@ -615,7 +571,7 @@ static const struct v4l2_file_operations usb_amradio_fops = { | |||
615 | .owner = THIS_MODULE, | 571 | .owner = THIS_MODULE, |
616 | .open = usb_amradio_open, | 572 | .open = usb_amradio_open, |
617 | .release = usb_amradio_close, | 573 | .release = usb_amradio_close, |
618 | .ioctl = usb_amradio_ioctl, | 574 | .unlocked_ioctl = video_ioctl2, |
619 | }; | 575 | }; |
620 | 576 | ||
621 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { | 577 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { |
@@ -671,19 +627,20 @@ static int usb_amradio_probe(struct usb_interface *intf, | |||
671 | goto err_v4l2; | 627 | goto err_v4l2; |
672 | } | 628 | } |
673 | 629 | ||
630 | mutex_init(&radio->lock); | ||
631 | |||
674 | strlcpy(radio->videodev.name, radio->v4l2_dev.name, | 632 | strlcpy(radio->videodev.name, radio->v4l2_dev.name, |
675 | sizeof(radio->videodev.name)); | 633 | sizeof(radio->videodev.name)); |
676 | radio->videodev.v4l2_dev = &radio->v4l2_dev; | 634 | radio->videodev.v4l2_dev = &radio->v4l2_dev; |
677 | radio->videodev.fops = &usb_amradio_fops; | 635 | radio->videodev.fops = &usb_amradio_fops; |
678 | radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; | 636 | radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; |
679 | radio->videodev.release = usb_amradio_video_device_release; | 637 | radio->videodev.release = usb_amradio_video_device_release; |
638 | radio->videodev.lock = &radio->lock; | ||
680 | 639 | ||
681 | radio->usbdev = interface_to_usbdev(intf); | 640 | radio->usbdev = interface_to_usbdev(intf); |
682 | radio->intf = intf; | 641 | radio->intf = intf; |
683 | radio->curfreq = 95.16 * FREQ_MUL; | 642 | radio->curfreq = 95.16 * FREQ_MUL; |
684 | 643 | ||
685 | mutex_init(&radio->lock); | ||
686 | |||
687 | video_set_drvdata(&radio->videodev, radio); | 644 | video_set_drvdata(&radio->videodev, radio); |
688 | 645 | ||
689 | retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, | 646 | retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, |