diff options
| -rw-r--r-- | drivers/usb/core/driver.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 6a3b5cae3a6e..64b91d6c5a5d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -1263,13 +1263,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
| 1263 | return status; | 1263 | return status; |
| 1264 | } | 1264 | } |
| 1265 | 1265 | ||
| 1266 | static void choose_wakeup(struct usb_device *udev, pm_message_t msg) | ||
| 1267 | { | ||
| 1268 | int w, i; | ||
| 1269 | struct usb_interface *intf; | ||
| 1270 | |||
| 1271 | /* Remote wakeup is needed only when we actually go to sleep. | ||
| 1272 | * For things like FREEZE and QUIESCE, if the device is already | ||
| 1273 | * autosuspended then its current wakeup setting is okay. | ||
| 1274 | */ | ||
| 1275 | if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { | ||
| 1276 | if (udev->state != USB_STATE_SUSPENDED) | ||
| 1277 | udev->do_remote_wakeup = 0; | ||
| 1278 | return; | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | /* If remote wakeup is permitted, see whether any interface drivers | ||
| 1282 | * actually want it. | ||
| 1283 | */ | ||
| 1284 | w = 0; | ||
| 1285 | if (device_may_wakeup(&udev->dev) && udev->actconfig) { | ||
| 1286 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | ||
| 1287 | intf = udev->actconfig->interface[i]; | ||
| 1288 | w |= intf->needs_remote_wakeup; | ||
| 1289 | } | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | /* If the device is autosuspended with the wrong wakeup setting, | ||
| 1293 | * autoresume now so the setting can be changed. | ||
| 1294 | */ | ||
| 1295 | if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup) | ||
| 1296 | pm_runtime_resume(&udev->dev); | ||
| 1297 | udev->do_remote_wakeup = w; | ||
| 1298 | } | ||
| 1299 | |||
| 1266 | /* The device lock is held by the PM core */ | 1300 | /* The device lock is held by the PM core */ |
| 1267 | int usb_suspend(struct device *dev, pm_message_t msg) | 1301 | int usb_suspend(struct device *dev, pm_message_t msg) |
| 1268 | { | 1302 | { |
| 1269 | struct usb_device *udev = to_usb_device(dev); | 1303 | struct usb_device *udev = to_usb_device(dev); |
| 1270 | 1304 | ||
| 1271 | do_unbind_rebind(udev, DO_UNBIND); | 1305 | do_unbind_rebind(udev, DO_UNBIND); |
| 1272 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | 1306 | choose_wakeup(udev, msg); |
| 1273 | return usb_suspend_both(udev, msg); | 1307 | return usb_suspend_both(udev, msg); |
| 1274 | } | 1308 | } |
| 1275 | 1309 | ||
