aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/usb.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-09-23 01:32:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 19:47:40 -0400
commit979d5199fee9e80290ddeb532e5993bd15506712 (patch)
tree6987772d41ec540b7e32beaa50c1493a95e3e2c8 /drivers/usb/core/usb.c
parent9293677af3dace2645dec0d0808efa02d36bf47b (diff)
[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(-)
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r--drivers/usb/core/usb.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e89dbd43e952..2493e7d9f5b3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1427,6 +1427,7 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
1427 1427
1428 /* USB devices enter SUSPEND state through their hubs, but can be 1428 /* USB devices enter SUSPEND state through their hubs, but can be
1429 * marked for FREEZE as soon as their children are already idled. 1429 * marked for FREEZE as soon as their children are already idled.
1430 * But those semantics are useless, so we equate the two (sigh).
1430 */ 1431 */
1431 if (dev->driver == &usb_generic_driver) { 1432 if (dev->driver == &usb_generic_driver) {
1432 if (dev->power.power_state.event == message.event) 1433 if (dev->power.power_state.event == message.event)
@@ -1435,10 +1436,6 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
1435 status = device_for_each_child(dev, NULL, verify_suspended); 1436 status = device_for_each_child(dev, NULL, verify_suspended);
1436 if (status) 1437 if (status)
1437 return status; 1438 return status;
1438 if (message.event == PM_EVENT_FREEZE) {
1439 dev->power.power_state = message;
1440 return 0;
1441 }
1442 return usb_suspend_device (to_usb_device(dev)); 1439 return usb_suspend_device (to_usb_device(dev));
1443 } 1440 }
1444 1441
@@ -1471,14 +1468,22 @@ static int usb_generic_resume(struct device *dev)
1471{ 1468{
1472 struct usb_interface *intf; 1469 struct usb_interface *intf;
1473 struct usb_driver *driver; 1470 struct usb_driver *driver;
1471 struct usb_device *udev;
1474 int status; 1472 int status;
1475 1473
1476 if (dev->power.power_state.event == PM_EVENT_ON) 1474 if (dev->power.power_state.event == PM_EVENT_ON)
1477 return 0; 1475 return 0;
1478 1476
1477 /* mark things as "on" immediately, no matter what errors crop up */
1478 dev->power.power_state.event = PM_EVENT_ON;
1479
1479 /* devices resume through their hubs */ 1480 /* devices resume through their hubs */
1480 if (dev->driver == &usb_generic_driver) 1481 if (dev->driver == &usb_generic_driver) {
1482 udev = to_usb_device(dev);
1483 if (udev->state == USB_STATE_NOTATTACHED)
1484 return 0;
1481 return usb_resume_device (to_usb_device(dev)); 1485 return usb_resume_device (to_usb_device(dev));
1486 }
1482 1487
1483 if ((dev->driver == NULL) || 1488 if ((dev->driver == NULL) ||
1484 (dev->driver_data == &usb_generic_driver_data)) 1489 (dev->driver_data == &usb_generic_driver_data))
@@ -1487,11 +1492,14 @@ static int usb_generic_resume(struct device *dev)
1487 intf = to_usb_interface(dev); 1492 intf = to_usb_interface(dev);
1488 driver = to_usb_driver(dev->driver); 1493 driver = to_usb_driver(dev->driver);
1489 1494
1495 udev = interface_to_usbdev(intf);
1496 if (udev->state == USB_STATE_NOTATTACHED)
1497 return 0;
1498
1490 /* if driver was suspended, it has a resume method; 1499 /* if driver was suspended, it has a resume method;
1491 * however, sysfs can wrongly mark things as suspended 1500 * however, sysfs can wrongly mark things as suspended
1492 * (on the "no suspend method" FIXME path above) 1501 * (on the "no suspend method" FIXME path above)
1493 */ 1502 */
1494 mark_active(intf);
1495 if (driver->resume) { 1503 if (driver->resume) {
1496 status = driver->resume(intf); 1504 status = driver->resume(intf);
1497 if (status) { 1505 if (status) {