diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d938b2b99e31..eb1d00a3543a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1196,9 +1196,14 @@ static int usb_resume_interface(struct usb_device *udev, * * This is the central routine for suspending USB devices. It calls the * suspend methods for all the interface drivers in @udev and then calls - * the suspend method for @udev itself. If an error occurs at any stage, - * all the interfaces which were suspended are resumed so that they remain - * in the same state as the device. + * the suspend method for @udev itself. When the routine is called in + * autosuspend, if an error occurs at any stage, all the interfaces + * which were suspended are resumed so that they remain in the same + * state as the device, but when called from system sleep, all error + * from suspend methods of interfaces and the non-root-hub device itself + * are simply ignored, so all suspended interfaces are only resumed + * to the device's state when @udev is root-hub and its suspend method + * returns failure. * * Autosuspend requests originating from a child device or an interface * driver may be made without the protection of @udev's device lock, but diff --git a/include/linux/usb.h b/include/linux/usb.h index 52464fb2389b..8d4bc173d66a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -976,7 +976,12 @@ struct usbdrv_wrap { * the "usbfs" filesystem. This lets devices provide ways to * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. - * @suspend: Called when the device is going to be suspended by the system. + * @suspend: Called when the device is going to be suspended by the + * system either from system sleep or runtime suspend context. The + * return value will be ignored in system sleep context, so do NOT + * try to continue using the device if suspend fails in this case. + * Instead, let the resume or reset-resume routine recover from + * the failure. * @resume: Called when the device is being resumed by the system. * @reset_resume: Called when the suspended device has been reset instead * of being resumed.