diff options
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r-- | drivers/usb/core/driver.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 3abb06955b2b..4a4e7ee84f0c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -1255,9 +1255,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1255 | udev->state == USB_STATE_SUSPENDED) | 1255 | udev->state == USB_STATE_SUSPENDED) |
1256 | goto done; | 1256 | goto done; |
1257 | 1257 | ||
1258 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | ||
1259 | |||
1260 | if (msg.event & PM_EVENT_AUTO) { | 1258 | if (msg.event & PM_EVENT_AUTO) { |
1259 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | ||
1261 | status = autosuspend_check(udev, 0); | 1260 | status = autosuspend_check(udev, 0); |
1262 | if (status < 0) | 1261 | if (status < 0) |
1263 | goto done; | 1262 | goto done; |
@@ -1789,6 +1788,34 @@ int usb_external_resume_device(struct usb_device *udev, pm_message_t msg) | |||
1789 | return status; | 1788 | return status; |
1790 | } | 1789 | } |
1791 | 1790 | ||
1791 | static void choose_wakeup(struct usb_device *udev, pm_message_t msg) | ||
1792 | { | ||
1793 | int w, i; | ||
1794 | struct usb_interface *intf; | ||
1795 | |||
1796 | /* Remote wakeup is needed only when we actually go to sleep. | ||
1797 | * For things like FREEZE and QUIESCE, if the device is already | ||
1798 | * autosuspended then its current wakeup setting is okay. | ||
1799 | */ | ||
1800 | if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { | ||
1801 | udev->do_remote_wakeup = 0; | ||
1802 | return; | ||
1803 | } | ||
1804 | |||
1805 | /* If remote wakeup is permitted, see whether any interface drivers | ||
1806 | * actually want it. | ||
1807 | */ | ||
1808 | w = 0; | ||
1809 | if (device_may_wakeup(&udev->dev) && udev->actconfig) { | ||
1810 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | ||
1811 | intf = udev->actconfig->interface[i]; | ||
1812 | w |= intf->needs_remote_wakeup; | ||
1813 | } | ||
1814 | } | ||
1815 | |||
1816 | udev->do_remote_wakeup = w; | ||
1817 | } | ||
1818 | |||
1792 | int usb_suspend(struct device *dev, pm_message_t msg) | 1819 | int usb_suspend(struct device *dev, pm_message_t msg) |
1793 | { | 1820 | { |
1794 | struct usb_device *udev; | 1821 | struct usb_device *udev; |
@@ -1808,6 +1835,7 @@ int usb_suspend(struct device *dev, pm_message_t msg) | |||
1808 | } | 1835 | } |
1809 | 1836 | ||
1810 | udev->skip_sys_resume = 0; | 1837 | udev->skip_sys_resume = 0; |
1838 | choose_wakeup(udev, msg); | ||
1811 | return usb_external_suspend_device(udev, msg); | 1839 | return usb_external_suspend_device(udev, msg); |
1812 | } | 1840 | } |
1813 | 1841 | ||