aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/hcd-pci.c11
-rw-r--r--drivers/usb/core/hcd.c40
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c22
4 files changed, 48 insertions, 27 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 29b5b2a6e183..e0afb5ad29e5 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -264,14 +264,19 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
264 */ 264 */
265 retval = pci_set_power_state (dev, PCI_D3hot); 265 retval = pci_set_power_state (dev, PCI_D3hot);
266 if (retval == 0) { 266 if (retval == 0) {
267 dev_dbg (hcd->self.controller, "--> PCI D3\n"); 267 int wake = device_can_wakeup(&hcd->self.root_hub->dev);
268
269 wake = wake && device_may_wakeup(hcd->self.controller);
270
271 dev_dbg (hcd->self.controller, "--> PCI D3%s\n",
272 wake ? "/wakeup" : "");
268 273
269 /* Ignore these return values. We rely on pci code to 274 /* Ignore these return values. We rely on pci code to
270 * reject requests the hardware can't implement, rather 275 * reject requests the hardware can't implement, rather
271 * than coding the same thing. 276 * than coding the same thing.
272 */ 277 */
273 (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); 278 (void) pci_enable_wake (dev, PCI_D3hot, wake);
274 (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); 279 (void) pci_enable_wake (dev, PCI_D3cold, wake);
275 } else { 280 } else {
276 dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", 281 dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
277 retval); 282 retval);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 6368562d73ca..a98d978d76e2 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -367,21 +367,39 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
367 367
368 /* DEVICE REQUESTS */ 368 /* DEVICE REQUESTS */
369 369
370 /* The root hub's remote wakeup enable bit is implemented using
371 * driver model wakeup flags. If this system supports wakeup
372 * through USB, userspace may change the default "allow wakeup"
373 * policy through sysfs or these calls.
374 *
375 * Most root hubs support wakeup from downstream devices, for
376 * runtime power management (disabling USB clocks and reducing
377 * VBUS power usage). However, not all of them do so; silicon,
378 * board, and BIOS bugs here are not uncommon, so these can't
379 * be treated quite like external hubs.
380 *
381 * Likewise, not all root hubs will pass wakeup events upstream,
382 * to wake up the whole system. So don't assume root hub and
383 * controller capabilities are identical.
384 */
385
370 case DeviceRequest | USB_REQ_GET_STATUS: 386 case DeviceRequest | USB_REQ_GET_STATUS:
371 tbuf [0] = (hcd->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP) 387 tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev)
388 << USB_DEVICE_REMOTE_WAKEUP)
372 | (1 << USB_DEVICE_SELF_POWERED); 389 | (1 << USB_DEVICE_SELF_POWERED);
373 tbuf [1] = 0; 390 tbuf [1] = 0;
374 len = 2; 391 len = 2;
375 break; 392 break;
376 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: 393 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
377 if (wValue == USB_DEVICE_REMOTE_WAKEUP) 394 if (wValue == USB_DEVICE_REMOTE_WAKEUP)
378 hcd->remote_wakeup = 0; 395 device_set_wakeup_enable(&hcd->self.root_hub->dev, 0);
379 else 396 else
380 goto error; 397 goto error;
381 break; 398 break;
382 case DeviceOutRequest | USB_REQ_SET_FEATURE: 399 case DeviceOutRequest | USB_REQ_SET_FEATURE:
383 if (hcd->can_wakeup && wValue == USB_DEVICE_REMOTE_WAKEUP) 400 if (device_can_wakeup(&hcd->self.root_hub->dev)
384 hcd->remote_wakeup = 1; 401 && wValue == USB_DEVICE_REMOTE_WAKEUP)
402 device_set_wakeup_enable(&hcd->self.root_hub->dev, 1);
385 else 403 else
386 goto error; 404 goto error;
387 break; 405 break;
@@ -410,7 +428,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
410 bufp = fs_rh_config_descriptor; 428 bufp = fs_rh_config_descriptor;
411 len = sizeof fs_rh_config_descriptor; 429 len = sizeof fs_rh_config_descriptor;
412 } 430 }
413 if (hcd->can_wakeup) 431 if (device_can_wakeup(&hcd->self.root_hub->dev))
414 patch_wakeup = 1; 432 patch_wakeup = 1;
415 break; 433 break;
416 case USB_DT_STRING << 8: 434 case USB_DT_STRING << 8:
@@ -1804,16 +1822,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
1804 device_init_wakeup(&rhdev->dev, 1822 device_init_wakeup(&rhdev->dev,
1805 device_can_wakeup(hcd->self.controller)); 1823 device_can_wakeup(hcd->self.controller));
1806 1824
1807 // ... all these hcd->*_wakeup flags will vanish 1825 /* NOTE: root hub and controller capabilities may not be the same */
1808 hcd->can_wakeup = device_can_wakeup(hcd->self.controller); 1826 if (device_can_wakeup(hcd->self.controller)
1809 1827 && device_can_wakeup(&hcd->self.root_hub->dev))
1810 /* hcd->driver->reset() reported can_wakeup, probably with
1811 * assistance from board's boot firmware.
1812 * NOTE: normal devices won't enable wakeup by default.
1813 */
1814 if (hcd->can_wakeup)
1815 dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); 1828 dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
1816 hcd->remote_wakeup = hcd->can_wakeup;
1817 1829
1818 /* enable irqs just before we start the controller */ 1830 /* enable irqs just before we start the controller */
1819 if (hcd->driver->irq) { 1831 if (hcd->driver->irq) {
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index f44a2fe62a9d..7022aafb2ae8 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -78,8 +78,6 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
78#define HCD_FLAG_HW_ACCESSIBLE 0x00000001 78#define HCD_FLAG_HW_ACCESSIBLE 0x00000001
79#define HCD_FLAG_SAW_IRQ 0x00000002 79#define HCD_FLAG_SAW_IRQ 0x00000002
80 80
81 unsigned can_wakeup:1; /* hw supports wakeup? */
82 unsigned remote_wakeup:1;/* sw should use wakeup? */
83 unsigned rh_registered:1;/* is root hub registered? */ 81 unsigned rh_registered:1;/* is root hub registered? */
84 82
85 /* The next flag is a stopgap, to be removed when all the HCDs 83 /* The next flag is a stopgap, to be removed when all the HCDs
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 867fa8130238..f1d64d4bbf5f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1006,12 +1006,18 @@ void usb_set_device_state(struct usb_device *udev,
1006 ; /* do nothing */ 1006 ; /* do nothing */
1007 else if (new_state != USB_STATE_NOTATTACHED) { 1007 else if (new_state != USB_STATE_NOTATTACHED) {
1008 udev->state = new_state; 1008 udev->state = new_state;
1009 if (new_state == USB_STATE_CONFIGURED) 1009
1010 device_init_wakeup(&udev->dev, 1010 /* root hub wakeup capabilities are managed out-of-band
1011 (udev->actconfig->desc.bmAttributes 1011 * and may involve silicon errata ... ignore them here.
1012 & USB_CONFIG_ATT_WAKEUP)); 1012 */
1013 else if (new_state != USB_STATE_SUSPENDED) 1013 if (udev->parent) {
1014 device_init_wakeup(&udev->dev, 0); 1014 if (new_state == USB_STATE_CONFIGURED)
1015 device_init_wakeup(&udev->dev,
1016 (udev->actconfig->desc.bmAttributes
1017 & USB_CONFIG_ATT_WAKEUP));
1018 else if (new_state != USB_STATE_SUSPENDED)
1019 device_init_wakeup(&udev->dev, 0);
1020 }
1015 } else 1021 } else
1016 recursively_mark_NOTATTACHED(udev); 1022 recursively_mark_NOTATTACHED(udev);
1017 spin_unlock_irqrestore(&device_state_lock, flags); 1023 spin_unlock_irqrestore(&device_state_lock, flags);
@@ -1877,9 +1883,9 @@ int usb_resume_device(struct usb_device *udev)
1877 if (udev->state == USB_STATE_NOTATTACHED) 1883 if (udev->state == USB_STATE_NOTATTACHED)
1878 return -ENODEV; 1884 return -ENODEV;
1879 1885
1880#ifdef CONFIG_USB_SUSPEND
1881 /* selective resume of one downstream hub-to-device port */ 1886 /* selective resume of one downstream hub-to-device port */
1882 if (udev->parent) { 1887 if (udev->parent) {
1888#ifdef CONFIG_USB_SUSPEND
1883 if (udev->state == USB_STATE_SUSPENDED) { 1889 if (udev->state == USB_STATE_SUSPENDED) {
1884 // NOTE swsusp may bork us, device state being wrong... 1890 // NOTE swsusp may bork us, device state being wrong...
1885 // NOTE this fails if parent is also suspended... 1891 // NOTE this fails if parent is also suspended...
@@ -1887,8 +1893,8 @@ int usb_resume_device(struct usb_device *udev)
1887 udev->portnum, udev); 1893 udev->portnum, udev);
1888 } else 1894 } else
1889 status = 0; 1895 status = 0;
1890 } else
1891#endif 1896#endif
1897 } else
1892 status = finish_device_resume(udev); 1898 status = finish_device_resume(udev);
1893 if (status < 0) 1899 if (status < 0)
1894 dev_dbg(&udev->dev, "can't resume, status %d\n", 1900 dev_dbg(&udev->dev, "can't resume, status %d\n",