[PATCH] OHCI PM updates
This simplifies the OHCI root hub suspend logic: - Uses new usbcore root hub calls to make autosuspend work again: * Uses a newish usbcore root hub wakeup mechanism, making requests to khubd not keventd. * Uses an even newer sibling suspend hook. - Expect someone always made usbcore call ohci_hub_suspend() before bus glue fires; and that ohci_hub_resume() is only called after that bus glue ran. Previously, only CONFIG_USB_SUSPEND promised those things. (Includes updates to PCI and OMAP bus glue.) - Handle a not-noticed-before special case during resume from one of the swsusp snapshots when using "usb-handoff": the controller isn't left in RESET state. (A bug to fix in the usb-handoff code...) Also cleans up a minor debug printk glitch, and switches an mdelay over to an msleep (how did that stick around for so long?). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/usb/host/ohci-dbg.c | 4 ---- drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 42 ++++++++++++------------------------------ drivers/usb/host/ohci-mem.c | 1 - drivers/usb/host/ohci-omap.c | 36 ++++++++++++------------------------ drivers/usb/host/ohci-pci.c | 40 ++++++++-------------------------------- drivers/usb/host/ohci.h | 1 - 7 files changed, 33 insertions(+), 93 deletions(-)
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5f827ea3c3
commit
f197b2c54b
@@ -458,41 +458,29 @@ static int ohci_hcd_omap_drv_remove(struct device *dev)
|
||||
static int ohci_omap_suspend(struct device *dev, pm_message_t message)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
|
||||
int status = -EINVAL;
|
||||
|
||||
down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
|
||||
status = ohci_hub_suspend(ohci_to_hcd(ohci));
|
||||
if (status == 0) {
|
||||
omap_ohci_clock_power(0);
|
||||
ohci_to_hcd(ohci)->self.root_hub->state =
|
||||
USB_STATE_SUSPENDED;
|
||||
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
||||
dev->power.power_state = PMSG_SUSPEND;
|
||||
}
|
||||
up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
|
||||
return status;
|
||||
if (time_before(jiffies, ohci->next_statechange))
|
||||
msleep(5);
|
||||
ohci->next_statechange = jiffies;
|
||||
|
||||
omap_ohci_clock_power(0);
|
||||
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
||||
dev->power.power_state = PMSG_SUSPEND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ohci_omap_resume(struct device *dev)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
|
||||
int status = 0;
|
||||
|
||||
if (time_before(jiffies, ohci->next_statechange))
|
||||
msleep(5);
|
||||
ohci->next_statechange = jiffies;
|
||||
|
||||
omap_ohci_clock_power(1);
|
||||
#ifdef CONFIG_USB_SUSPEND
|
||||
/* get extra cleanup even if remote wakeup isn't in use */
|
||||
status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
|
||||
#else
|
||||
down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
|
||||
status = ohci_hub_resume(ohci_to_hcd(ohci));
|
||||
up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
|
||||
#endif
|
||||
if (status == 0)
|
||||
dev->power.power_state = PMSG_ON;
|
||||
return status;
|
||||
dev->power.power_state = PMSG_ON;
|
||||
usb_hcd_resume_root_hub(dev_get_drvdata(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user