aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-pci.c
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2013-07-23 04:35:47 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2013-07-23 17:50:29 -0400
commit26b76798e0507429506b93cd49f8c4cfdab06896 (patch)
tree264be6752d1b833de4807f33c18f971993c0f952 /drivers/usb/host/ehci-pci.c
parent063ebeb4335312d05bdf6fb4fc0e41500c6c0afb (diff)
Intel xhci: refactor EHCI/xHCI port switching
Make the Linux xHCI driver automatically try to switchover the EHCI ports to xHCI when an Intel xHCI host is detected, and it also finds an Intel EHCI host. This means we will no longer have to add Intel xHCI hosts to a quirks list when the PCI device IDs change. Simply continuing to add new Intel xHCI PCI device IDs to the quirks list is not sustainable. During suspend ports may be swicthed back to EHCI by BIOS and not properly restored to xHCI at resume. Previously both EHCI and xHCI resume functions switched ports back to XHCI, but it's enough to do it in xHCI only because the hub driver doesn't start running again until after both hosts are resumed. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r--drivers/usb/host/ehci-pci.c42
1 files changed, 0 insertions, 42 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 595d210655b6..6bd299e61f58 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -315,53 +315,11 @@ done:
315 * Also they depend on separate root hub suspend/resume. 315 * Also they depend on separate root hub suspend/resume.
316 */ 316 */
317 317
318static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
319{
320 return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
321 pdev->vendor == PCI_VENDOR_ID_INTEL &&
322 (pdev->device == 0x1E26 ||
323 pdev->device == 0x8C2D ||
324 pdev->device == 0x8C26 ||
325 pdev->device == 0x9C26);
326}
327
328static void ehci_enable_xhci_companion(void)
329{
330 struct pci_dev *companion = NULL;
331
332 /* The xHCI and EHCI controllers are not on the same PCI slot */
333 for_each_pci_dev(companion) {
334 if (!usb_is_intel_switchable_xhci(companion))
335 continue;
336 usb_enable_xhci_ports(companion);
337 return;
338 }
339}
340
341static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) 318static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
342{ 319{
343 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 320 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
344 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 321 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
345 322
346 /* The BIOS on systems with the Intel Panther Point chipset may or may
347 * not support xHCI natively. That means that during system resume, it
348 * may switch the ports back to EHCI so that users can use their
349 * keyboard to select a kernel from GRUB after resume from hibernate.
350 *
351 * The BIOS is supposed to remember whether the OS had xHCI ports
352 * enabled before resume, and switch the ports back to xHCI when the
353 * BIOS/OS semaphore is written, but we all know we can't trust BIOS
354 * writers.
355 *
356 * Unconditionally switch the ports back to xHCI after a system resume.
357 * We can't tell whether the EHCI or xHCI controller will be resumed
358 * first, so we have to do the port switchover in both drivers. Writing
359 * a '1' to the port switchover registers should have no effect if the
360 * port was already switched over.
361 */
362 if (usb_is_intel_switchable_ehci(pdev))
363 ehci_enable_xhci_companion();
364
365 if (ehci_resume(hcd, hibernated) != 0) 323 if (ehci_resume(hcd, hibernated) != 0)
366 (void) ehci_pci_reinit(ehci, pdev); 324 (void) ehci_pci_reinit(ehci, pdev);
367 return 0; 325 return 0;