diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2008-11-25 16:39:18 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-07 13:00:03 -0500 |
commit | 65bfd2967c906ca322a4bb69a285fe0de8916ac6 (patch) | |
tree | ddd3293f945613d0d27ec1dbd36030c079fb9492 /drivers/usb/core/hub.c | |
parent | 4ec06d629628b6e5c7ff50d349a26ef5c35696e3 (diff) |
USB: Enhance usage of pm_message_t
This patch (as1177) modifies the USB core suspend and resume
routines. The resume functions now will take a pm_message_t argument,
so they will know what sort of resume is occurring. The new argument
is also passed to the port suspend/resume and bus suspend/resume
routines (although they don't use it for anything but debugging).
In addition, special pm_message_t values are used for user-initiated,
device-initiated (i.e., remote wakeup), and automatic suspend/resume.
By testing these values, drivers can tell whether or not a particular
suspend was an autosuspend. Unfortunately, they can't do the same for
resumes -- not until the pm_message_t argument is also passed to the
drivers' resume methods. That will require a bigger change.
IMO, the whole Power Management framework should have been set up this
way in the first place.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index ff066edf4dc..fc99ef67761 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1984,7 +1984,7 @@ static int check_port_resume_type(struct usb_device *udev, | |||
1984 | * | 1984 | * |
1985 | * Returns 0 on success, else negative errno. | 1985 | * Returns 0 on success, else negative errno. |
1986 | */ | 1986 | */ |
1987 | int usb_port_suspend(struct usb_device *udev) | 1987 | int usb_port_suspend(struct usb_device *udev, pm_message_t msg) |
1988 | { | 1988 | { |
1989 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 1989 | struct usb_hub *hub = hdev_to_hub(udev->parent); |
1990 | int port1 = udev->portnum; | 1990 | int port1 = udev->portnum; |
@@ -2023,7 +2023,7 @@ int usb_port_suspend(struct usb_device *udev) | |||
2023 | } else { | 2023 | } else { |
2024 | /* device has up to 10 msec to fully suspend */ | 2024 | /* device has up to 10 msec to fully suspend */ |
2025 | dev_dbg(&udev->dev, "usb %ssuspend\n", | 2025 | dev_dbg(&udev->dev, "usb %ssuspend\n", |
2026 | udev->auto_pm ? "auto-" : ""); | 2026 | (msg.event & PM_EVENT_AUTO ? "auto-" : "")); |
2027 | usb_set_device_state(udev, USB_STATE_SUSPENDED); | 2027 | usb_set_device_state(udev, USB_STATE_SUSPENDED); |
2028 | msleep(10); | 2028 | msleep(10); |
2029 | } | 2029 | } |
@@ -2142,7 +2142,7 @@ static int finish_port_resume(struct usb_device *udev) | |||
2142 | * | 2142 | * |
2143 | * Returns 0 on success, else negative errno. | 2143 | * Returns 0 on success, else negative errno. |
2144 | */ | 2144 | */ |
2145 | int usb_port_resume(struct usb_device *udev) | 2145 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) |
2146 | { | 2146 | { |
2147 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 2147 | struct usb_hub *hub = hdev_to_hub(udev->parent); |
2148 | int port1 = udev->portnum; | 2148 | int port1 = udev->portnum; |
@@ -2167,7 +2167,7 @@ int usb_port_resume(struct usb_device *udev) | |||
2167 | } else { | 2167 | } else { |
2168 | /* drive resume for at least 20 msec */ | 2168 | /* drive resume for at least 20 msec */ |
2169 | dev_dbg(&udev->dev, "usb %sresume\n", | 2169 | dev_dbg(&udev->dev, "usb %sresume\n", |
2170 | udev->auto_pm ? "auto-" : ""); | 2170 | (msg.event & PM_EVENT_AUTO ? "auto-" : "")); |
2171 | msleep(25); | 2171 | msleep(25); |
2172 | 2172 | ||
2173 | /* Virtual root hubs can trigger on GET_PORT_STATUS to | 2173 | /* Virtual root hubs can trigger on GET_PORT_STATUS to |
@@ -2208,7 +2208,7 @@ static int remote_wakeup(struct usb_device *udev) | |||
2208 | if (udev->state == USB_STATE_SUSPENDED) { | 2208 | if (udev->state == USB_STATE_SUSPENDED) { |
2209 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); | 2209 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); |
2210 | usb_mark_last_busy(udev); | 2210 | usb_mark_last_busy(udev); |
2211 | status = usb_external_resume_device(udev); | 2211 | status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME); |
2212 | } | 2212 | } |
2213 | return status; | 2213 | return status; |
2214 | } | 2214 | } |
@@ -2217,14 +2217,14 @@ static int remote_wakeup(struct usb_device *udev) | |||
2217 | 2217 | ||
2218 | /* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */ | 2218 | /* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */ |
2219 | 2219 | ||
2220 | int usb_port_suspend(struct usb_device *udev) | 2220 | int usb_port_suspend(struct usb_device *udev, pm_message_t msg) |
2221 | { | 2221 | { |
2222 | return 0; | 2222 | return 0; |
2223 | } | 2223 | } |
2224 | 2224 | ||
2225 | /* However we may need to do a reset-resume */ | 2225 | /* However we may need to do a reset-resume */ |
2226 | 2226 | ||
2227 | int usb_port_resume(struct usb_device *udev) | 2227 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) |
2228 | { | 2228 | { |
2229 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 2229 | struct usb_hub *hub = hdev_to_hub(udev->parent); |
2230 | int port1 = udev->portnum; | 2230 | int port1 = udev->portnum; |
@@ -2264,7 +2264,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
2264 | 2264 | ||
2265 | udev = hdev->children [port1-1]; | 2265 | udev = hdev->children [port1-1]; |
2266 | if (udev && udev->can_submit) { | 2266 | if (udev && udev->can_submit) { |
2267 | if (!hdev->auto_pm) | 2267 | if (!(msg.event & PM_EVENT_AUTO)) |
2268 | dev_dbg(&intf->dev, "port %d nyet suspended\n", | 2268 | dev_dbg(&intf->dev, "port %d nyet suspended\n", |
2269 | port1); | 2269 | port1); |
2270 | return -EBUSY; | 2270 | return -EBUSY; |