aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAndy Ross <andy.ross@windriver.com>2011-05-11 18:52:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-12 12:42:01 -0400
commit3610ea5397b80822e417aaa0e706fd803fb05680 (patch)
tree8b6234cb0e4db0450bb16e88c9de27df2e5f5a21 /drivers/usb
parent5c853013dcdadb60724268bf860d372fba71694c (diff)
ehci: workaround for pci quirk timeout on ExoPC
The BIOS handoff for the unused EHCI controller on the ExoPC tablet hangs for 90 seconds on boot. Detect that device, skip negotiation and force the handoff. Signed-off-by: Andy Ross <andy.ross@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/pci-quirks.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index e300509faa61..f16c59d5f487 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/acpi.h> 16#include <linux/acpi.h>
17#include <linux/dmi.h>
17#include "pci-quirks.h" 18#include "pci-quirks.h"
18#include "xhci-ext-caps.h" 19#include "xhci-ext-caps.h"
19 20
@@ -507,9 +508,20 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
507 void __iomem *op_reg_base, 508 void __iomem *op_reg_base,
508 u32 cap, u8 offset) 509 u32 cap, u8 offset)
509{ 510{
510 int msec, tried_handoff = 0; 511 int try_handoff = 1, tried_handoff = 0;
512
513 /* The Pegatron Lucid (ExoPC) tablet sporadically waits for 90
514 * seconds trying the handoff on its unused controller. Skip
515 * it. */
516 if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
517 const char *dmi_bn = dmi_get_system_info(DMI_BOARD_NAME);
518 const char *dmi_bv = dmi_get_system_info(DMI_BIOS_VERSION);
519 if (dmi_bn && !strcmp(dmi_bn, "EXOPG06411") &&
520 dmi_bv && !strcmp(dmi_bv, "Lucid-CE-133"))
521 try_handoff = 0;
522 }
511 523
512 if (cap & EHCI_USBLEGSUP_BIOS) { 524 if (try_handoff && (cap & EHCI_USBLEGSUP_BIOS)) {
513 dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n"); 525 dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
514 526
515#if 0 527#if 0
@@ -534,20 +546,23 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
534 } 546 }
535 547
536 /* if boot firmware now owns EHCI, spin till it hands it over. */ 548 /* if boot firmware now owns EHCI, spin till it hands it over. */
537 msec = 1000; 549 if (try_handoff) {
538 while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { 550 int msec = 1000;
539 tried_handoff = 1; 551 while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
540 msleep(10); 552 tried_handoff = 1;
541 msec -= 10; 553 msleep(10);
542 pci_read_config_dword(pdev, offset, &cap); 554 msec -= 10;
555 pci_read_config_dword(pdev, offset, &cap);
556 }
543 } 557 }
544 558
545 if (cap & EHCI_USBLEGSUP_BIOS) { 559 if (cap & EHCI_USBLEGSUP_BIOS) {
546 /* well, possibly buggy BIOS... try to shut it down, 560 /* well, possibly buggy BIOS... try to shut it down,
547 * and hope nothing goes too wrong 561 * and hope nothing goes too wrong
548 */ 562 */
549 dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" 563 if (try_handoff)
550 " (BIOS bug?) %08x\n", cap); 564 dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
565 " (BIOS bug?) %08x\n", cap);
551 pci_write_config_byte(pdev, offset + 2, 0); 566 pci_write_config_byte(pdev, offset + 2, 0);
552 } 567 }
553 568