aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 1e36dbb48366..6e0d886bcce5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -730,6 +730,9 @@ void xhci_shutdown(struct usb_hcd *hcd)
730 730
731 spin_lock_irq(&xhci->lock); 731 spin_lock_irq(&xhci->lock);
732 xhci_halt(xhci); 732 xhci_halt(xhci);
733 /* Workaround for spurious wakeups at shutdown with HSW */
734 if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
735 xhci_reset(xhci);
733 spin_unlock_irq(&xhci->lock); 736 spin_unlock_irq(&xhci->lock);
734 737
735 xhci_cleanup_msix(xhci); 738 xhci_cleanup_msix(xhci);
@@ -737,6 +740,10 @@ void xhci_shutdown(struct usb_hcd *hcd)
737 xhci_dbg_trace(xhci, trace_xhci_dbg_init, 740 xhci_dbg_trace(xhci, trace_xhci_dbg_init,
738 "xhci_shutdown completed - status = %x", 741 "xhci_shutdown completed - status = %x",
739 xhci_readl(xhci, &xhci->op_regs->status)); 742 xhci_readl(xhci, &xhci->op_regs->status));
743
744 /* Yet another workaround for spurious wakeups at shutdown with HSW */
745 if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
746 pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
740} 747}
741 748
742#ifdef CONFIG_PM 749#ifdef CONFIG_PM
@@ -839,6 +846,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
839int xhci_suspend(struct xhci_hcd *xhci) 846int xhci_suspend(struct xhci_hcd *xhci)
840{ 847{
841 int rc = 0; 848 int rc = 0;
849 unsigned int delay = XHCI_MAX_HALT_USEC;
842 struct usb_hcd *hcd = xhci_to_hcd(xhci); 850 struct usb_hcd *hcd = xhci_to_hcd(xhci);
843 u32 command; 851 u32 command;
844 852
@@ -861,8 +869,12 @@ int xhci_suspend(struct xhci_hcd *xhci)
861 command = xhci_readl(xhci, &xhci->op_regs->command); 869 command = xhci_readl(xhci, &xhci->op_regs->command);
862 command &= ~CMD_RUN; 870 command &= ~CMD_RUN;
863 xhci_writel(xhci, command, &xhci->op_regs->command); 871 xhci_writel(xhci, command, &xhci->op_regs->command);
872
873 /* Some chips from Fresco Logic need an extraordinary delay */
874 delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
875
864 if (xhci_handshake(xhci, &xhci->op_regs->status, 876 if (xhci_handshake(xhci, &xhci->op_regs->status,
865 STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { 877 STS_HALT, STS_HALT, delay)) {
866 xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); 878 xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
867 spin_unlock_irq(&xhci->lock); 879 spin_unlock_irq(&xhci->lock);
868 return -ETIMEDOUT; 880 return -ETIMEDOUT;