[PATCH] root hub changes (lesser half)
This patch collects various small updates related to root hubs, to shrink later patches which build on them. - For root hub suspend/resume support: * Make the existing usb_hcd_resume_root_hub() routine respect pmcore locking, exporting and using the dpm_runtime_resume() method. * Add a new usb_hcd_suspend_root_hub() to pair with that routine. (Essential to make OHCI autosuspend behave again...) * HC_SUSPENDED by itself only refers to the root hub's downstream ports. So let HCDs see root hub URBs unless the parent device is suspended. - Remove an assertion we no longer need (and now, also don't want). - Generic suspend/resume updates to work better with swsusp. * Ignore the FREEZE vs SUSPEND distinction for hardware; trying to use it breaks the swsusp snapshots it's supposed to help (sigh). * On resume, mark devices as resumed right away, but then do nothing else if the device is marked NOTATTACHED. These changes shouldn't be very noticable by themselves. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/base/power/runtime.c | 1 drivers/usb/core/hcd.c | 64 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/core/hcd.h | 1 drivers/usb/core/hub.c | 45 ++++++++++++++++++++++++------ drivers/usb/core/usb.c | 20 +++++++++---- drivers/usb/core/usb.h | 1 6 files changed, 111 insertions(+), 21 deletions(-)
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9293677af3
commit
979d5199fe
@@ -1427,6 +1427,7 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
|
||||
|
||||
/* USB devices enter SUSPEND state through their hubs, but can be
|
||||
* marked for FREEZE as soon as their children are already idled.
|
||||
* But those semantics are useless, so we equate the two (sigh).
|
||||
*/
|
||||
if (dev->driver == &usb_generic_driver) {
|
||||
if (dev->power.power_state.event == message.event)
|
||||
@@ -1435,10 +1436,6 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
|
||||
status = device_for_each_child(dev, NULL, verify_suspended);
|
||||
if (status)
|
||||
return status;
|
||||
if (message.event == PM_EVENT_FREEZE) {
|
||||
dev->power.power_state = message;
|
||||
return 0;
|
||||
}
|
||||
return usb_suspend_device (to_usb_device(dev));
|
||||
}
|
||||
|
||||
@@ -1471,14 +1468,22 @@ static int usb_generic_resume(struct device *dev)
|
||||
{
|
||||
struct usb_interface *intf;
|
||||
struct usb_driver *driver;
|
||||
struct usb_device *udev;
|
||||
int status;
|
||||
|
||||
if (dev->power.power_state.event == PM_EVENT_ON)
|
||||
return 0;
|
||||
|
||||
/* mark things as "on" immediately, no matter what errors crop up */
|
||||
dev->power.power_state.event = PM_EVENT_ON;
|
||||
|
||||
/* devices resume through their hubs */
|
||||
if (dev->driver == &usb_generic_driver)
|
||||
if (dev->driver == &usb_generic_driver) {
|
||||
udev = to_usb_device(dev);
|
||||
if (udev->state == USB_STATE_NOTATTACHED)
|
||||
return 0;
|
||||
return usb_resume_device (to_usb_device(dev));
|
||||
}
|
||||
|
||||
if ((dev->driver == NULL) ||
|
||||
(dev->driver_data == &usb_generic_driver_data))
|
||||
@@ -1487,11 +1492,14 @@ static int usb_generic_resume(struct device *dev)
|
||||
intf = to_usb_interface(dev);
|
||||
driver = to_usb_driver(dev->driver);
|
||||
|
||||
udev = interface_to_usbdev(intf);
|
||||
if (udev->state == USB_STATE_NOTATTACHED)
|
||||
return 0;
|
||||
|
||||
/* if driver was suspended, it has a resume method;
|
||||
* however, sysfs can wrongly mark things as suspended
|
||||
* (on the "no suspend method" FIXME path above)
|
||||
*/
|
||||
mark_active(intf);
|
||||
if (driver->resume) {
|
||||
status = driver->resume(intf);
|
||||
if (status) {
|
||||
|
Reference in New Issue
Block a user