aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-pci.c')
-rw-r--r--drivers/usb/host/xhci-pci.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 58c43ed7ff3b..f0640b7a1c42 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -28,7 +28,9 @@
28#include "xhci.h" 28#include "xhci.h"
29#include "xhci-trace.h" 29#include "xhci-trace.h"
30 30
31#define PORT2_SSIC_CONFIG_REG2 0x883c 31#define SSIC_PORT_NUM 2
32#define SSIC_PORT_CFG2 0x880c
33#define SSIC_PORT_CFG2_OFFSET 0x30
32#define PROG_DONE (1 << 30) 34#define PROG_DONE (1 << 30)
33#define SSIC_PORT_UNUSED (1 << 31) 35#define SSIC_PORT_UNUSED (1 << 31)
34 36
@@ -45,6 +47,7 @@
45#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 47#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5
46#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f 48#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f
47#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f 49#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
50#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
48 51
49static const char hcd_name[] = "xhci_hcd"; 52static const char hcd_name[] = "xhci_hcd";
50 53
@@ -151,9 +154,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
151 if (pdev->vendor == PCI_VENDOR_ID_INTEL && 154 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
152 (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || 155 (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
153 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || 156 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
154 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) { 157 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
158 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) {
155 xhci->quirks |= XHCI_PME_STUCK_QUIRK; 159 xhci->quirks |= XHCI_PME_STUCK_QUIRK;
156 } 160 }
161 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
162 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
163 xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
164 }
157 if (pdev->vendor == PCI_VENDOR_ID_ETRON && 165 if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
158 pdev->device == PCI_DEVICE_ID_EJ168) { 166 pdev->device == PCI_DEVICE_ID_EJ168) {
159 xhci->quirks |= XHCI_RESET_ON_RESUME; 167 xhci->quirks |= XHCI_RESET_ON_RESUME;
@@ -312,22 +320,20 @@ static void xhci_pci_remove(struct pci_dev *dev)
312 * SSIC PORT need to be marked as "unused" before putting xHCI 320 * SSIC PORT need to be marked as "unused" before putting xHCI
313 * into D3. After D3 exit, the SSIC port need to be marked as "used". 321 * into D3. After D3 exit, the SSIC port need to be marked as "used".
314 * Without this change, xHCI might not enter D3 state. 322 * Without this change, xHCI might not enter D3 state.
315 * Make sure PME works on some Intel xHCI controllers by writing 1 to clear
316 * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4
317 */ 323 */
318static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) 324static void xhci_ssic_port_unused_quirk(struct usb_hcd *hcd, bool suspend)
319{ 325{
320 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 326 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
321 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
322 u32 val; 327 u32 val;
323 void __iomem *reg; 328 void __iomem *reg;
329 int i;
324 330
325 if (pdev->vendor == PCI_VENDOR_ID_INTEL && 331 for (i = 0; i < SSIC_PORT_NUM; i++) {
326 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { 332 reg = (void __iomem *) xhci->cap_regs +
327 333 SSIC_PORT_CFG2 +
328 reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2; 334 i * SSIC_PORT_CFG2_OFFSET;
329 335
330 /* Notify SSIC that SSIC profile programming is not done */ 336 /* Notify SSIC that SSIC profile programming is not done. */
331 val = readl(reg) & ~PROG_DONE; 337 val = readl(reg) & ~PROG_DONE;
332 writel(val, reg); 338 writel(val, reg);
333 339
@@ -344,6 +350,17 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend)
344 writel(val, reg); 350 writel(val, reg);
345 readl(reg); 351 readl(reg);
346 } 352 }
353}
354
355/*
356 * Make sure PME works on some Intel xHCI controllers by writing 1 to clear
357 * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4
358 */
359static void xhci_pme_quirk(struct usb_hcd *hcd)
360{
361 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
362 void __iomem *reg;
363 u32 val;
347 364
348 reg = (void __iomem *) xhci->cap_regs + 0x80a4; 365 reg = (void __iomem *) xhci->cap_regs + 0x80a4;
349 val = readl(reg); 366 val = readl(reg);
@@ -355,6 +372,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
355{ 372{
356 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 373 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
357 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 374 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
375 int ret;
358 376
359 /* 377 /*
360 * Systems with the TI redriver that loses port status change events 378 * Systems with the TI redriver that loses port status change events
@@ -364,9 +382,16 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
364 pdev->no_d3cold = true; 382 pdev->no_d3cold = true;
365 383
366 if (xhci->quirks & XHCI_PME_STUCK_QUIRK) 384 if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
367 xhci_pme_quirk(hcd, true); 385 xhci_pme_quirk(hcd);
386
387 if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
388 xhci_ssic_port_unused_quirk(hcd, true);
368 389
369 return xhci_suspend(xhci, do_wakeup); 390 ret = xhci_suspend(xhci, do_wakeup);
391 if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
392 xhci_ssic_port_unused_quirk(hcd, false);
393
394 return ret;
370} 395}
371 396
372static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) 397static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
@@ -396,8 +421,11 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
396 if (pdev->vendor == PCI_VENDOR_ID_INTEL) 421 if (pdev->vendor == PCI_VENDOR_ID_INTEL)
397 usb_enable_intel_xhci_ports(pdev); 422 usb_enable_intel_xhci_ports(pdev);
398 423
424 if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
425 xhci_ssic_port_unused_quirk(hcd, false);
426
399 if (xhci->quirks & XHCI_PME_STUCK_QUIRK) 427 if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
400 xhci_pme_quirk(hcd, false); 428 xhci_pme_quirk(hcd);
401 429
402 retval = xhci_resume(xhci, hibernated); 430 retval = xhci_resume(xhci, hibernated);
403 return retval; 431 return retval;