Commit 5c853013 authored by Andy Ross's avatar Andy Ross Committed by Greg Kroah-Hartman

ehci: pci quirk cleanup

Factor the handoff code out from quirk_usb_disable_ehci
Signed-off-by: default avatarAndy Ross <andy.ross@windriver.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent af5c5805
...@@ -503,14 +503,70 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) ...@@ -503,14 +503,70 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
iounmap(base); iounmap(base);
} }
static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
void __iomem *op_reg_base,
u32 cap, u8 offset)
{
int msec, tried_handoff = 0;
if (cap & EHCI_USBLEGSUP_BIOS) {
dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
#if 0
/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
* but that seems dubious in general (the BIOS left it off intentionally)
* and is known to prevent some systems from booting. so we won't do this
* unless maybe we can determine when we're on a system that needs SMI forced.
*/
/* BIOS workaround (?): be sure the pre-Linux code
* receives the SMI
*/
pci_read_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, &val);
pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS,
val | EHCI_USBLEGCTLSTS_SOOE);
#endif
/* some systems get upset if this semaphore is
* set for any other reason than forcing a BIOS
* handoff..
*/
pci_write_config_byte(pdev, offset + 3, 1);
}
/* 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 (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);
pci_write_config_byte(pdev, offset + 2, 0);
}
/* just in case, always disable EHCI SMIs */
pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, 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);
}
static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
{ {
int wait_time, delta;
void __iomem *base, *op_reg_base; void __iomem *base, *op_reg_base;
u32 hcc_params, val; u32 hcc_params, cap, val;
u8 offset, cap_length; u8 offset, cap_length;
int count = 256/4; int wait_time, delta, count = 256/4;
int tried_handoff = 0;
if (!mmio_resource_enabled(pdev, 0)) if (!mmio_resource_enabled(pdev, 0))
return; return;
...@@ -529,77 +585,17 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -529,77 +585,17 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
hcc_params = readl(base + EHCI_HCC_PARAMS); hcc_params = readl(base + EHCI_HCC_PARAMS);
offset = (hcc_params >> 8) & 0xff; offset = (hcc_params >> 8) & 0xff;
while (offset && --count) { while (offset && --count) {
u32 cap;
int msec;
pci_read_config_dword(pdev, offset, &cap); pci_read_config_dword(pdev, offset, &cap);
switch (cap & 0xff) {
case 1: /* BIOS/SMM/... handoff support */
if ((cap & EHCI_USBLEGSUP_BIOS)) {
dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
#if 0
/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
* but that seems dubious in general (the BIOS left it off intentionally)
* and is known to prevent some systems from booting. so we won't do this
* unless maybe we can determine when we're on a system that needs SMI forced.
*/
/* BIOS workaround (?): be sure the
* pre-Linux code receives the SMI
*/
pci_read_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS,
&val);
pci_write_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS,
val | EHCI_USBLEGCTLSTS_SOOE);
#endif
/* some systems get upset if this semaphore is
* set for any other reason than forcing a BIOS
* handoff..
*/
pci_write_config_byte(pdev, offset + 3, 1);
}
/* 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 (cap & EHCI_USBLEGSUP_BIOS) { switch (cap & 0xff) {
/* well, possibly buggy BIOS... try to shut case 1:
* it down, and hope nothing goes too wrong ehci_bios_handoff(pdev, op_reg_base, cap, offset);
*/
dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
" (BIOS bug?) %08x\n", cap);
pci_write_config_byte(pdev, offset + 2, 0);
}
/* just in case, always disable EHCI SMIs */
pci_write_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS,
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 cap, set cap=0 so we exit */
cap = 0; cap = 0; /* then fallthrough... */
/* FALLTHROUGH */
default: default:
dev_warn(&pdev->dev, "EHCI: unrecognized capability " dev_warn(&pdev->dev, "EHCI: unrecognized capability "
"%02x\n", cap & 0xff); "%02x\n", cap & 0xff);
break;
} }
offset = (cap >> 8) & 0xff; offset = (cap >> 8) & 0xff;
} }
......
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