diff options
author | David Brownell <david-b@pacbell.net> | 2005-09-23 01:32:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:40 -0400 |
commit | 979d5199fee9e80290ddeb532e5993bd15506712 (patch) | |
tree | 6987772d41ec540b7e32beaa50c1493a95e3e2c8 /drivers/usb/core/usb.c | |
parent | 9293677af3dace2645dec0d0808efa02d36bf47b (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.c | 20 |
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) { |