aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/xhci-pci.c30
-rw-r--r--drivers/usb/host/xhci.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 7f76c8a12f89..fd53c9ebd662 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -37,6 +37,9 @@
37 37
38#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 38#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
39#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 39#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
40#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5
41#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f
42#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
40 43
41static const char hcd_name[] = "xhci_hcd"; 44static const char hcd_name[] = "xhci_hcd";
42 45
@@ -133,6 +136,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
133 pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { 136 pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
134 xhci->quirks |= XHCI_SPURIOUS_REBOOT; 137 xhci->quirks |= XHCI_SPURIOUS_REBOOT;
135 } 138 }
139 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
140 (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
141 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
142 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
143 xhci->quirks |= XHCI_PME_STUCK_QUIRK;
144 }
136 if (pdev->vendor == PCI_VENDOR_ID_ETRON && 145 if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
137 pdev->device == PCI_DEVICE_ID_EJ168) { 146 pdev->device == PCI_DEVICE_ID_EJ168) {
138 xhci->quirks |= XHCI_RESET_ON_RESUME; 147 xhci->quirks |= XHCI_RESET_ON_RESUME;
@@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
159 "QUIRK: Resetting on resume"); 168 "QUIRK: Resetting on resume");
160} 169}
161 170
171/*
172 * Make sure PME works on some Intel xHCI controllers by writing 1 to clear
173 * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4
174 */
175static void xhci_pme_quirk(struct xhci_hcd *xhci)
176{
177 u32 val;
178 void __iomem *reg;
179
180 reg = (void __iomem *) xhci->cap_regs + 0x80a4;
181 val = readl(reg);
182 writel(val | BIT(28), reg);
183 readl(reg);
184}
185
162/* called during probe() after chip reset completes */ 186/* called during probe() after chip reset completes */
163static int xhci_pci_setup(struct usb_hcd *hcd) 187static int xhci_pci_setup(struct usb_hcd *hcd)
164{ 188{
@@ -283,6 +307,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
283 if (xhci->quirks & XHCI_COMP_MODE_QUIRK) 307 if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
284 pdev->no_d3cold = true; 308 pdev->no_d3cold = true;
285 309
310 if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
311 xhci_pme_quirk(xhci);
312
286 return xhci_suspend(xhci, do_wakeup); 313 return xhci_suspend(xhci, do_wakeup);
287} 314}
288 315
@@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
313 if (pdev->vendor == PCI_VENDOR_ID_INTEL) 340 if (pdev->vendor == PCI_VENDOR_ID_INTEL)
314 usb_enable_intel_xhci_ports(pdev); 341 usb_enable_intel_xhci_ports(pdev);
315 342
343 if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
344 xhci_pme_quirk(xhci);
345
316 retval = xhci_resume(xhci, hibernated); 346 retval = xhci_resume(xhci, hibernated);
317 return retval; 347 return retval;
318} 348}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d0663931e5ba..265ab1771d24 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1566,6 +1566,7 @@ struct xhci_hcd {
1566#define XHCI_SPURIOUS_WAKEUP (1 << 18) 1566#define XHCI_SPURIOUS_WAKEUP (1 << 18)
1567/* For controllers with a broken beyond repair streams implementation */ 1567/* For controllers with a broken beyond repair streams implementation */
1568#define XHCI_BROKEN_STREAMS (1 << 19) 1568#define XHCI_BROKEN_STREAMS (1 << 19)
1569#define XHCI_PME_STUCK_QUIRK (1 << 20)
1569 unsigned int num_active_eps; 1570 unsigned int num_active_eps;
1570 unsigned int limit_active_eps; 1571 unsigned int limit_active_eps;
1571 /* There are two roothubs to keep track of bus suspend info for */ 1572 /* There are two roothubs to keep track of bus suspend info for */