Commit 4fe5354f authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

EHCI: fix problem with BIOS handoff

This patch (as882) fixes a problem with the EHCI BIOS handoff.  On my
machine, the BIOS configures the controller and the handoff fails,
leaving the controller configured.  During resume-from-disk, this
confuses ehci-hcd into thinking that the controller has not been
tampered with.

The problem is fixed by turning off the Configured Flag whenever a
BIOS handoff is attempted, whether it succeeds or not.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 36433127
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define EHCI_USBSTS 4 /* status register */ #define EHCI_USBSTS 4 /* status register */
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
#define EHCI_USBINTR 8 /* interrupt register */ #define EHCI_USBINTR 8 /* interrupt register */
#define EHCI_CONFIGFLAG 0x40 /* configured flag register */
#define EHCI_USBLEGSUP 0 /* legacy support register */ #define EHCI_USBLEGSUP 0 /* legacy support register */
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
...@@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
u32 hcc_params, val; u32 hcc_params, val;
u8 offset, cap_length; u8 offset, cap_length;
int count = 256/4; int count = 256/4;
int tried_handoff = 0;
if (!mmio_resource_enabled(pdev, 0)) if (!mmio_resource_enabled(pdev, 0))
return; return;
...@@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
*/ */
msec = 5000; msec = 5000;
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
tried_handoff = 1;
msleep(10); msleep(10);
msec -= 10; msec -= 10;
pci_read_config_dword(pdev, offset, &cap); pci_read_config_dword(pdev, offset, &cap);
...@@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
pci_write_config_dword(pdev, pci_write_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS, offset + EHCI_USBLEGCTLSTS,
0); 0);
/* If the BIOS ever owned the controller then we
* can't expect any power sessions to remain intact.
*/
if (tried_handoff)
writel(0, op_reg_base + EHCI_CONFIGFLAG);
break; break;
case 0: /* illegal reserved capability */ case 0: /* illegal reserved capability */
cap = 0; cap = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment