From 3da2495c0a92723d58cacaaff48dc60a29ddaae6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 14 Nov 2006 16:28:01 -0500 Subject: OHCI: disallow autostop when wakeup is not available This patch (as822) prevents the OHCI autostop mechanism from kicking in if the root hub is not able or not allowed to issue wakeup requests. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host/ohci-hub.c') diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 6f113596af66..da09e7930c1b 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -422,7 +422,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ohci->autostop = 0; ohci->next_statechange = jiffies + STATECHANGE_DELAY; - } else if (time_after_eq (jiffies, + } else if (device_may_wakeup(&hcd->self.root_hub->dev) + && time_after_eq(jiffies, ohci->next_statechange) && !ohci->ed_rm_list && !(ohci->hc_control & -- cgit v1.2.3 From 583ceada075597a5b6acab1140d61ac81586a2a6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Oct 2006 12:04:22 -0400 Subject: USB: OHCI: fix root-hub resume bug When a suspended OHCI controller sees a port's status change, it sets both the Root-Hub-Status-Change and the Resume-Detect bits in the Interrupt Status register. Processing both these bits, the driver tries to resume the root hub twice! This patch (as807) fixes the bug by ignoring RD if RHSC is set. It also prints a slightly more informative log message when a remote-wakeup event occurs. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 25 +++++++++++++++---------- drivers/usb/host/ohci-hub.c | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/usb/host/ohci-hub.c') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9be6b303e784..ea4714e557e4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -715,13 +715,6 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) return IRQ_NOTMINE; } - if (ints & OHCI_INTR_RHSC) { - ohci_vdbg (ohci, "rhsc\n"); - ohci->next_statechange = jiffies + STATECHANGE_DELAY; - ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); - usb_hcd_poll_rh_status(hcd); - } - if (ints & OHCI_INTR_UE) { disable (ohci); ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); @@ -731,9 +724,21 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) ohci_usb_reset (ohci); } - if (ints & OHCI_INTR_RD) { - ohci_vdbg (ohci, "resume detect\n"); - ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); + if (ints & OHCI_INTR_RHSC) { + ohci_vdbg(ohci, "rhsc\n"); + ohci->next_statechange = jiffies + STATECHANGE_DELAY; + ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, + ®s->intrstatus); + usb_hcd_poll_rh_status(hcd); + } + + /* For connect and disconnect events, we expect the controller + * to turn on RHSC along with RD. But for remote wakeup events + * this might not happen. + */ + else if (ints & OHCI_INTR_RD) { + ohci_vdbg(ohci, "resume detect\n"); + ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus); hcd->poll_rh = 1; if (ohci->autostop) { spin_lock (&ohci->lock); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index da09e7930c1b..6995ea36f2e8 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -169,7 +169,8 @@ __acquires(ohci->lock) break; case OHCI_USB_RESUME: /* HCFS changes sometime after INTR_RD */ - ohci_info (ohci, "wakeup\n"); + ohci_info(ohci, "%swakeup\n", + autostopped ? "auto-" : ""); break; case OHCI_USB_OPER: /* this can happen after resuming a swsusp snapshot */ -- cgit v1.2.3