From 1467b595408ac678d4b03fbc57f42cce86e1f346 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sat, 27 Dec 2008 22:30:34 -0200 Subject: radio-mr800: correct unplug, fix to previous patch From: Alexey Klimov This patch corrects unplug procedure, that was implemented wrong in previous patch. New function usb_amradio_device_release added. Disconnect lock removed. Priority: high Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'linux/drivers/media/radio/radio-mr800.c') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index dbce57c26..ff0d5240c 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -142,7 +142,6 @@ struct amradio_device { unsigned char *buffer; struct mutex lock; /* buffer locking */ - struct mutex disconnect_lock; int curfreq; int stereo; int users; @@ -305,16 +304,12 @@ static void usb_amradio_disconnect(struct usb_interface *intf) { struct amradio_device *radio = usb_get_intfdata(intf); - mutex_lock(&radio->disconnect_lock); + mutex_lock(&radio->lock); radio->removed = 1; - usb_set_intfdata(intf, NULL); + mutex_unlock(&radio->lock); - if (radio->users == 0) { - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } - mutex_unlock(&radio->disconnect_lock); + usb_set_intfdata(intf, NULL); + video_unregister_device(radio->videodev); } /* vidioc_querycap - query device capabilities */ @@ -532,7 +527,7 @@ static int usb_amradio_open(struct inode *inode, struct file *file) return 0; } -/*close device - free driver structures */ +/*close device */ static int usb_amradio_close(struct inode *inode, struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); @@ -541,21 +536,15 @@ static int usb_amradio_close(struct inode *inode, struct file *file) if (!radio) return -ENODEV; - mutex_lock(&radio->disconnect_lock); radio->users = 0; - if (radio->removed) { - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } else { + if (!radio->removed) { retval = amradio_stop(radio); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); } - mutex_unlock(&radio->disconnect_lock); return 0; } @@ -612,12 +601,24 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; +static void usb_amradio_device_release(struct video_device *videodev) +{ + struct amradio_device *radio = video_get_drvdata(videodev); + + /* we call v4l to free radio->videodev */ + video_device_release(videodev); + + /* free rest memory */ + kfree(radio->buffer); + kfree(radio); +} + /* V4L2 interface */ static struct video_device amradio_videodev_template = { .name = "AverMedia MR 800 USB FM Radio", .fops = &usb_amradio_fops, .ioctl_ops = &usb_amradio_ioctl_ops, - .release = video_device_release, + .release = usb_amradio_device_release, }; /* check if the device is present and register with v4l and @@ -655,7 +656,6 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; - mutex_init(&radio->disconnect_lock); mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); -- cgit v1.2.3