aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/driver.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-02-12 12:21:11 +0100
committerRafael J. Wysocki <rjw@sisk.pl>2010-02-26 20:39:12 +0100
commit6d19c009cc780c63de25a046509ebc9473809fd6 (patch)
treed3a6186a5b3b2cd75a5778ba355ea9c3c7823a6c /drivers/usb/core/driver.c
parenta1e4d72cd3024999bfb6703092ea271438805c89 (diff)
downloadkernel_samsung_smdk4412-6d19c009cc780c63de25a046509ebc9473809fd6.zip
kernel_samsung_smdk4412-6d19c009cc780c63de25a046509ebc9473809fd6.tar.gz
kernel_samsung_smdk4412-6d19c009cc780c63de25a046509ebc9473809fd6.tar.bz2
USB: implement non-tree resume ordering constraints for PCI host controllers
This patch (as1331) adds non-tree ordering constraints needed for proper resume of PCI USB host controllers from hibernation. The main issue is that non-high-speed devices must not be resumed before the high-speed root hub, because it is the ehci_bus_resume() routine which takes care of handing the device connection over to the companion controller. If the device resume is attempted before the handover then the device won't be found and it will be treated as though it had disconnected. The patch adds a new field to the usb_bus structure; for each full/low-speed bus this field will contain a pointer to the companion high-speed bus (if one exists). It is used during normal device resume; if the hs_companion pointer isn't NULL then we wait for the root-hub device on the hs_companion bus. A secondary issue is that an EHCI controlller shouldn't be resumed before any of its companions. On some machines I have observed handovers failing if the companion controller is reinitialized after the handover. Thus, the EHCI resume routine must wait for the companion controllers to be resumed. The patch also fixes a small bug in usb_hcd_pci_probe(); an error path jumps to the wrong label, causing a memory leak. [rjw: Fixed compilation for CONFIG_PM_SLEEP unset.] Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r--drivers/usb/core/driver.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 60a45f1..f2f055e 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1022,6 +1022,14 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
goto done;
}
+ /* Non-root devices on a full/low-speed bus must wait for their
+ * companion high-speed root hub, in case a handoff is needed.
+ */
+ if (!(msg.event & PM_EVENT_AUTO) && udev->parent &&
+ udev->bus->hs_companion)
+ device_pm_wait_for_dev(&udev->dev,
+ &udev->bus->hs_companion->root_hub->dev);
+
if (udev->quirks & USB_QUIRK_RESET_RESUME)
udev->reset_resume = 1;