usb: force warm reset to break resume livelock

Resuming a powered down port sometimes results in the port state being
stuck in USB_SS_PORT_LS_POLLING:

 hub 3-0:1.0: debounce: port 1: total 2000ms stable 0ms status 0x2e0
 port1: can't get reconnection after setting port  power on, status -110
 hub 3-0:1.0: port 1 status 0000.02e0 after resume, -19
 usb 3-1: can't resume, status -19
 hub 3-0:1.0: logical disconnect on port 1

In the case above we wait 2 seconds for the port to reconnect and for
that entire time the port remained in the polling state.  A warm reset
triggers the device to reconnect and resume as normal.  With this patch
we get:

 hub 3-0:1.0: debounce: port 1: total 2000ms stable 0ms status 0x2e0
 usb usb3: port1 usb_port_runtime_resume requires warm reset
 hub 3-0:1.0: port 1 not warm reset yet, waiting 50ms
 usb 3-1: reset SuperSpeed USB device number 2 using xhci_hcd

With this in place we may want to consider reducing the timeout and
relying on warm reset for recovery.  Other xHCs that fail to propagate
warm resets on hub resume may want to trigger this behavior via a quirk.

Cc: Julius Werner <jwerner@chromium.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Vikas Sajjan <vikas.sajjan@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Vincent Palatin <vpalatin@chromium.org>
Cc: Lan Tianyu <tianyu.lan@intel.com>
Cc: Ksenia Ragiadakou <burzalodowa@gmail.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Douglas Anderson <dianders@chromium.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Sunil Joshi <joshi@samsung.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
3 files changed