aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r--drivers/usb/host/ohci-hcd.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 94d8cf4b36c1..0684f57c14a0 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -101,7 +101,7 @@
101 101
102#include "../core/hcd.h" 102#include "../core/hcd.h"
103 103
104#define DRIVER_VERSION "2005 April 22" 104#define DRIVER_VERSION "2006 August 04"
105#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" 105#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
106#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" 106#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
107 107
@@ -110,9 +110,10 @@
110#undef OHCI_VERBOSE_DEBUG /* not always helpful */ 110#undef OHCI_VERBOSE_DEBUG /* not always helpful */
111 111
112/* For initializing controller (mask in an HCFS mode too) */ 112/* For initializing controller (mask in an HCFS mode too) */
113#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR 113#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
114#define OHCI_INTR_INIT \ 114#define OHCI_INTR_INIT \
115 (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_WDH) 115 (OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \
116 | OHCI_INTR_RD | OHCI_INTR_WDH)
116 117
117#ifdef __hppa__ 118#ifdef __hppa__
118/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ 119/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
@@ -128,6 +129,8 @@
128 129
129static const char hcd_name [] = "ohci_hcd"; 130static const char hcd_name [] = "ohci_hcd";
130 131
132#define STATECHANGE_DELAY msecs_to_jiffies(300)
133
131#include "ohci.h" 134#include "ohci.h"
132 135
133static void ohci_dump (struct ohci_hcd *ohci, int verbose); 136static void ohci_dump (struct ohci_hcd *ohci, int verbose);
@@ -446,7 +449,6 @@ static int ohci_init (struct ohci_hcd *ohci)
446 449
447 disable (ohci); 450 disable (ohci);
448 ohci->regs = hcd->regs; 451 ohci->regs = hcd->regs;
449 ohci->next_statechange = jiffies;
450 452
451 /* REVISIT this BIOS handshake is now moved into PCI "quirks", and 453 /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
452 * was never needed for most non-PCI systems ... remove the code? 454 * was never needed for most non-PCI systems ... remove the code?
@@ -637,10 +639,14 @@ retry:
637 return -EOVERFLOW; 639 return -EOVERFLOW;
638 } 640 }
639 641
640 /* start controller operations */ 642 /* use rhsc irqs after khubd is fully initialized */
643 hcd->poll_rh = 1;
644 hcd->uses_new_polling = 1;
645
646 /* start controller operations */
641 ohci->hc_control &= OHCI_CTRL_RWC; 647 ohci->hc_control &= OHCI_CTRL_RWC;
642 ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; 648 ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
643 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 649 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
644 hcd->state = HC_STATE_RUNNING; 650 hcd->state = HC_STATE_RUNNING;
645 651
646 /* wake on ConnectStatusChange, matching external hubs */ 652 /* wake on ConnectStatusChange, matching external hubs */
@@ -648,7 +654,7 @@ retry:
648 654
649 /* Choose the interrupts we care about now, others later on demand */ 655 /* Choose the interrupts we care about now, others later on demand */
650 mask = OHCI_INTR_INIT; 656 mask = OHCI_INTR_INIT;
651 ohci_writel (ohci, mask, &ohci->regs->intrstatus); 657 ohci_writel (ohci, ~0, &ohci->regs->intrstatus);
652 ohci_writel (ohci, mask, &ohci->regs->intrenable); 658 ohci_writel (ohci, mask, &ohci->regs->intrenable);
653 659
654 /* handle root hub init quirks ... */ 660 /* handle root hub init quirks ... */
@@ -672,6 +678,7 @@ retry:
672 // flush those writes 678 // flush those writes
673 (void) ohci_readl (ohci, &ohci->regs->control); 679 (void) ohci_readl (ohci, &ohci->regs->control);
674 680
681 ohci->next_statechange = jiffies + STATECHANGE_DELAY;
675 spin_unlock_irq (&ohci->lock); 682 spin_unlock_irq (&ohci->lock);
676 683
677 // POTPGT delay is bits 24-31, in 2 ms units. 684 // POTPGT delay is bits 24-31, in 2 ms units.
@@ -709,7 +716,23 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
709 /* interrupt for some other device? */ 716 /* interrupt for some other device? */
710 } else if ((ints &= ohci_readl (ohci, &regs->intrenable)) == 0) { 717 } else if ((ints &= ohci_readl (ohci, &regs->intrenable)) == 0) {
711 return IRQ_NOTMINE; 718 return IRQ_NOTMINE;
712 } 719 }
720
721 /* NOTE: vendors didn't always make the same implementation
722 * choices for RHSC. Sometimes it triggers on an edge (like
723 * setting and maybe clearing a port status change bit); and
724 * it's level-triggered on other silicon, active until khubd
725 * clears all active port status change bits. Poll by timer
726 * til it's fully debounced and the difference won't matter.
727 */
728 if (ints & OHCI_INTR_RHSC) {
729 ohci_vdbg (ohci, "rhsc\n");
730 ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrdisable);
731 hcd->poll_rh = 1;
732 ohci->next_statechange = jiffies + STATECHANGE_DELAY;
733 ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus);
734 usb_hcd_poll_rh_status(hcd);
735 }
713 736
714 if (ints & OHCI_INTR_UE) { 737 if (ints & OHCI_INTR_UE) {
715 disable (ohci); 738 disable (ohci);