Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / drivers / media / radio / radio-mr800.c
index 353b828..b540e80 100644 (file)
@@ -176,8 +176,6 @@ static int amradio_set_mute(struct amradio_device *radio, char argument)
        int retval;
        int size;
 
-       BUG_ON(!mutex_is_locked(&radio->lock));
-
        radio->buffer[0] = 0x00;
        radio->buffer[1] = 0x55;
        radio->buffer[2] = 0xaa;
@@ -207,8 +205,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
        int size;
        unsigned short freq_send = 0x10 + (freq >> 3) / 25;
 
-       BUG_ON(!mutex_is_locked(&radio->lock));
-
        radio->buffer[0] = 0x00;
        radio->buffer[1] = 0x55;
        radio->buffer[2] = 0xaa;
@@ -253,8 +249,6 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument)
        int retval;
        int size;
 
-       BUG_ON(!mutex_is_locked(&radio->lock));
-
        radio->buffer[0] = 0x00;
        radio->buffer[1] = 0x55;
        radio->buffer[2] = 0xaa;
@@ -290,11 +284,13 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
        struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
 
        mutex_lock(&radio->lock);
-       radio->usbdev = NULL;
-       mutex_unlock(&radio->lock);
-
+       /* increase the device node's refcount */
+       get_device(&radio->videodev.dev);
        v4l2_device_disconnect(&radio->v4l2_dev);
        video_unregister_device(&radio->videodev);
+       mutex_unlock(&radio->lock);
+       /* decrease the device node's refcount, allowing it to be released */
+       put_device(&radio->videodev.dev);
 }
 
 /* vidioc_querycap - query device capabilities */
@@ -503,28 +499,18 @@ out:
 static int usb_amradio_open(struct file *file)
 {
        struct amradio_device *radio = video_drvdata(file);
-       int retval = 0;
-
-       mutex_lock(&radio->lock);
-
-       if (!radio->usbdev) {
-               retval = -EIO;
-               goto unlock;
-       }
+       int retval;
 
        file->private_data = radio;
        retval = usb_autopm_get_interface(radio->intf);
        if (retval)
-               goto unlock;
+               return retval;
 
        if (unlikely(!radio->initialized)) {
                retval = usb_amradio_init(radio);
                if (retval)
                        usb_autopm_put_interface(radio->intf);
        }
-
-unlock:
-       mutex_unlock(&radio->lock);
        return retval;
 }
 
@@ -532,37 +518,10 @@ unlock:
 static int usb_amradio_close(struct file *file)
 {
        struct amradio_device *radio = file->private_data;
-       int retval = 0;
-
-       mutex_lock(&radio->lock);
 
-       if (!radio->usbdev)
-               retval = -EIO;
-       else
+       if (video_is_registered(&radio->videodev))
                usb_autopm_put_interface(radio->intf);
-
-       mutex_unlock(&radio->lock);
-       return retval;
-}
-
-static long usb_amradio_ioctl(struct file *file, unsigned int cmd,
-                               unsigned long arg)
-{
-       struct amradio_device *radio = file->private_data;
-       long retval = 0;
-
-       mutex_lock(&radio->lock);
-
-       if (!radio->usbdev) {
-               retval = -EIO;
-               goto unlock;
-       }
-
-       retval = video_ioctl2(file, cmd, arg);
-
-unlock:
-       mutex_unlock(&radio->lock);
-       return retval;
+       return 0;
 }
 
 /* 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)
        struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
 
        mutex_lock(&radio->lock);
-
        if (!radio->muted && radio->initialized) {
                amradio_set_mute(radio, AMRADIO_STOP);
                radio->muted = 0;
        }
+       mutex_unlock(&radio->lock);
 
        dev_info(&intf->dev, "going into suspend..\n");
-
-       mutex_unlock(&radio->lock);
        return 0;
 }
 
@@ -589,7 +546,6 @@ static int usb_amradio_resume(struct usb_interface *intf)
        struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
 
        mutex_lock(&radio->lock);
-
        if (unlikely(!radio->initialized))
                goto unlock;
 
@@ -604,9 +560,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
                amradio_set_mute(radio, AMRADIO_START);
 
 unlock:
-       dev_info(&intf->dev, "coming out of suspend..\n");
-
        mutex_unlock(&radio->lock);
+
+       dev_info(&intf->dev, "coming out of suspend..\n");
        return 0;
 }
 
@@ -615,7 +571,7 @@ static const struct v4l2_file_operations usb_amradio_fops = {
        .owner          = THIS_MODULE,
        .open           = usb_amradio_open,
        .release        = usb_amradio_close,
-       .ioctl          = usb_amradio_ioctl,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
@@ -671,19 +627,20 @@ static int usb_amradio_probe(struct usb_interface *intf,
                goto err_v4l2;
        }
 
+       mutex_init(&radio->lock);
+
        strlcpy(radio->videodev.name, radio->v4l2_dev.name,
                sizeof(radio->videodev.name));
        radio->videodev.v4l2_dev = &radio->v4l2_dev;
        radio->videodev.fops = &usb_amradio_fops;
        radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops;
        radio->videodev.release = usb_amradio_video_device_release;
+       radio->videodev.lock = &radio->lock;
 
        radio->usbdev = interface_to_usbdev(intf);
        radio->intf = intf;
        radio->curfreq = 95.16 * FREQ_MUL;
 
-       mutex_init(&radio->lock);
-
        video_set_drvdata(&radio->videodev, radio);
 
        retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,