diff options
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 185721dba42b..6bf909e1adf0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -299,6 +299,19 @@ static void ehci_watchdog (unsigned long param) | |||
299 | spin_unlock_irqrestore (&ehci->lock, flags); | 299 | spin_unlock_irqrestore (&ehci->lock, flags); |
300 | } | 300 | } |
301 | 301 | ||
302 | /* On some systems, leaving remote wakeup enabled prevents system shutdown. | ||
303 | * The firmware seems to think that powering off is a wakeup event! | ||
304 | * This routine turns off remote wakeup and everything else, on all ports. | ||
305 | */ | ||
306 | static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) | ||
307 | { | ||
308 | int port = HCS_N_PORTS(ehci->hcs_params); | ||
309 | |||
310 | while (port--) | ||
311 | ehci_writel(ehci, PORT_RWC_BITS, | ||
312 | &ehci->regs->port_status[port]); | ||
313 | } | ||
314 | |||
302 | /* ehci_shutdown kick in for silicon on any bus (not just pci, etc). | 315 | /* ehci_shutdown kick in for silicon on any bus (not just pci, etc). |
303 | * This forcibly disables dma and IRQs, helping kexec and other cases | 316 | * This forcibly disables dma and IRQs, helping kexec and other cases |
304 | * where the next system software may expect clean state. | 317 | * where the next system software may expect clean state. |
@@ -310,9 +323,13 @@ ehci_shutdown (struct usb_hcd *hcd) | |||
310 | 323 | ||
311 | ehci = hcd_to_ehci (hcd); | 324 | ehci = hcd_to_ehci (hcd); |
312 | (void) ehci_halt (ehci); | 325 | (void) ehci_halt (ehci); |
326 | ehci_turn_off_all_ports(ehci); | ||
313 | 327 | ||
314 | /* make BIOS/etc use companion controller during reboot */ | 328 | /* make BIOS/etc use companion controller during reboot */ |
315 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); | 329 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
330 | |||
331 | /* unblock posted writes */ | ||
332 | ehci_readl(ehci, &ehci->regs->configured_flag); | ||
316 | } | 333 | } |
317 | 334 | ||
318 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | 335 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) |