aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2010-01-06 09:56:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:53:35 -0500
commit16985408b5c48585762ec3b9b7bae1dec4ad7437 (patch)
tree1db9d25a5e4319c3fb85d9e71a736e76ad8dc0b0 /drivers/usb/core/hub.c
parentce126644aa10bf1d8f1c1929b65adab026095761 (diff)
USB: retain USB device power/wakeup setting across reconfiguration
Currently a non-root-hub USB device's wakeup settings are initialized when the device is set to a configured state using device_init_wakeup(), but this is not correct as wakeup is split into "capable" (can_wakeup) and "enabled" (should_wakeup). The settings should be initialized instead in the device initialization (usb_new_device) with the "capable" setting disabled and the "enabled" setting enabled. The "capable" setting should be set based on the device being configured or unconfigured, and "enabled" setting set based on the sysfs power/wakeup control. This patch retains the sysfs power/wakeup setting of a non-root-hub USB device over a USB device re-configuration, which can happen (for example) after a suspend/resume cycle. Signed-off-by: Dan Streetman <ddstreet@ieee.org> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: 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.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bb416cdee1a7..6f84d383ecee 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1448,11 +1448,11 @@ void usb_set_device_state(struct usb_device *udev,
1448 || new_state == USB_STATE_SUSPENDED) 1448 || new_state == USB_STATE_SUSPENDED)
1449 ; /* No change to wakeup settings */ 1449 ; /* No change to wakeup settings */
1450 else if (new_state == USB_STATE_CONFIGURED) 1450 else if (new_state == USB_STATE_CONFIGURED)
1451 device_init_wakeup(&udev->dev, 1451 device_set_wakeup_capable(&udev->dev,
1452 (udev->actconfig->desc.bmAttributes 1452 (udev->actconfig->desc.bmAttributes
1453 & USB_CONFIG_ATT_WAKEUP)); 1453 & USB_CONFIG_ATT_WAKEUP));
1454 else 1454 else
1455 device_init_wakeup(&udev->dev, 0); 1455 device_set_wakeup_capable(&udev->dev, 0);
1456 } 1456 }
1457 if (udev->state == USB_STATE_SUSPENDED && 1457 if (udev->state == USB_STATE_SUSPENDED &&
1458 new_state != USB_STATE_SUSPENDED) 1458 new_state != USB_STATE_SUSPENDED)
@@ -1799,10 +1799,18 @@ int usb_new_device(struct usb_device *udev)
1799{ 1799{
1800 int err; 1800 int err;
1801 1801
1802 /* Increment the parent's count of unsuspended children */ 1802 if (udev->parent) {
1803 if (udev->parent) 1803 /* Increment the parent's count of unsuspended children */
1804 usb_autoresume_device(udev->parent); 1804 usb_autoresume_device(udev->parent);
1805 1805
1806 /* Initialize non-root-hub device wakeup to disabled;
1807 * device (un)configuration controls wakeup capable
1808 * sysfs power/wakeup controls wakeup enabled/disabled
1809 */
1810 device_init_wakeup(&udev->dev, 0);
1811 device_set_wakeup_enable(&udev->dev, 1);
1812 }
1813
1806 usb_detect_quirks(udev); 1814 usb_detect_quirks(udev);
1807 err = usb_enumerate_device(udev); /* Read descriptors */ 1815 err = usb_enumerate_device(udev); /* Read descriptors */
1808 if (err < 0) 1816 if (err < 0)