USB: add do_wakeup parameter for PCI HCD suspend
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 25 Jun 2010 18:02:14 +0000 (14:02 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 10 Aug 2010 21:35:37 +0000 (14:35 -0700)
This patch (as1385) adds a "do_wakeup" parameter to the pci_suspend
method used by PCI-based host controller drivers.  ehci-hcd in
particular needs to know whether or not to enable wakeup when
suspending a controller.  Although that information is currently
available through device_may_wakeup(), when support is added for
runtime suspend this will no longer be true.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/hcd-pci.c
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-pci.c
drivers/usb/host/uhci-hcd.c
include/linux/usb/hcd.h

index f0156de8db670d3db182c386e914e5bd69e6e63c..e387e394f8762af6f4c85177379537ced658caa6 100644 (file)
@@ -386,7 +386,9 @@ static int hcd_pci_suspend(struct device *dev)
                return retval;
 
        if (hcd->driver->pci_suspend) {
-               retval = hcd->driver->pci_suspend(hcd);
+               bool    do_wakeup = device_may_wakeup(dev);
+
+               retval = hcd->driver->pci_suspend(hcd, do_wakeup);
                suspend_report_result(hcd->driver->pci_suspend, retval);
                if (retval)
                        return retval;
index faa61748db7037d487bd91315fb9c3e779a5bd29..2baf8a849086768f5d5f5929f4fff0a7b2e8b95d 100644 (file)
@@ -228,7 +228,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
         * the root hub is either suspended or stopped.
         */
        spin_lock_irqsave(&ehci->lock, flags);
-       ehci_prepare_ports_for_controller_suspend(ehci);
+       ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        (void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
index 5cd967d28938fc4e28ec3f4eb021f919d1ec2376..a416421abfa2e23f212614709b79424175b1d7ca 100644 (file)
@@ -313,7 +313,8 @@ static int ehci_fsl_drv_suspend(struct device *dev)
        struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
        void __iomem *non_ehci = hcd->regs;
 
-       ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd));
+       ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd),
+                       device_may_wakeup(dev));
        if (!fsl_deep_sleep())
                return 0;
 
index 0931f5a7dec4c288043fd310b40a327a69197001..1292a5b2197ae8d4d1b0955fa736e6f74cb31b78 100644 (file)
@@ -107,7 +107,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
 }
 
 static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
-               bool suspending)
+               bool suspending, bool do_wakeup)
 {
        int             port;
        u32             temp;
@@ -117,8 +117,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
         * when the controller is suspended or resumed.  In all other
         * cases they don't need to be changed.
         */
-       if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup ||
-                       device_may_wakeup(ehci_to_hcd(ehci)->self.controller))
+       if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
                return;
 
        /* clear phy low-power mode before changing wakeup flags */
index a307d550bdafe39dff2cd76ff4d631a03f5ee390..f555e4f35a04b79037343ac28b83d92dea2117bd 100644 (file)
@@ -277,7 +277,7 @@ done:
  * Also they depend on separate root hub suspend/resume.
  */
 
-static int ehci_pci_suspend(struct usb_hcd *hcd)
+static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        unsigned long           flags;
@@ -291,7 +291,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd)
         * the root hub is either suspended or stopped.
         */
        spin_lock_irqsave (&ehci->lock, flags);
-       ehci_prepare_ports_for_controller_suspend(ehci);
+       ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        (void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
index e6c57cc416f689c136f23f4b5fb11e7445d65b71..a4a63ce290e90e4ba82f842d1047a920673b589b 100644 (file)
@@ -540,11 +540,11 @@ struct ehci_fstn {
 
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
-#define ehci_prepare_ports_for_controller_suspend(ehci)                \
-               ehci_adjust_port_wakeup_flags(ehci, true);
+#define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup)     \
+               ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup);
 
-#define ehci_prepare_ports_for_controller_resume(ehci)         \
-               ehci_adjust_port_wakeup_flags(ehci, false);
+#define ehci_prepare_ports_for_controller_resume(ehci)                 \
+               ehci_adjust_port_wakeup_flags(ehci, false, false);
 
 /*-------------------------------------------------------------------------*/
 
index b8a1148f248e4faeb404fbcedf76e6c36d0e6ea2..6bdc8b25a6a10051f29c43bbfef682aefb9a4504 100644 (file)
@@ -392,7 +392,7 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
 
 #ifdef CONFIG_PM
 
-static int ohci_pci_suspend(struct usb_hcd *hcd)
+static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
        unsigned long   flags;
index 2743ec770f0cbef80fc7a67ef9209fa22b1a4204..a7850f51fdc500a0042b41704388ba29856d2e05 100644 (file)
@@ -788,7 +788,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
        return rc;
 }
 
-static int uhci_pci_suspend(struct usb_hcd *hcd)
+static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
        int rc = 0;
index f8f8fa7a56e89a456d78563f715af3994a6728f3..ae10020b4023fdfd2b81f298a5ebb992ba20d4bb 100644 (file)
@@ -211,7 +211,7 @@ struct hc_driver {
         * a whole, not just the root hub; they're for PCI bus glue.
         */
        /* called after suspending the hub, before entering D3 etc */
-       int     (*pci_suspend)(struct usb_hcd *hcd);
+       int     (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);
 
        /* called after entering D0 (etc), before resuming the hub */
        int     (*pci_resume)(struct usb_hcd *hcd, bool hibernated);