Commit 8d1a243b authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

OHCI: add auto-stop support

This patch (as790b) adds "autostop" support to ohci-hcd: the driver
will automatically stop the host controller when no devices have been
connected for at least one second.  This feature is useful when the
USB autosuspend facility isn't available, such as when
CONFIG_USB_SUSPEND hasn't been set.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1f7e1a3b
...@@ -715,17 +715,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -715,17 +715,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
return IRQ_NOTMINE; return IRQ_NOTMINE;
} }
/* 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. Poll by timer
* til it's fully debounced and the difference won't matter.
*/
if (ints & OHCI_INTR_RHSC) { if (ints & OHCI_INTR_RHSC) {
ohci_vdbg (ohci, "rhsc\n"); ohci_vdbg (ohci, "rhsc\n");
ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrdisable);
hcd->poll_rh = 1;
ohci->next_statechange = jiffies + STATECHANGE_DELAY; ohci->next_statechange = jiffies + STATECHANGE_DELAY;
ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus); ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus);
usb_hcd_poll_rh_status(hcd); usb_hcd_poll_rh_status(hcd);
...@@ -743,13 +734,18 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -743,13 +734,18 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
if (ints & OHCI_INTR_RD) { if (ints & OHCI_INTR_RD) {
ohci_vdbg (ohci, "resume detect\n"); ohci_vdbg (ohci, "resume detect\n");
ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus); ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
if (hcd->state != HC_STATE_QUIESCING) hcd->poll_rh = 1;
if (ohci->autostop) {
spin_lock (&ohci->lock);
ohci_rh_resume (ohci);
spin_unlock (&ohci->lock);
} else
usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(hcd);
} }
if (ints & OHCI_INTR_WDH) { if (ints & OHCI_INTR_WDH) {
if (HC_IS_RUNNING(hcd->state)) if (HC_IS_RUNNING(hcd->state))
ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable); ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable);
spin_lock (&ohci->lock); spin_lock (&ohci->lock);
dl_done_list (ohci, ptregs); dl_done_list (ohci, ptregs);
spin_unlock (&ohci->lock); spin_unlock (&ohci->lock);
......
This diff is collapsed.
...@@ -388,6 +388,7 @@ struct ohci_hcd { ...@@ -388,6 +388,7 @@ struct ohci_hcd {
u32 hc_control; /* copy of hc control reg */ u32 hc_control; /* copy of hc control reg */
unsigned long next_statechange; /* suspend/resume */ unsigned long next_statechange; /* suspend/resume */
u32 fminterval; /* saved register */ u32 fminterval; /* saved register */
unsigned autostop:1; /* rh auto stopping/stopped */
unsigned long flags; /* for HC bugs */ unsigned long flags; /* for HC bugs */
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
......
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