[PATCH] update PCI early-handoff handling for OHCI
The PCI "early usb handoff" quirk logic didn't work like "ohci-hcd" ... This patch makes it do so by: - Resetting the controller after kicking BIOS off, matching the normal "chip in hardware reset" startup mode; - Reporting any BIOS that borks this simple handoff; it's likely got a few other surprises for us too. - Ignoring that handoff on HPPA; The diagnostic string is mostly shared with EHCI, saving a few bytes. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/usb/host/pci-quirks.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
This commit is contained in:
Родитель
f197b2c54b
Коммит
f2cb36c1df
|
@ -60,6 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, qui
|
|||
#define OHCI_INTRENABLE 0x10
|
||||
#define OHCI_INTRDISABLE 0x14
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||
#define OHCI_INTR_OC (1 << 30) /* ownership change */
|
||||
|
||||
|
@ -140,13 +141,17 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
|||
{
|
||||
void __iomem *base;
|
||||
int wait_time;
|
||||
u32 control;
|
||||
|
||||
base = ioremap_nocache(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
if (base == NULL) return;
|
||||
|
||||
if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
|
||||
wait_time = 500; /* 0.5 seconds */
|
||||
/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
|
||||
#ifndef __hppa__
|
||||
control = readl(base + OHCI_CONTROL);
|
||||
if (control & OHCI_CTRL_IR) {
|
||||
wait_time = 500; /* arbitrary; 5 seconds */
|
||||
writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
|
||||
writel(OHCI_OCR, base + OHCI_CMDSTATUS);
|
||||
while (wait_time > 0 &&
|
||||
|
@ -154,7 +159,15 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
|||
wait_time -= 10;
|
||||
msleep(10);
|
||||
}
|
||||
if (wait_time <= 0)
|
||||
printk(KERN_WARNING "%s %s: early BIOS handoff "
|
||||
"failed (BIOS bug ?)\n",
|
||||
pdev->dev.bus_id, "OHCI");
|
||||
|
||||
/* reset controller, preserving RWC */
|
||||
writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* disable interrupts
|
||||
|
@ -211,8 +224,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
/*
|
||||
* well, possibly buggy BIOS...
|
||||
*/
|
||||
printk(KERN_WARNING "EHCI early BIOS handoff "
|
||||
"failed (BIOS bug ?)\n");
|
||||
printk(KERN_WARNING "%s %s: early BIOS handoff "
|
||||
"failed (BIOS bug ?)\n",
|
||||
pdev->dev.bus_id, "EHCI");
|
||||
pci_write_config_dword(pdev,
|
||||
hcc_params + EHCI_USBLEGSUP,
|
||||
EHCI_USBLEGSUP_OS);
|
||||
|
|
Загрузка…
Ссылка в новой задаче