Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41240
b: refs/heads/master
c: 052ac01
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Dec 1, 2006
1 parent 466d8d3 commit 98620db
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b1878440d46a0dc357ed5c9687c534e20955e940
refs/heads/master: 052ac01aeb84d8427ba8ac3d70991ac01b009b59
10 changes: 10 additions & 0 deletions trunk/drivers/usb/host/ohci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,16 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
&regs->intrstatus);

/* NOTE: Vendors didn't always make the same implementation
* choices for RHSC. Many followed the spec; RHSC triggers
* on an edge, like setting and maybe clearing a port status
* change bit. With others it's level-triggered, active
* until khubd clears all the port status change bits. We'll
* always disable it here and rely on polling until khubd
* re-enables it.
*/
ohci_writel(ohci, OHCI_INTR_RHSC, &regs->intrdisable);
usb_hcd_poll_rh_status(hcd);
}

Expand Down
24 changes: 8 additions & 16 deletions trunk/drivers/usb/host/ohci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);

ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
spin_lock_irq(&ohci->lock);
if (!ohci->autostop)
del_timer(&hcd->rh_timer); /* Prevent next poll */
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
spin_unlock_irq(&ohci->lock);
}

#define OHCI_SCHED_ENABLES \
Expand Down Expand Up @@ -348,7 +352,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int i, changed = 0, length = 1;
int any_connected = 0, rhsc_enabled = 1;
int any_connected = 0;
unsigned long flags;

spin_lock_irqsave (&ohci->lock, flags);
Expand Down Expand Up @@ -389,19 +393,6 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
}
}

/* NOTE: vendors didn't always make the same implementation
* choices for RHSC. Sometimes it triggers on an edge (like
* setting and maybe clearing a port status change bit); and
* it's level-triggered on other silicon, active until khubd
* clears all active port status change bits. If it's still
* set (level-triggered) we must disable it and rely on
* polling until khubd re-enables it.
*/
if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) {
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
(void) ohci_readl (ohci, &ohci->regs->intrdisable);
rhsc_enabled = 0;
}
hcd->poll_rh = 1;

/* carry out appropriate state changes */
Expand All @@ -412,7 +403,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
* and RHSC is enabled */
if (!ohci->autostop) {
if (any_connected) {
if (rhsc_enabled)
if (ohci_readl(ohci, &ohci->regs->intrenable) &
OHCI_INTR_RHSC)
hcd->poll_rh = 0;
} else {
ohci->autostop = 1;
Expand Down

0 comments on commit 98620db

Please sign in to comment.