autosuspend for radio-mr800 driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

this patch should cleanup suspend/resume support and add autosuspend
support. Could you test this?

	Regards
		Oliver

--

commit 57375ad73388fd944d7447ddb3e1e56eb48ba421
Author: Oliver Neukum <oneukum@linux-d698.(none)>
Date:   Thu Jul 2 20:03:02 2009 +0200

    usb: autosuspend for radio-mr800 driver

diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 837467f..496c9cf 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -123,11 +123,13 @@ static int usb_amradio_close(struct file *file);
 static int usb_amradio_suspend(struct usb_interface *intf,
 				pm_message_t message);
 static int usb_amradio_resume(struct usb_interface *intf);
+static int usb_amradio_reset_resume(struct usb_interface *intf);
 
 /* Data for one (physical) device */
 struct amradio_device {
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
+	struct usb_interface *intf;
 	struct video_device *videodev;
 	struct v4l2_device v4l2_dev;
 
@@ -156,9 +158,9 @@ static struct usb_driver usb_amradio_driver = {
 	.disconnect		= usb_amradio_disconnect,
 	.suspend		= usb_amradio_suspend,
 	.resume			= usb_amradio_resume,
-	.reset_resume		= usb_amradio_resume,
+	.reset_resume		= usb_amradio_reset_resume,
 	.id_table		= usb_amradio_device_table,
-	.supports_autosuspend	= 0,
+	.supports_autosuspend	= 1,
 };
 
 /* switch on/off the radio. Send 8 bytes to device */
@@ -541,13 +543,15 @@ static int usb_amradio_open(struct file *file)
 	radio->users = 1;
 	radio->muted = 1;
 
+	retval = usb_autopm_get_interface(radio->intf);
+	if (retval < 0)
+		goto err_out;
+
 	retval = amradio_set_mute(radio, AMRADIO_START);
 	if (retval < 0) {
 		amradio_dev_warn(&radio->videodev->dev,
-			"radio did not start up properly\n");
-		radio->users = 0;
-		unlock_kernel();
-		return -EIO;
+			"radio did not wake up\n");
+		goto err_out_pm;
 	}
 
 	retval = amradio_set_stereo(radio, WANT_STEREO);
@@ -562,6 +566,15 @@ static int usb_amradio_open(struct file *file)
 
 	unlock_kernel();
 	return 0;
+
+err_out_pm:
+	amradio_dev_warn(&radio->videodev->dev,
+		"radio did not start up properly\n");
+	usb_autopm_put_interface(radio->intf);
+err_out:
+	radio->users = 0;
+	unlock_kernel();
+	return -EIO;
 }
 
 /*close device */
@@ -582,6 +595,7 @@ static int usb_amradio_close(struct file *file)
 		if (retval < 0)
 			amradio_dev_warn(&radio->videodev->dev,
 				"amradio_stop failed\n");
+		usb_autopm_put_interface(radio->intf);
 	}
 
 	return 0;
@@ -591,30 +605,45 @@ static int usb_amradio_close(struct file *file)
 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
+	int retval = 0;
 
 	retval = amradio_set_mute(radio, AMRADIO_STOP);
 	if (retval < 0)
 		dev_warn(&intf->dev, "amradio_stop failed\n");
+	else
+		dev_info(&intf->dev, "going into suspend..\n");
 
-	dev_info(&intf->dev, "going into suspend..\n");
-
-	return 0;
+	return retval;
 }
 
-/* Resume device - start device. Need to be checked and fixed */
 static int usb_amradio_resume(struct usb_interface *intf)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
+	int retval = 0;
 
-	retval = amradio_set_mute(radio, AMRADIO_START);
-	if (retval < 0)
-		dev_warn(&intf->dev, "amradio_start failed\n");
+	if (radio->users) {
+		retval = amradio_set_mute(radio, AMRADIO_START);
+		if (retval < 0)
+			dev_warn(&intf->dev, "amradio_start failed\n");
+	}
 
 	dev_info(&intf->dev, "coming out of suspend..\n");
 
-	return 0;
+	return retval;
+}
+
+static int usb_amradio_reset_resume(struct usb_interface *intf)	
+{
+	struct amradio_device *radio = usb_get_intfdata(intf);
+	int retval = 0;
+
+	if (radio->users) {
+		retval = amradio_set_stereo(radio, WANT_STEREO);
+		if (!retval)
+			retval = usb_amradio_resume(intf);
+	}
+
+	return retval;
 }
 
 /* File system interface */
@@ -669,6 +698,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
 		return -ENOMEM;
 	}
 
+	radio->intf = intf;
 	radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
 
 	if (!radio->buffer) {

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux