aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-pci.c39
-rw-r--r--drivers/usb/host/pci-quirks.c63
-rw-r--r--drivers/usb/host/pci-quirks.h2
-rw-r--r--drivers/usb/host/xhci-pci.c20
4 files changed, 124 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 660b80a75cac..1102ce65a3a9 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -348,11 +348,50 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
348 return rc; 348 return rc;
349} 349}
350 350
351static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
352{
353 return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
354 pdev->vendor == PCI_VENDOR_ID_INTEL &&
355 pdev->device == 0x1E26;
356}
357
358static void ehci_enable_xhci_companion(void)
359{
360 struct pci_dev *companion = NULL;
361
362 /* The xHCI and EHCI controllers are not on the same PCI slot */
363 for_each_pci_dev(companion) {
364 if (!usb_is_intel_switchable_xhci(companion))
365 continue;
366 usb_enable_xhci_ports(companion);
367 return;
368 }
369}
370
351static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) 371static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
352{ 372{
353 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 373 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
354 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 374 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
355 375
376 /* The BIOS on systems with the Intel Panther Point chipset may or may
377 * not support xHCI natively. That means that during system resume, it
378 * may switch the ports back to EHCI so that users can use their
379 * keyboard to select a kernel from GRUB after resume from hibernate.
380 *
381 * The BIOS is supposed to remember whether the OS had xHCI ports
382 * enabled before resume, and switch the ports back to xHCI when the
383 * BIOS/OS semaphore is written, but we all know we can't trust BIOS
384 * writers.
385 *
386 * Unconditionally switch the ports back to xHCI after a system resume.
387 * We can't tell whether the EHCI or xHCI controller will be resumed
388 * first, so we have to do the port switchover in both drivers. Writing
389 * a '1' to the port switchover registers should have no effect if the
390 * port was already switched over.
391 */
392 if (usb_is_intel_switchable_ehci(pdev))
393 ehci_enable_xhci_companion();
394
356 // maybe restore FLADJ 395 // maybe restore FLADJ
357 396
358 if (time_before(jiffies, ehci->next_statechange)) 397 if (time_before(jiffies, ehci->next_statechange))
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index f16c59d5f487..fd930618c28f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -69,6 +69,9 @@
69#define NB_PIF0_PWRDOWN_0 0x01100012 69#define NB_PIF0_PWRDOWN_0 0x01100012
70#define NB_PIF0_PWRDOWN_1 0x01100013 70#define NB_PIF0_PWRDOWN_1 0x01100013
71 71
72#define USB_INTEL_XUSB2PR 0xD0
73#define USB_INTEL_USB3_PSSEN 0xD8
74
72static struct amd_chipset_info { 75static struct amd_chipset_info {
73 struct pci_dev *nb_dev; 76 struct pci_dev *nb_dev;
74 struct pci_dev *smbus_dev; 77 struct pci_dev *smbus_dev;
@@ -673,6 +676,64 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
673 return -ETIMEDOUT; 676 return -ETIMEDOUT;
674} 677}
675 678
679bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
680{
681 return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
682 pdev->vendor == PCI_VENDOR_ID_INTEL &&
683 pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI;
684}
685EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
686
687/*
688 * Intel's Panther Point chipset has two host controllers (EHCI and xHCI) that
689 * share some number of ports. These ports can be switched between either
690 * controller. Not all of the ports under the EHCI host controller may be
691 * switchable.
692 *
693 * The ports should be switched over to xHCI before PCI probes for any device
694 * start. This avoids active devices under EHCI being disconnected during the
695 * port switchover, which could cause loss of data on USB storage devices, or
696 * failed boot when the root file system is on a USB mass storage device and is
697 * enumerated under EHCI first.
698 *
699 * We write into the xHC's PCI configuration space in some Intel-specific
700 * registers to switch the ports over. The USB 3.0 terminations and the USB
701 * 2.0 data wires are switched separately. We want to enable the SuperSpeed
702 * terminations before switching the USB 2.0 wires over, so that USB 3.0
703 * devices connect at SuperSpeed, rather than at USB 2.0 speeds.
704 */
705void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
706{
707 u32 ports_available;
708
709 ports_available = 0xffffffff;
710 /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable
711 * Register, to turn on SuperSpeed terminations for all
712 * available ports.
713 */
714 pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
715 cpu_to_le32(ports_available));
716
717 pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
718 &ports_available);
719 dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled "
720 "under xHCI: 0x%x\n", ports_available);
721
722 ports_available = 0xffffffff;
723 /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to
724 * switch the USB 2.0 power and data lines over to the xHCI
725 * host.
726 */
727 pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
728 cpu_to_le32(ports_available));
729
730 pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
731 &ports_available);
732 dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over "
733 "to xHCI: 0x%x\n", ports_available);
734}
735EXPORT_SYMBOL_GPL(usb_enable_xhci_ports);
736
676/** 737/**
677 * PCI Quirks for xHCI. 738 * PCI Quirks for xHCI.
678 * 739 *
@@ -732,6 +793,8 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
732 writel(XHCI_LEGACY_DISABLE_SMI, 793 writel(XHCI_LEGACY_DISABLE_SMI,
733 base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); 794 base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
734 795
796 if (usb_is_intel_switchable_xhci(pdev))
797 usb_enable_xhci_ports(pdev);
735hc_init: 798hc_init:
736 op_reg_base = base + XHCI_HC_LENGTH(readl(base)); 799 op_reg_base = base + XHCI_HC_LENGTH(readl(base));
737 800
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index 6ae9f78e9938..b1002a8ef96f 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -8,6 +8,8 @@ int usb_amd_find_chipset_info(void);
8void usb_amd_dev_put(void); 8void usb_amd_dev_put(void);
9void usb_amd_quirk_pll_disable(void); 9void 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);
12void usb_enable_xhci_ports(struct pci_dev *xhci_pdev);
11#else 13#else
12static inline void usb_amd_quirk_pll_disable(void) {} 14static inline void usb_amd_quirk_pll_disable(void) {}
13static inline void usb_amd_quirk_pll_enable(void) {} 15static 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 cbc4d491e626..faf039ac6573 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -242,8 +242,28 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
242static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) 242static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
243{ 243{
244 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 244 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
245 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
245 int retval = 0; 246 int retval = 0;
246 247
248 /* The BIOS on systems with the Intel Panther Point chipset may or may
249 * not support xHCI natively. That means that during system resume, it
250 * may switch the ports back to EHCI so that users can use their
251 * keyboard to select a kernel from GRUB after resume from hibernate.
252 *
253 * The BIOS is supposed to remember whether the OS had xHCI ports
254 * enabled before resume, and switch the ports back to xHCI when the
255 * BIOS/OS semaphore is written, but we all know we can't trust BIOS
256 * writers.
257 *
258 * Unconditionally switch the ports back to xHCI after a system resume.
259 * We can't tell whether the EHCI or xHCI controller will be resumed
260 * first, so we have to do the port switchover in both drivers. Writing
261 * a '1' to the port switchover registers should have no effect if the
262 * port was already switched over.
263 */
264 if (usb_is_intel_switchable_xhci(pdev))
265 usb_enable_xhci_ports(pdev);
266
247 retval = xhci_resume(xhci, hibernated); 267 retval = xhci_resume(xhci, hibernated);
248 return retval; 268 return retval;
249} 269}