aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/host/ehci-hub.c4
-rw-r--r--drivers/usb/host/ehci-pci.c1
4 files changed, 14 insertions, 6 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 801b6f142fa7..ebccdefcc6f2 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1523,9 +1523,14 @@ static int usb_suspend(struct device *dev, pm_message_t message)
1523 udev = to_usb_device(dev); 1523 udev = to_usb_device(dev);
1524 1524
1525 /* If udev is already suspended, we can skip this suspend and 1525 /* If udev is already suspended, we can skip this suspend and
1526 * we should also skip the upcoming system resume. */ 1526 * we should also skip the upcoming system resume. High-speed
1527 * root hubs are an exception; they need to resume whenever the
1528 * system wakes up in order for USB-PERSIST port handover to work
1529 * properly.
1530 */
1527 if (udev->state == USB_STATE_SUSPENDED) { 1531 if (udev->state == USB_STATE_SUSPENDED) {
1528 udev->skip_sys_resume = 1; 1532 if (udev->parent || udev->speed != USB_SPEED_HIGH)
1533 udev->skip_sys_resume = 1;
1529 return 0; 1534 return 0;
1530 } 1535 }
1531 1536
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 57aeca160f38..a42db75c2336 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2890,7 +2890,13 @@ loop:
2890 2890
2891static int hub_thread(void *__unused) 2891static int hub_thread(void *__unused)
2892{ 2892{
2893 /* khubd needs to be freezable to avoid intefering with USB-PERSIST
2894 * port handover. Otherwise it might see that a full-speed device
2895 * was gone before the EHCI controller had handed its port over to
2896 * the companion full-speed controller.
2897 */
2893 set_freezable(); 2898 set_freezable();
2899
2894 do { 2900 do {
2895 hub_events(); 2901 hub_events();
2896 wait_event_freezable(khubd_wait, 2902 wait_event_freezable(khubd_wait,
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 4e065e556e4b..8d513a15d0cd 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -281,9 +281,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
281 ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); 281 ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
282 282
283 spin_unlock_irq (&ehci->lock); 283 spin_unlock_irq (&ehci->lock);
284 284 ehci_handover_companion_ports(ehci);
285 if (!power_okay)
286 ehci_handover_companion_ports(ehci);
287 return 0; 285 return 0;
288} 286}
289 287
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 72ccd56e36dd..040bd8632eb3 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -329,7 +329,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
329 329
330 /* here we "know" root ports should always stay powered */ 330 /* here we "know" root ports should always stay powered */
331 ehci_port_power(ehci, 1); 331 ehci_port_power(ehci, 1);
332 ehci_handover_companion_ports(ehci);
333 332
334 hcd->state = HC_STATE_SUSPENDED; 333 hcd->state = HC_STATE_SUSPENDED;
335 return 0; 334 return 0;