]> err.no Git - linux-2.6/commitdiff
USB: Implement PM FREEZE and PRETHAW
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 4 May 2007 15:51:25 +0000 (11:51 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 12 Jul 2007 23:29:46 +0000 (16:29 -0700)
This patch (as884) finally implements the time-saving semantics
possible with the Power Management FREEZE and PRETHAW events.  Their
proper handling requires only that devices be quiesced, with
interrupts and DMA turned off; non-root USB devices don't actually
need to be put in a suspended state.  The patch checks and avoids
doing the suspend call when possible.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/driver.c
drivers/usb/core/generic.c

index 38c3dd2a44e092515fc9fbbd2fa68d3416f66dda..63d47946e3dbac5025f1f4f3efe4a9f0610d1dc9 100644 (file)
@@ -1050,8 +1050,15 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                                break;
                }
        }
-       if (status == 0)
+       if (status == 0) {
+
+               /* Non-root devices don't need to do anything for FREEZE
+                * or PRETHAW. */
+               if (udev->parent && (msg.event == PM_EVENT_FREEZE ||
+                               msg.event == PM_EVENT_PRETHAW))
+                       goto done;
                status = usb_suspend_device(udev, msg);
+       }
 
        /* If the suspend failed, resume interfaces that did get suspended */
        if (status != 0) {
index 9bbcb20e2d94c3bf5ca96f77d0c1050d87d14eb2..e7ec9b6b7a9323f18939f4fadbc9e6b45d81100a 100644 (file)
@@ -193,10 +193,6 @@ static void generic_disconnect(struct usb_device *udev)
 
 static int generic_suspend(struct usb_device *udev, pm_message_t msg)
 {
-       /* USB devices enter SUSPEND state through their hubs, but can be
-        * marked for FREEZE as soon as their children are already idled.
-        * But those semantics are useless, so we equate the two (sigh).
-        */
        return usb_port_suspend(udev);
 }