diff options
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 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 | ||
351 | static 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 | |||
358 | static 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 | |||
351 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 371 | static 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)) |