|
@@ -2039,8 +2039,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
|
|
|
status = hcd->driver->bus_resume(hcd);
|
|
|
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
|
|
|
if (status == 0) {
|
|
|
- /* TRSMRCY = 10 msec */
|
|
|
- msleep(10);
|
|
|
+ struct usb_device *udev;
|
|
|
+ int port1;
|
|
|
+
|
|
|
spin_lock_irq(&hcd_root_hub_lock);
|
|
|
if (!HCD_DEAD(hcd)) {
|
|
|
usb_set_device_state(rhdev, rhdev->actconfig
|
|
@@ -2050,6 +2051,20 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
|
|
|
hcd->state = HC_STATE_RUNNING;
|
|
|
}
|
|
|
spin_unlock_irq(&hcd_root_hub_lock);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check whether any of the enabled ports on the root hub are
|
|
|
+ * unsuspended. If they are then a TRSMRCY delay is needed
|
|
|
+ * (this is what the USB-2 spec calls a "global resume").
|
|
|
+ * Otherwise we can skip the delay.
|
|
|
+ */
|
|
|
+ usb_hub_for_each_child(rhdev, port1, udev) {
|
|
|
+ if (udev->state != USB_STATE_NOTATTACHED &&
|
|
|
+ !udev->port_is_suspended) {
|
|
|
+ usleep_range(10000, 11000); /* TRSMRCY */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
} else {
|
|
|
hcd->state = old_state;
|
|
|
dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
|