Commit cf44e793 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: OHCI autodetects "need" for init reset quirk

Ther recent QUIRK_INITRESET update turns out to need support for some ALi
and ServerWorks chips, as well as the original SiS and OPTi cases.  Rather
than trying to maintain a quirk table (for what I still think must be a
subtle init sequence bug), this patch kicks it in automatically when the
frame clock init problem is detected.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent ec211cf2
...@@ -545,6 +545,7 @@ static int ohci_run (struct ohci_hcd *ohci) ...@@ -545,6 +545,7 @@ static int ohci_run (struct ohci_hcd *ohci)
/* 2msec timelimit here means no irqs/preempt */ /* 2msec timelimit here means no irqs/preempt */
spin_lock_irq (&ohci->lock); spin_lock_irq (&ohci->lock);
retry:
/* HC Reset requires max 10 us delay */ /* HC Reset requires max 10 us delay */
writel (OHCI_HCR, &ohci->regs->cmdstatus); writel (OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */ temp = 30; /* ... allow extra time */
...@@ -563,6 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci) ...@@ -563,6 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci)
* ... but some hardware won't init fmInterval "by the book" * ... but some hardware won't init fmInterval "by the book"
* (SiS, OPTi ...), so reset again instead. SiS doesn't need * (SiS, OPTi ...), so reset again instead. SiS doesn't need
* this if we write fmInterval after we're OPERATIONAL. * this if we write fmInterval after we're OPERATIONAL.
* Unclear about ALi, ServerWorks, and others ... this could
* easily be a longstanding bug in chip init on Linux.
*/ */
if (ohci->flags & OHCI_QUIRK_INITRESET) { if (ohci->flags & OHCI_QUIRK_INITRESET) {
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
...@@ -586,6 +589,11 @@ static int ohci_run (struct ohci_hcd *ohci) ...@@ -586,6 +589,11 @@ static int ohci_run (struct ohci_hcd *ohci)
*/ */
if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0 if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
|| !ohci_readl (&ohci->regs->periodicstart)) { || !ohci_readl (&ohci->regs->periodicstart)) {
if (!(ohci->flags & OHCI_QUIRK_INITRESET)) {
ohci->flags |= OHCI_QUIRK_INITRESET;
ohci_dbg (ohci, "enabling initreset quirk\n");
goto retry;
}
spin_unlock_irq (&ohci->lock); spin_unlock_irq (&ohci->lock);
ohci_err (ohci, "init err (%08x %04x)\n", ohci_err (ohci, "init err (%08x %04x)\n",
ohci_readl (&ohci->regs->fminterval), ohci_readl (&ohci->regs->fminterval),
......
...@@ -69,8 +69,6 @@ ohci_pci_start (struct usb_hcd *hcd) ...@@ -69,8 +69,6 @@ ohci_pci_start (struct usb_hcd *hcd)
&& pdev->device == 0xc861) { && pdev->device == 0xc861) {
ohci_info (ohci, ohci_info (ohci,
"WARNING: OPTi workarounds unavailable\n"); "WARNING: OPTi workarounds unavailable\n");
/* OPTi sometimes acts wierd during init */
ohci->flags = OHCI_QUIRK_INITRESET;
} }
/* Check for NSC87560. We have to look at the bridge (fn1) to /* Check for NSC87560. We have to look at the bridge (fn1) to
...@@ -88,13 +86,6 @@ ohci_pci_start (struct usb_hcd *hcd) ...@@ -88,13 +86,6 @@ ohci_pci_start (struct usb_hcd *hcd)
ohci_info (ohci, "Using NSC SuperIO setup\n"); ohci_info (ohci, "Using NSC SuperIO setup\n");
} }
} }
/* SiS sometimes acts wierd during init */
else if (pdev->vendor == PCI_VENDOR_ID_SI) {
ohci->flags = OHCI_QUIRK_INITRESET;
ohci_info(ohci, "SiS init quirk\n");
}
} }
/* NOTE: there may have already been a first reset, to /* NOTE: there may have already been a first reset, to
......
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