diff options
Diffstat (limited to 'drivers/media/radio/radio-mr800.c')
-rw-r--r-- | drivers/media/radio/radio-mr800.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 7b7a1cfb121d..bb68148b2b6d 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -141,7 +141,6 @@ struct amradio_device { | |||
141 | 141 | ||
142 | unsigned char *buffer; | 142 | unsigned char *buffer; |
143 | struct mutex lock; /* buffer locking */ | 143 | struct mutex lock; /* buffer locking */ |
144 | struct mutex disconnect_lock; | ||
145 | int curfreq; | 144 | int curfreq; |
146 | int stereo; | 145 | int stereo; |
147 | int users; | 146 | int users; |
@@ -302,16 +301,12 @@ static void usb_amradio_disconnect(struct usb_interface *intf) | |||
302 | { | 301 | { |
303 | struct amradio_device *radio = usb_get_intfdata(intf); | 302 | struct amradio_device *radio = usb_get_intfdata(intf); |
304 | 303 | ||
305 | mutex_lock(&radio->disconnect_lock); | 304 | mutex_lock(&radio->lock); |
306 | radio->removed = 1; | 305 | radio->removed = 1; |
307 | usb_set_intfdata(intf, NULL); | 306 | mutex_unlock(&radio->lock); |
308 | 307 | ||
309 | if (radio->users == 0) { | 308 | usb_set_intfdata(intf, NULL); |
310 | video_unregister_device(radio->videodev); | 309 | video_unregister_device(radio->videodev); |
311 | kfree(radio->buffer); | ||
312 | kfree(radio); | ||
313 | } | ||
314 | mutex_unlock(&radio->disconnect_lock); | ||
315 | } | 310 | } |
316 | 311 | ||
317 | /* vidioc_querycap - query device capabilities */ | 312 | /* vidioc_querycap - query device capabilities */ |
@@ -529,7 +524,7 @@ static int usb_amradio_open(struct inode *inode, struct file *file) | |||
529 | return 0; | 524 | return 0; |
530 | } | 525 | } |
531 | 526 | ||
532 | /*close device - free driver structures */ | 527 | /*close device */ |
533 | static int usb_amradio_close(struct inode *inode, struct file *file) | 528 | static int usb_amradio_close(struct inode *inode, struct file *file) |
534 | { | 529 | { |
535 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); | 530 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); |
@@ -538,21 +533,15 @@ static int usb_amradio_close(struct inode *inode, struct file *file) | |||
538 | if (!radio) | 533 | if (!radio) |
539 | return -ENODEV; | 534 | return -ENODEV; |
540 | 535 | ||
541 | mutex_lock(&radio->disconnect_lock); | ||
542 | radio->users = 0; | 536 | radio->users = 0; |
543 | if (radio->removed) { | ||
544 | video_unregister_device(radio->videodev); | ||
545 | kfree(radio->buffer); | ||
546 | kfree(radio); | ||
547 | 537 | ||
548 | } else { | 538 | if (!radio->removed) { |
549 | retval = amradio_stop(radio); | 539 | retval = amradio_stop(radio); |
550 | if (retval < 0) | 540 | if (retval < 0) |
551 | amradio_dev_warn(&radio->videodev->dev, | 541 | amradio_dev_warn(&radio->videodev->dev, |
552 | "amradio_stop failed\n"); | 542 | "amradio_stop failed\n"); |
553 | } | 543 | } |
554 | 544 | ||
555 | mutex_unlock(&radio->disconnect_lock); | ||
556 | return 0; | 545 | return 0; |
557 | } | 546 | } |
558 | 547 | ||
@@ -609,12 +598,24 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { | |||
609 | .vidioc_s_input = vidioc_s_input, | 598 | .vidioc_s_input = vidioc_s_input, |
610 | }; | 599 | }; |
611 | 600 | ||
601 | static void usb_amradio_device_release(struct video_device *videodev) | ||
602 | { | ||
603 | struct amradio_device *radio = video_get_drvdata(videodev); | ||
604 | |||
605 | /* we call v4l to free radio->videodev */ | ||
606 | video_device_release(videodev); | ||
607 | |||
608 | /* free rest memory */ | ||
609 | kfree(radio->buffer); | ||
610 | kfree(radio); | ||
611 | } | ||
612 | |||
612 | /* V4L2 interface */ | 613 | /* V4L2 interface */ |
613 | static struct video_device amradio_videodev_template = { | 614 | static struct video_device amradio_videodev_template = { |
614 | .name = "AverMedia MR 800 USB FM Radio", | 615 | .name = "AverMedia MR 800 USB FM Radio", |
615 | .fops = &usb_amradio_fops, | 616 | .fops = &usb_amradio_fops, |
616 | .ioctl_ops = &usb_amradio_ioctl_ops, | 617 | .ioctl_ops = &usb_amradio_ioctl_ops, |
617 | .release = video_device_release, | 618 | .release = usb_amradio_device_release, |
618 | }; | 619 | }; |
619 | 620 | ||
620 | /* check if the device is present and register with v4l and | 621 | /* check if the device is present and register with v4l and |
@@ -652,7 +653,6 @@ static int usb_amradio_probe(struct usb_interface *intf, | |||
652 | radio->usbdev = interface_to_usbdev(intf); | 653 | radio->usbdev = interface_to_usbdev(intf); |
653 | radio->curfreq = 95.16 * FREQ_MUL; | 654 | radio->curfreq = 95.16 * FREQ_MUL; |
654 | 655 | ||
655 | mutex_init(&radio->disconnect_lock); | ||
656 | mutex_init(&radio->lock); | 656 | mutex_init(&radio->lock); |
657 | 657 | ||
658 | video_set_drvdata(radio->videodev, radio); | 658 | video_set_drvdata(radio->videodev, radio); |