Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
4147200d 057c58bf

+17 -15
+3 -1
drivers/usb/core/hcd-pci.c
··· 386 386 return retval; 387 387 388 388 if (hcd->driver->pci_suspend) { 389 - retval = hcd->driver->pci_suspend(hcd); 389 + bool do_wakeup = device_may_wakeup(dev); 390 + 391 + retval = hcd->driver->pci_suspend(hcd, do_wakeup); 390 392 suspend_report_result(hcd->driver->pci_suspend, retval); 391 393 if (retval) 392 394 return retval;
+1 -1
drivers/usb/host/ehci-au1xxx.c
··· 228 228 * the root hub is either suspended or stopped. 229 229 */ 230 230 spin_lock_irqsave(&ehci->lock, flags); 231 - ehci_prepare_ports_for_controller_suspend(ehci); 231 + ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); 232 232 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 233 233 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 234 234
+2 -1
drivers/usb/host/ehci-fsl.c
··· 313 313 struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); 314 314 void __iomem *non_ehci = hcd->regs; 315 315 316 - ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd)); 316 + ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), 317 + device_may_wakeup(dev)); 317 318 if (!fsl_deep_sleep()) 318 319 return 0; 319 320
+2 -3
drivers/usb/host/ehci-hub.c
··· 107 107 } 108 108 109 109 static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, 110 - bool suspending) 110 + bool suspending, bool do_wakeup) 111 111 { 112 112 int port; 113 113 u32 temp; ··· 117 117 * when the controller is suspended or resumed. In all other 118 118 * cases they don't need to be changed. 119 119 */ 120 - if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || 121 - device_may_wakeup(ehci_to_hcd(ehci)->self.controller)) 120 + if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup) 122 121 return; 123 122 124 123 /* clear phy low-power mode before changing wakeup flags */
+2 -2
drivers/usb/host/ehci-pci.c
··· 277 277 * Also they depend on separate root hub suspend/resume. 278 278 */ 279 279 280 - static int ehci_pci_suspend(struct usb_hcd *hcd) 280 + static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) 281 281 { 282 282 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 283 283 unsigned long flags; ··· 291 291 * the root hub is either suspended or stopped. 292 292 */ 293 293 spin_lock_irqsave (&ehci->lock, flags); 294 - ehci_prepare_ports_for_controller_suspend(ehci); 294 + ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); 295 295 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 296 296 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 297 297
+4 -4
drivers/usb/host/ehci.h
··· 540 540 541 541 /* Prepare the PORTSC wakeup flags during controller suspend/resume */ 542 542 543 - #define ehci_prepare_ports_for_controller_suspend(ehci) \ 544 - ehci_adjust_port_wakeup_flags(ehci, true); 543 + #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \ 544 + ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup); 545 545 546 - #define ehci_prepare_ports_for_controller_resume(ehci) \ 547 - ehci_adjust_port_wakeup_flags(ehci, false); 546 + #define ehci_prepare_ports_for_controller_resume(ehci) \ 547 + ehci_adjust_port_wakeup_flags(ehci, false, false); 548 548 549 549 /*-------------------------------------------------------------------------*/ 550 550
+1 -1
drivers/usb/host/ohci-pci.c
··· 392 392 393 393 #ifdef CONFIG_PM 394 394 395 - static int ohci_pci_suspend(struct usb_hcd *hcd) 395 + static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) 396 396 { 397 397 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 398 398 unsigned long flags;
+1 -1
drivers/usb/host/uhci-hcd.c
··· 788 788 return rc; 789 789 } 790 790 791 - static int uhci_pci_suspend(struct usb_hcd *hcd) 791 + static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) 792 792 { 793 793 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 794 794 int rc = 0;
+1 -1
include/linux/usb/hcd.h
··· 211 211 * a whole, not just the root hub; they're for PCI bus glue. 212 212 */ 213 213 /* called after suspending the hub, before entering D3 etc */ 214 - int (*pci_suspend)(struct usb_hcd *hcd); 214 + int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup); 215 215 216 216 /* called after entering D0 (etc), before resuming the hub */ 217 217 int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);