V4L/DVB (9539): dsbr100: add suspend and resume
Alexey Klimov [Sat, 8 Nov 2008 03:40:46 +0000 (00:40 -0300)]
This patch adds support for suspend and resume methods in driver.
Without this kradio and gnomeradio crashes during resume.
Also .supports_autosuspend in usb_driver struct set equal to 0 to avoid
suspending of module if usb_autosuspend enabled.

Signed-off-by: Alexey Klimov <klimov.linux@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

drivers/media/radio/dsbr100.c

index a5ca176..e6485cf 100644 (file)
@@ -131,6 +131,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
 static void usb_dsbr100_disconnect(struct usb_interface *intf);
 static int usb_dsbr100_open(struct inode *inode, struct file *file);
 static int usb_dsbr100_close(struct inode *inode, struct file *file);
+static int usb_dsbr100_suspend(struct usb_interface *intf,
+                                               pm_message_t message);
+static int usb_dsbr100_resume(struct usb_interface *intf);
 
 static int radio_nr = -1;
 module_param(radio_nr, int, 0);
@@ -157,10 +160,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
 
 /* USB subsystem interface */
 static struct usb_driver usb_dsbr100_driver = {
-       .name =         "dsbr100",
-       .probe =        usb_dsbr100_probe,
-       .disconnect =   usb_dsbr100_disconnect,
-       .id_table =     usb_dsbr100_device_table,
+       .name                   = "dsbr100",
+       .probe                  = usb_dsbr100_probe,
+       .disconnect             = usb_dsbr100_disconnect,
+       .id_table               = usb_dsbr100_device_table,
+       .suspend                = usb_dsbr100_suspend,
+       .resume                 = usb_dsbr100_resume,
+       .reset_resume           = usb_dsbr100_resume,
+       .supports_autosuspend   = 0,
 };
 
 /* Low-level device interface begins here */
@@ -448,6 +455,36 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
        return 0;
 }
 
+/* Suspend device - stop device. */
+static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct dsbr100_device *radio = usb_get_intfdata(intf);
+       int retval;
+
+       retval = dsbr100_stop(radio);
+       if (retval == -1)
+               dev_warn(&intf->dev, "dsbr100_stop failed\n");
+
+       dev_info(&intf->dev, "going into suspend..\n");
+
+       return 0;
+}
+
+/* Resume device - start device. */
+static int usb_dsbr100_resume(struct usb_interface *intf)
+{
+       struct dsbr100_device *radio = usb_get_intfdata(intf);
+       int retval;
+
+       retval = dsbr100_start(radio);
+       if (retval == -1)
+               dev_warn(&intf->dev, "dsbr100_start failed\n");
+
+       dev_info(&intf->dev, "coming out of suspend..\n");
+
+       return 0;
+}
+
 /* File system interface */
 static const struct file_operations usb_dsbr100_fops = {
        .owner          = THIS_MODULE,