[PATCH 165/205] ehci: workaround for pci quirk timeout on ExoPC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andy Ross <andy.ross@xxxxxxxxxxxxx>

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@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/host/pci-quirks.c |   35 +++++++++++++++++++++++++----------
 1 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index e300509..f16c59d 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);
 	}
 
-- 
1.7.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux