diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-28 12:36:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-28 12:36:15 -0700 |
commit | 87367a0b71a5188e34a913c05673b5078f71a64d (patch) | |
tree | da14cc575bfe692f07b42c2c8a13d9aa403fc471 /drivers/usb/host/ehci-pci.c | |
parent | 4cb865deec59ef31d966622d1ec87411ae32dfab (diff) | |
parent | 2cf95c18d5069e13c02a8667d91e064df8e17e09 (diff) |
Merge branch 'for-usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci
* 'for-usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci:
Intel xhci: Limit number of active endpoints to 64.
Intel xhci: Ignore spurious successful event.
Intel xhci: Support EHCI/xHCI port switching.
Intel xhci: Add PCI id for Panther Point xHCI host.
xhci: STFU: Be quieter during URB submission and completion.
xhci: STFU: Don't print event ring dequeue pointer.
xhci: STFU: Remove function tracing.
xhci: Don't submit commands when the host is dead.
xhci: Clear stopped_td when Stop Endpoint command completes.
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 660b80a75ca..1102ce65a3a 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) return rc; } +static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) +{ + return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && + pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == 0x1E26; +} + +static void ehci_enable_xhci_companion(void) +{ + struct pci_dev *companion = NULL; + + /* The xHCI and EHCI controllers are not on the same PCI slot */ + for_each_pci_dev(companion) { + if (!usb_is_intel_switchable_xhci(companion)) + continue; + usb_enable_xhci_ports(companion); + return; + } +} + static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + /* The BIOS on systems with the Intel Panther Point chipset may or may + * not support xHCI natively. That means that during system resume, it + * may switch the ports back to EHCI so that users can use their + * keyboard to select a kernel from GRUB after resume from hibernate. + * + * The BIOS is supposed to remember whether the OS had xHCI ports + * enabled before resume, and switch the ports back to xHCI when the + * BIOS/OS semaphore is written, but we all know we can't trust BIOS + * writers. + * + * Unconditionally switch the ports back to xHCI after a system resume. + * We can't tell whether the EHCI or xHCI controller will be resumed + * first, so we have to do the port switchover in both drivers. Writing + * a '1' to the port switchover registers should have no effect if the + * port was already switched over. + */ + if (usb_is_intel_switchable_ehci(pdev)) + ehci_enable_xhci_companion(); + // maybe restore FLADJ if (time_before(jiffies, ehci->next_statechange)) |