summaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorDan Williams2014-05-21 03:08:12 +0200
committerGreg Kroah-Hartman2014-05-28 01:35:09 +0200
commit9262c19d14c433a6a1ba25c3ff897cb89e412309 (patch)
tree50f83b859b251a3e842953e4fb9619a05ece02da /drivers/usb/core/hub.c
parentUSB: mutual exclusion for resetting a hub and power-managing a port (diff)
downloadkernel-qcow2-linux-9262c19d14c433a6a1ba25c3ff897cb89e412309.tar.gz
kernel-qcow2-linux-9262c19d14c433a6a1ba25c3ff897cb89e412309.tar.xz
kernel-qcow2-linux-9262c19d14c433a6a1ba25c3ff897cb89e412309.zip
usb: disable port power control if not supported in wHubCharacteristics
A hub indicates whether it supports per-port power control via the wHubCharacteristics field in its descriptor. If it is not supported a hub will still emulate ClearPortPower(PORT_POWER) requests by stopping the link state machine. However, since this does not save power do not bother suspending. This also consolidates support checks into a hub_is_port_power_switchable() helper. Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c8
1 files changed, 2 insertions, 6 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5f43c22ba787..77b91888abef 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -818,8 +818,6 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
int port1;
unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
unsigned delay;
- u16 wHubCharacteristics =
- le16_to_cpu(hub->descriptor->wHubCharacteristics);
/* Enable power on each port. Some hubs have reserved values
* of LPSM (> 2) in their descriptors, even though they are
@@ -827,7 +825,7 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
* but only emulate it. In all cases, the ports won't work
* unless we send these messages to the hub.
*/
- if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2)
+ if (hub_is_port_power_switchable(hub))
dev_dbg(hub->intfdev, "enabling power on all ports\n");
else
dev_dbg(hub->intfdev, "trying to enable port power on "
@@ -4417,8 +4415,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
struct usb_device *hdev = hub->hdev;
struct device *hub_dev = hub->intfdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
- unsigned wHubCharacteristics =
- le16_to_cpu(hub->descriptor->wHubCharacteristics);
struct usb_device *udev;
int status, i;
unsigned unit_load;
@@ -4503,7 +4499,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
test_bit(port1, hub->removed_bits)) {
/* maybe switch power back on (e.g. root hub was reset) */
- if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
+ if (hub_is_port_power_switchable(hub)
&& !port_is_power_on(hub, portstatus))
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);