diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-09-26 14:46:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-28 18:36:46 -0400 |
commit | 8d1a243ba5dda5c1a3cca5df8fb19ab8b138f074 (patch) | |
tree | c9be9a9d8d4f5477a47bfc5f8a6f612a0c4867ca /drivers/usb/host/ohci-hcd.c | |
parent | 1f7e1a3b7e05c833229c4b6e9d3c96262df59e99 (diff) |
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: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1027aa04583d..d1d68c402251 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -715,17 +715,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
715 | return IRQ_NOTMINE; | 715 | return IRQ_NOTMINE; |
716 | } | 716 | } |
717 | 717 | ||
718 | /* NOTE: vendors didn't always make the same implementation | ||
719 | * choices for RHSC. Sometimes it triggers on an edge (like | ||
720 | * setting and maybe clearing a port status change bit); and | ||
721 | * it's level-triggered on other silicon, active until khubd | ||
722 | * clears all active port status change bits. Poll by timer | ||
723 | * til it's fully debounced and the difference won't matter. | ||
724 | */ | ||
725 | if (ints & OHCI_INTR_RHSC) { | 718 | if (ints & OHCI_INTR_RHSC) { |
726 | ohci_vdbg (ohci, "rhsc\n"); | 719 | ohci_vdbg (ohci, "rhsc\n"); |
727 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrdisable); | ||
728 | hcd->poll_rh = 1; | ||
729 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; | 720 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; |
730 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); | 721 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); |
731 | usb_hcd_poll_rh_status(hcd); | 722 | usb_hcd_poll_rh_status(hcd); |
@@ -743,13 +734,18 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
743 | if (ints & OHCI_INTR_RD) { | 734 | if (ints & OHCI_INTR_RD) { |
744 | ohci_vdbg (ohci, "resume detect\n"); | 735 | ohci_vdbg (ohci, "resume detect\n"); |
745 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); | 736 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); |
746 | if (hcd->state != HC_STATE_QUIESCING) | 737 | hcd->poll_rh = 1; |
738 | if (ohci->autostop) { | ||
739 | spin_lock (&ohci->lock); | ||
740 | ohci_rh_resume (ohci); | ||
741 | spin_unlock (&ohci->lock); | ||
742 | } else | ||
747 | usb_hcd_resume_root_hub(hcd); | 743 | usb_hcd_resume_root_hub(hcd); |
748 | } | 744 | } |
749 | 745 | ||
750 | if (ints & OHCI_INTR_WDH) { | 746 | if (ints & OHCI_INTR_WDH) { |
751 | if (HC_IS_RUNNING(hcd->state)) | 747 | if (HC_IS_RUNNING(hcd->state)) |
752 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); | 748 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); |
753 | spin_lock (&ohci->lock); | 749 | spin_lock (&ohci->lock); |
754 | dl_done_list (ohci, ptregs); | 750 | dl_done_list (ohci, ptregs); |
755 | spin_unlock (&ohci->lock); | 751 | spin_unlock (&ohci->lock); |