Commit 4147200d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: add do_wakeup parameter for PCI HCD suspend

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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 057c58bf
...@@ -386,7 +386,9 @@ static int hcd_pci_suspend(struct device *dev) ...@@ -386,7 +386,9 @@ static int hcd_pci_suspend(struct device *dev)
return retval; return retval;
if (hcd->driver->pci_suspend) { 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); suspend_report_result(hcd->driver->pci_suspend, retval);
if (retval) if (retval)
return retval; return retval;
......
...@@ -228,7 +228,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) ...@@ -228,7 +228,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
* the root hub is either suspended or stopped. * the root hub is either suspended or stopped.
*/ */
spin_lock_irqsave(&ehci->lock, flags); 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); ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable);
......
...@@ -313,7 +313,8 @@ static int ehci_fsl_drv_suspend(struct device *dev) ...@@ -313,7 +313,8 @@ static int ehci_fsl_drv_suspend(struct device *dev)
struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
void __iomem *non_ehci = hcd->regs; 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()) if (!fsl_deep_sleep())
return 0; return 0;
......
...@@ -107,7 +107,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) ...@@ -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, static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
bool suspending) bool suspending, bool do_wakeup)
{ {
int port; int port;
u32 temp; u32 temp;
...@@ -117,8 +117,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, ...@@ -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 * when the controller is suspended or resumed. In all other
* cases they don't need to be changed. * cases they don't need to be changed.
*/ */
if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
device_may_wakeup(ehci_to_hcd(ehci)->self.controller))
return; return;
/* clear phy low-power mode before changing wakeup flags */ /* clear phy low-power mode before changing wakeup flags */
......
...@@ -277,7 +277,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ...@@ -277,7 +277,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
* Also they depend on separate root hub suspend/resume. * 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); struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned long flags; unsigned long flags;
...@@ -291,7 +291,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd) ...@@ -291,7 +291,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd)
* the root hub is either suspended or stopped. * the root hub is either suspended or stopped.
*/ */
spin_lock_irqsave (&ehci->lock, flags); 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); ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable);
......
...@@ -540,11 +540,11 @@ struct ehci_fstn { ...@@ -540,11 +540,11 @@ struct ehci_fstn {
/* Prepare the PORTSC wakeup flags during controller suspend/resume */ /* Prepare the PORTSC wakeup flags during controller suspend/resume */
#define ehci_prepare_ports_for_controller_suspend(ehci) \ #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \
ehci_adjust_port_wakeup_flags(ehci, true); ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup);
#define ehci_prepare_ports_for_controller_resume(ehci) \ #define ehci_prepare_ports_for_controller_resume(ehci) \
ehci_adjust_port_wakeup_flags(ehci, false); ehci_adjust_port_wakeup_flags(ehci, false, false);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -392,7 +392,7 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) ...@@ -392,7 +392,7 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
#ifdef CONFIG_PM #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); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags; unsigned long flags;
......
...@@ -788,7 +788,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd) ...@@ -788,7 +788,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
return rc; 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); struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int rc = 0; int rc = 0;
......
...@@ -211,7 +211,7 @@ struct hc_driver { ...@@ -211,7 +211,7 @@ struct hc_driver {
* a whole, not just the root hub; they're for PCI bus glue. * a whole, not just the root hub; they're for PCI bus glue.
*/ */
/* called after suspending the hub, before entering D3 etc */ /* 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 */ /* called after entering D0 (etc), before resuming the hub */
int (*pci_resume)(struct usb_hcd *hcd, bool hibernated); int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);
......
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