diff options
| -rw-r--r-- | drivers/usb/host/xhci-pci.c | 17 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 7 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 1 |
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 5444ecdbfb92..b8dffd59eb25 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -35,6 +35,9 @@ | |||
| 35 | #define PCI_VENDOR_ID_ETRON 0x1b6f | 35 | #define PCI_VENDOR_ID_ETRON 0x1b6f |
| 36 | #define PCI_DEVICE_ID_ASROCK_P67 0x7023 | 36 | #define PCI_DEVICE_ID_ASROCK_P67 0x7023 |
| 37 | 37 | ||
| 38 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 | ||
| 39 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 | ||
| 40 | |||
| 38 | static const char hcd_name[] = "xhci_hcd"; | 41 | static const char hcd_name[] = "xhci_hcd"; |
| 39 | 42 | ||
| 40 | /* called after powerup, by probe or system-pm "wakeup" */ | 43 | /* called after powerup, by probe or system-pm "wakeup" */ |
| @@ -118,6 +121,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 118 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | 121 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; |
| 119 | xhci->quirks |= XHCI_AVOID_BEI; | 122 | xhci->quirks |= XHCI_AVOID_BEI; |
| 120 | } | 123 | } |
| 124 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
| 125 | (pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI || | ||
| 126 | pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) { | ||
| 127 | /* Workaround for occasional spurious wakeups from S5 (or | ||
| 128 | * any other sleep) on Haswell machines with LPT and LPT-LP | ||
| 129 | * with the new Intel BIOS | ||
| 130 | */ | ||
| 131 | xhci->quirks |= XHCI_SPURIOUS_WAKEUP; | ||
| 132 | } | ||
| 121 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 133 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| 122 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 134 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { |
| 123 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 135 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| @@ -225,6 +237,11 @@ static void xhci_pci_remove(struct pci_dev *dev) | |||
| 225 | usb_put_hcd(xhci->shared_hcd); | 237 | usb_put_hcd(xhci->shared_hcd); |
| 226 | } | 238 | } |
| 227 | usb_hcd_pci_remove(dev); | 239 | usb_hcd_pci_remove(dev); |
| 240 | |||
| 241 | /* Workaround for spurious wakeups at shutdown with HSW */ | ||
| 242 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | ||
| 243 | pci_set_power_state(dev, PCI_D3hot); | ||
| 244 | |||
| 228 | kfree(xhci); | 245 | kfree(xhci); |
| 229 | } | 246 | } |
| 230 | 247 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6d3e298a8174..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 |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 4f82d2172afa..941d5f59e4dc 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
| @@ -1549,6 +1549,7 @@ struct xhci_hcd { | |||
| 1549 | #define XHCI_AVOID_BEI (1 << 15) | 1549 | #define XHCI_AVOID_BEI (1 << 15) |
| 1550 | #define XHCI_PLAT (1 << 16) | 1550 | #define XHCI_PLAT (1 << 16) |
| 1551 | #define XHCI_SLOW_SUSPEND (1 << 17) | 1551 | #define XHCI_SLOW_SUSPEND (1 << 17) |
| 1552 | #define XHCI_SPURIOUS_WAKEUP (1 << 18) | ||
| 1552 | unsigned int num_active_eps; | 1553 | unsigned int num_active_eps; |
| 1553 | unsigned int limit_active_eps; | 1554 | unsigned int limit_active_eps; |
| 1554 | /* There are two roothubs to keep track of bus suspend info for */ | 1555 | /* There are two roothubs to keep track of bus suspend info for */ |
