aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-hcd.c17
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 */
306static 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
318static void ehci_port_power (struct ehci_hcd *ehci, int is_on) 335static void ehci_port_power (struct ehci_hcd *ehci, int is_on)