aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-03-03 15:15:36 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-25 00:16:32 -0400
commit3bb1af5243d41af9518728445e9c9bd30dd47237 (patch)
tree83a82f0bb1ca4ab268b49a9d1e06548bb33e52ef
parent8f7f85e9f9561507b009d26395c53e70758695ec (diff)
USB: EHCI: carry out port handover during each root-hub resume
This patch (as1044) causes EHCI port handover for non-high-speed devices to occur during every root-hub resume, not just in cases where the controller lost power or was reset. This is necessary because: When some machines go into suspend, they remove power from on-board USB devices while retaining suspend current for USB controllers. The user might well unplug a USB device while the system is suspended and then plug it back in before resuming. A corresponding change is made to the core resume routine; now high-speed root hubs will always be resumed when the system wakes up, even if they were suspended before the system went to sleep. If this weren't done then EHCI port handover wouldn't work, since it is called when the EHCI root hub is resumed. Finally, a comment is added to the hub driver explaining the khubd has to be freezable; if it weren't frozen then it could interfere with port handover. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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;