aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/pci-quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/pci-quirks.c')
-rw-r--r--drivers/usb/host/pci-quirks.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index dd483c13565b..ce636466edb7 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
567{ 567{
568 void __iomem *base; 568 void __iomem *base;
569 u32 control; 569 u32 control;
570 u32 fminterval; 570 u32 fminterval = 0;
571 bool no_fminterval = false;
571 int cnt; 572 int cnt;
572 573
573 if (!mmio_resource_enabled(pdev, 0)) 574 if (!mmio_resource_enabled(pdev, 0))
@@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
577 if (base == NULL) 578 if (base == NULL)
578 return; 579 return;
579 580
581 /*
582 * ULi M5237 OHCI controller locks the whole system when accessing
583 * the OHCI_FMINTERVAL offset.
584 */
585 if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237)
586 no_fminterval = true;
587
580 control = readl(base + OHCI_CONTROL); 588 control = readl(base + OHCI_CONTROL);
581 589
582/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ 590/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
@@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
615 } 623 }
616 624
617 /* software reset of the controller, preserving HcFmInterval */ 625 /* software reset of the controller, preserving HcFmInterval */
618 fminterval = readl(base + OHCI_FMINTERVAL); 626 if (!no_fminterval)
627 fminterval = readl(base + OHCI_FMINTERVAL);
628
619 writel(OHCI_HCR, base + OHCI_CMDSTATUS); 629 writel(OHCI_HCR, base + OHCI_CMDSTATUS);
620 630
621 /* reset requires max 10 us delay */ 631 /* reset requires max 10 us delay */
@@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
624 break; 634 break;
625 udelay(1); 635 udelay(1);
626 } 636 }
627 writel(fminterval, base + OHCI_FMINTERVAL); 637
638 if (!no_fminterval)
639 writel(fminterval, base + OHCI_FMINTERVAL);
628 640
629 /* Now the controller is safely in SUSPEND and nothing can wake it up */ 641 /* Now the controller is safely in SUSPEND and nothing can wake it up */
630 iounmap(base); 642 iounmap(base);