diff options
author | Steve French <sfrench@us.ibm.com> | 2007-07-19 04:38:57 +0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-07-19 04:38:57 +0400 |
commit | 1ff8392c32a2645d2665ca779ecb91bb29361c13 (patch) | |
tree | 860b95e9a499ade4060848740fc6ce1fbb4e4e8d /drivers/usb/core/generic.c | |
parent | 70b315b0dd3879cb3ab8aadffb14f10b2d19b9c3 (diff) | |
parent | 5bae7ac9feba925fd0099057f6b23d7be80b7b41 (diff) | |
download | linux-1ff8392c32a2645d2665ca779ecb91bb29361c13.tar.xz |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
fs/cifs/export.c
Diffstat (limited to 'drivers/usb/core/generic.c')
-rw-r--r-- | drivers/usb/core/generic.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 9bbcb20e2d94..b2fc2b115256 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -19,6 +19,7 @@ #include <linux/usb.h> #include "usb.h" +#include "hcd.h" static inline const char *plural(int n) { @@ -193,16 +194,34 @@ 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). + int rc; + + /* Normal USB devices suspend through their upstream port. + * Root hubs don't have upstream ports to suspend, + * so we have to shut down their downstream HC-to-USB + * interfaces manually by doing a bus (or "global") suspend. */ - return usb_port_suspend(udev); + if (!udev->parent) + rc = hcd_bus_suspend(udev); + else + rc = usb_port_suspend(udev); + return rc; } static int generic_resume(struct usb_device *udev) { - return usb_port_resume(udev); + int rc; + + /* Normal USB devices resume/reset through their upstream port. + * Root hubs don't have upstream ports to resume or reset, + * so we have to start up their downstream HC-to-USB + * interfaces manually by doing a bus (or "global") resume. + */ + if (!udev->parent) + rc = hcd_bus_resume(udev); + else + rc = usb_port_resume(udev); + return rc; } #endif /* CONFIG_PM */ |