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/hub.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/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 660064466791..3c8d8d1f993c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -449,11 +449,18 @@ static void hub_power_on(struct usb_hub *hub) | |||
449 | msleep(max(pgood_delay, (unsigned) 100)); | 449 | msleep(max(pgood_delay, (unsigned) 100)); |
450 | } | 450 | } |
451 | 451 | ||
452 | static void hub_quiesce(struct usb_hub *hub) | 452 | static inline void __hub_quiesce(struct usb_hub *hub) |
453 | { | 453 | { |
454 | /* stop khubd and related activity */ | 454 | /* (nonblocking) khubd and related activity won't re-trigger */ |
455 | hub->quiescing = 1; | 455 | hub->quiescing = 1; |
456 | hub->activating = 0; | 456 | hub->activating = 0; |
457 | hub->resume_root_hub = 0; | ||
458 | } | ||
459 | |||
460 | static void hub_quiesce(struct usb_hub *hub) | ||
461 | { | ||
462 | /* (blocking) stop khubd and related activity */ | ||
463 | __hub_quiesce(hub); | ||
457 | usb_kill_urb(hub->urb); | 464 | usb_kill_urb(hub->urb); |
458 | if (hub->has_indicators) | 465 | if (hub->has_indicators) |
459 | cancel_delayed_work(&hub->leds); | 466 | cancel_delayed_work(&hub->leds); |
@@ -467,6 +474,7 @@ static void hub_activate(struct usb_hub *hub) | |||
467 | 474 | ||
468 | hub->quiescing = 0; | 475 | hub->quiescing = 0; |
469 | hub->activating = 1; | 476 | hub->activating = 1; |
477 | hub->resume_root_hub = 0; | ||
470 | status = usb_submit_urb(hub->urb, GFP_NOIO); | 478 | status = usb_submit_urb(hub->urb, GFP_NOIO); |
471 | if (status < 0) | 479 | if (status < 0) |
472 | dev_err(hub->intfdev, "activate --> %d\n", status); | 480 | dev_err(hub->intfdev, "activate --> %d\n", status); |
@@ -1959,6 +1967,18 @@ static int hub_resume(struct usb_interface *intf) | |||
1959 | return 0; | 1967 | return 0; |
1960 | } | 1968 | } |
1961 | 1969 | ||
1970 | void usb_suspend_root_hub(struct usb_device *hdev) | ||
1971 | { | ||
1972 | struct usb_hub *hub = hdev_to_hub(hdev); | ||
1973 | |||
1974 | /* This also makes any led blinker stop retriggering. We're called | ||
1975 | * from irq, so the blinker might still be scheduled. Caller promises | ||
1976 | * that the root hub status URB will be canceled. | ||
1977 | */ | ||
1978 | __hub_quiesce(hub); | ||
1979 | mark_quiesced(to_usb_interface(hub->intfdev)); | ||
1980 | } | ||
1981 | |||
1962 | void usb_resume_root_hub(struct usb_device *hdev) | 1982 | void usb_resume_root_hub(struct usb_device *hdev) |
1963 | { | 1983 | { |
1964 | struct usb_hub *hub = hdev_to_hub(hdev); | 1984 | struct usb_hub *hub = hdev_to_hub(hdev); |
@@ -2616,21 +2636,30 @@ static void hub_events(void) | |||
2616 | intf = to_usb_interface(hub->intfdev); | 2636 | intf = to_usb_interface(hub->intfdev); |
2617 | hub_dev = &intf->dev; | 2637 | hub_dev = &intf->dev; |
2618 | 2638 | ||
2619 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", | 2639 | i = hub->resume_root_hub; |
2640 | |||
2641 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n", | ||
2620 | hdev->state, hub->descriptor | 2642 | hdev->state, hub->descriptor |
2621 | ? hub->descriptor->bNbrPorts | 2643 | ? hub->descriptor->bNbrPorts |
2622 | : 0, | 2644 | : 0, |
2623 | /* NOTE: expects max 15 ports... */ | 2645 | /* NOTE: expects max 15 ports... */ |
2624 | (u16) hub->change_bits[0], | 2646 | (u16) hub->change_bits[0], |
2625 | (u16) hub->event_bits[0]); | 2647 | (u16) hub->event_bits[0], |
2648 | i ? ", resume root" : ""); | ||
2626 | 2649 | ||
2627 | usb_get_intf(intf); | 2650 | usb_get_intf(intf); |
2628 | i = hub->resume_root_hub; | ||
2629 | spin_unlock_irq(&hub_event_lock); | 2651 | spin_unlock_irq(&hub_event_lock); |
2630 | 2652 | ||
2631 | /* Is this is a root hub wanting to be resumed? */ | 2653 | /* Is this is a root hub wanting to reactivate the downstream |
2632 | if (i) | 2654 | * ports? If so, be sure the interface resumes even if its |
2633 | usb_resume_device(hdev); | 2655 | * stub "device" node was never suspended. |
2656 | */ | ||
2657 | if (i) { | ||
2658 | extern void dpm_runtime_resume(struct device *); | ||
2659 | |||
2660 | dpm_runtime_resume(&hdev->dev); | ||
2661 | dpm_runtime_resume(&intf->dev); | ||
2662 | } | ||
2634 | 2663 | ||
2635 | /* Lock the device, then check to see if we were | 2664 | /* Lock the device, then check to see if we were |
2636 | * disconnected while waiting for the lock to succeed. */ | 2665 | * disconnected while waiting for the lock to succeed. */ |