summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAndy Ross <andy.ross@windriver.com>2011-05-11 15:52:38 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-12 09:42:01 -0700
commit3610ea5397b80822e417aaa0e706fd803fb05680 (patch)
tree8b6234cb0e4db0450bb16e88c9de27df2e5f5a21 /drivers/usb
parent5c853013dcdadb60724268bf860d372fba71694c (diff)
downloadlinux-3610ea5397b80822e417aaa0e706fd803fb05680.tar.gz
linux-3610ea5397b80822e417aaa0e706fd803fb05680.tar.bz2
linux-3610ea5397b80822e417aaa0e706fd803fb05680.zip
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 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/acpi.h>
+#include <linux/dmi.h>
#include "pci-quirks.h"
#include "xhci-ext-caps.h"
@@ -507,9 +508,20 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
void __iomem *op_reg_base,
u32 cap, u8 offset)
{
- int msec, tried_handoff = 0;
+ int try_handoff = 1, tried_handoff = 0;
+
+ /* The Pegatron Lucid (ExoPC) tablet sporadically waits for 90
+ * seconds trying the handoff on its unused controller. Skip
+ * it. */
+ if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
+ const char *dmi_bn = dmi_get_system_info(DMI_BOARD_NAME);
+ const char *dmi_bv = dmi_get_system_info(DMI_BIOS_VERSION);
+ if (dmi_bn && !strcmp(dmi_bn, "EXOPG06411") &&
+ dmi_bv && !strcmp(dmi_bv, "Lucid-CE-133"))
+ try_handoff = 0;
+ }
- if (cap & EHCI_USBLEGSUP_BIOS) {
+ if (try_handoff && (cap & EHCI_USBLEGSUP_BIOS)) {
dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
#if 0
@@ -534,20 +546,23 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
}
/* if boot firmware now owns EHCI, spin till it hands it over. */
- msec = 1000;
- while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
- tried_handoff = 1;
- msleep(10);
- msec -= 10;
- pci_read_config_dword(pdev, offset, &cap);
+ if (try_handoff) {
+ int msec = 1000;
+ while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+ tried_handoff = 1;
+ msleep(10);
+ msec -= 10;
+ pci_read_config_dword(pdev, offset, &cap);
+ }
}
if (cap & EHCI_USBLEGSUP_BIOS) {
/* well, possibly buggy BIOS... try to shut it down,
* and hope nothing goes too wrong
*/
- dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
- " (BIOS bug?) %08x\n", cap);
+ if (try_handoff)
+ dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
+ " (BIOS bug?) %08x\n", cap);
pci_write_config_byte(pdev, offset + 2, 0);
}