diff options
author | Lan Tianyu <tianyu.lan@intel.com> | 2013-01-23 00:26:30 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-25 22:14:20 +0400 |
commit | ad493e5e580546e6c3024b76a41535476da1546a (patch) | |
tree | 256edf0ac3bc23573c0daa0b66a985970c489f61 /drivers/usb/core/hub.h | |
parent | 971fcd492cebf544714f12d94549d2f0d2002645 (diff) | |
download | linux-ad493e5e580546e6c3024b76a41535476da1546a.tar.xz |
usb: add usb port auto power off mechanism
This patch is to add usb port auto power off mechanism.
When usb device is suspending, usb core will suspend usb port and
usb port runtime pm callback will clear PORT_POWER feature to
power off port if all conditions were met. These conditions are
remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist
enable. When it resumes, power on port again.
Add did_runtime_put in the struct usb_port to ensure
pm_runtime_get/put(portdev) to be called pairedly. Set did_runtime_put
to true when call pm_runtime_put(portdev) during suspending. The
pm_runtime_get(portdev) only will be called when did_runtime_put
is set to true during resuming. Set did_runtime_put to false after
calling pm_runtime_get(portdev).
Make clear_port_feature() and hdev_to_hub() as global symbol.
Rename clear_port_feature() to usb_clear_port_feature() and
hdev_to_hub() to usb_hub_to_struct_hub().
Extend hub_port_debounce() with the fuction of debouncing to
be connected. Add two wraps: hub_port_debounce_be_connected()
and hub_port_debouce_be_stable().
Increase HUB_DEBOUNCE_TIMEOUT to 2000 because some usb ssds
needs around 1.5 or more to make the hub port status to be
connected steadily after being powered off and powered on.
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/hub.h')
-rw-r--r-- | drivers/usb/core/hub.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 452e5cd7b249..80ab9ee07017 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -80,6 +80,8 @@ struct usb_hub { * @port_owner: port's owner * @connect_type: port's connect type * @portnum: port index num based one + * @power_is_on: port's power state + * @did_runtime_put: port has done pm_runtime_put(). */ struct usb_port { struct usb_device *child; @@ -87,6 +89,8 @@ struct usb_port { struct dev_state *port_owner; enum usb_port_connect_type connect_type; u8 portnum; + unsigned power_is_on:1; + unsigned did_runtime_put:1; }; #define to_usb_port(_dev) \ @@ -98,4 +102,21 @@ extern void usb_hub_remove_port_device(struct usb_hub *hub, int port1); extern int usb_hub_set_port_power(struct usb_device *hdev, int port1, bool set); +extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); +extern int hub_port_debounce(struct usb_hub *hub, int port1, + bool must_be_connected); +extern int usb_clear_port_feature(struct usb_device *hdev, + int port1, int feature); + +static inline int hub_port_debounce_be_connected(struct usb_hub *hub, + int port1) +{ + return hub_port_debounce(hub, port1, true); +} + +static inline int hub_port_debounce_be_stable(struct usb_hub *hub, + int port1) +{ + return hub_port_debounce(hub, port1, false); +} |