aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/pci-quirks.c7
-rw-r--r--drivers/usb/host/pci-quirks.h1
-rw-r--r--drivers/usb/host/xhci-pci.c9
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--drivers/usb/host/xhci.h1
5 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index df0828cb2aa3..c5e9e4a76f14 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -800,6 +800,13 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
800} 800}
801EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); 801EXPORT_SYMBOL_GPL(usb_enable_xhci_ports);
802 802
803void usb_disable_xhci_ports(struct pci_dev *xhci_pdev)
804{
805 pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0);
806 pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0);
807}
808EXPORT_SYMBOL_GPL(usb_disable_xhci_ports);
809
803/** 810/**
804 * PCI Quirks for xHCI. 811 * PCI Quirks for xHCI.
805 * 812 *
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index b1002a8ef96f..ef004a5de20f 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -10,6 +10,7 @@ void usb_amd_quirk_pll_disable(void);
10void usb_amd_quirk_pll_enable(void); 10void usb_amd_quirk_pll_enable(void);
11bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); 11bool usb_is_intel_switchable_xhci(struct pci_dev *pdev);
12void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); 12void usb_enable_xhci_ports(struct pci_dev *xhci_pdev);
13void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
13#else 14#else
14static inline void usb_amd_quirk_pll_disable(void) {} 15static inline void usb_amd_quirk_pll_disable(void) {}
15static inline void usb_amd_quirk_pll_enable(void) {} 16static inline void usb_amd_quirk_pll_enable(void) {}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 92eaff6097c0..9bfd4ca1153c 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -94,6 +94,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
94 xhci->quirks |= XHCI_EP_LIMIT_QUIRK; 94 xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
95 xhci->limit_active_eps = 64; 95 xhci->limit_active_eps = 64;
96 xhci->quirks |= XHCI_SW_BW_CHECKING; 96 xhci->quirks |= XHCI_SW_BW_CHECKING;
97 /*
98 * PPT desktop boards DH77EB and DH77DF will power back on after
99 * a few seconds of being shutdown. The fix for this is to
100 * switch the ports from xHCI to EHCI on shutdown. We can't use
101 * DMI information to find those particular boards (since each
102 * vendor will change the board name), so we have to key off all
103 * PPT chipsets.
104 */
105 xhci->quirks |= XHCI_SPURIOUS_REBOOT;
97 } 106 }
98 if (pdev->vendor == PCI_VENDOR_ID_ETRON && 107 if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
99 pdev->device == PCI_DEVICE_ID_ASROCK_P67) { 108 pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 5c3a3f75e4d5..c59d5b5b6c7d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -659,6 +659,9 @@ void xhci_shutdown(struct usb_hcd *hcd)
659{ 659{
660 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 660 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
661 661
662 if (xhci->quirks && XHCI_SPURIOUS_REBOOT)
663 usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
664
662 spin_lock_irq(&xhci->lock); 665 spin_lock_irq(&xhci->lock);
663 xhci_halt(xhci); 666 xhci_halt(xhci);
664 spin_unlock_irq(&xhci->lock); 667 spin_unlock_irq(&xhci->lock);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 96f49dbb50ac..c713256297ac 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1494,6 +1494,7 @@ struct xhci_hcd {
1494#define XHCI_TRUST_TX_LENGTH (1 << 10) 1494#define XHCI_TRUST_TX_LENGTH (1 << 10)
1495#define XHCI_LPM_SUPPORT (1 << 11) 1495#define XHCI_LPM_SUPPORT (1 << 11)
1496#define XHCI_INTEL_HOST (1 << 12) 1496#define XHCI_INTEL_HOST (1 << 12)
1497#define XHCI_SPURIOUS_REBOOT (1 << 13)
1497 unsigned int num_active_eps; 1498 unsigned int num_active_eps;
1498 unsigned int limit_active_eps; 1499 unsigned int limit_active_eps;
1499 /* There are two roothubs to keep track of bus suspend info for */ 1500 /* There are two roothubs to keep track of bus suspend info for */