From 58a97ffeb2297f154659f339d77eb3f32c4d8b3e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2008 12:17:10 -0400 Subject: USB: HCDs use the do_remote_wakeup flag When a USB device is suspended, whether or not it is enabled for remote wakeup depends on the device_may_wakeup() setting. The setting is then saved in the do_remote_wakeup flag. Later on, however, the device_may_wakeup() value can change because of user activity. So when testing whether a suspended device is or should be enabled for remote wakeup, we should always test do_remote_wakeup instead of device_may_wakeup(). This patch (as1076) makes that change for root hubs in several places. The patch also adjusts uhci-hcd so that when an autostopped controller is suspended, the remote wakeup setting agrees with the value recorded in the root hub's do_remote_wakeup flag. And the patch adjusts ehci-hcd so that wakeup events on selectively suspended ports (i.e., the bus itself isn't suspended) don't turn on the PME# wakeup signal. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/usb/host/uhci-hcd.c') diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index fec9872dd9d..f65d5a85873 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -262,20 +262,12 @@ __acquires(uhci->lock) { int auto_stop; int int_enable, egsm_enable; + struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); - dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, - "%s%s\n", __FUNCTION__, + dev_dbg(&rhdev->dev, "%s%s\n", __func__, (auto_stop ? " (auto-stop)" : "")); - /* If we get a suspend request when we're already auto-stopped - * then there's nothing to do. - */ - if (uhci->rh_state == UHCI_RH_AUTO_STOPPED) { - uhci->rh_state = new_state; - return; - } - /* Enable resume-detect interrupts if they work. * Then enter Global Suspend mode if _it_ works, still configured. */ @@ -285,8 +277,10 @@ __acquires(uhci->lock) if (remote_wakeup_is_broken(uhci)) egsm_enable = 0; if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || - !device_may_wakeup( - &uhci_to_hcd(uhci)->self.root_hub->dev)) +#ifdef CONFIG_PM + (!auto_stop && !rhdev->do_remote_wakeup) || +#endif + (auto_stop && !device_may_wakeup(&rhdev->dev))) uhci->working_RD = int_enable = 0; outw(int_enable, uhci->io_addr + USBINTR); @@ -308,8 +302,7 @@ __acquires(uhci->lock) return; } if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) - dev_warn(&uhci_to_hcd(uhci)->self.root_hub->dev, - "Controller not stopped yet!\n"); + dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n"); uhci_get_current_frame_number(uhci); -- cgit v1.2.3