USB: Avoid runtime suspend loops for HCDs that can't handle suspend/resume
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 23 May 2014 14:45:54 +0000 (10:45 -0400)
committerBen Hutchings <ben@decadent.org.uk>
Fri, 11 Jul 2014 12:33:36 +0000 (13:33 +0100)
commit502c1d6c3e8bbf4fd9152348ee65c439f37596b8
tree843204f20190e3064efb5af8e6b27725e73f268b
parent6733fc4b7822e896f6a0fae44c92a28e7fc3d77f
USB: Avoid runtime suspend loops for HCDs that can't handle suspend/resume

commit 8ef42ddd9a53b73e6fc3934278710c27f80f324f upstream.

Not all host controller drivers have bus-suspend and bus-resume
methods.  When one doesn't, it will cause problems if runtime PM is
enabled in the kernel.  The PM core will attempt to suspend the
controller's root hub, the suspend will fail because there is no
bus-suspend routine, and a -EBUSY error code will be returned to the
PM core.  This will cause the suspend attempt to be repeated shortly
thereafter, in a never-ending loop.

Part of the problem is that the original error code -ENOENT gets
changed to -EBUSY in usb_runtime_suspend(), on the grounds that the PM
core will interpret -ENOENT as meaning that the root hub has gotten
into a runtime-PM error state.  While this change is appropriate for
real USB devices, it's not such a good idea for a root hub.  In fact,
considering the root hub to be in a runtime-PM error state would not
be far from the truth.  Therefore this patch updates
usb_runtime_suspend() so that it adjusts error codes only for
non-root-hub devices.

Furthermore, the patch attempts to prevent the problem from occurring
in the first place by not enabling runtime PM by default for root hubs
whose host controller driver doesn't have bus_suspend and bus_resume
methods.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Will Deacon <will.deacon@arm.com>
Tested-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: runtime PM is also not supported for USB 3.0
 non-root hubs]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/core/driver.c
drivers/usb/core/hub.c