summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAnshuman Gupta <anshuman.gupta@intel.com>2017-10-05 11:21:46 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-05 11:01:58 +0200
commit0914ea66d24c045cdc4f424342057980e86629cf (patch)
tree8d383be02d03b918e6a50ca18da6cd8b464b28c0 /drivers/usb/host
parent651aaf36a7d7b36a58980e70133f9437d4f6d312 (diff)
usb: xhci: reduce device initiated resume time variance.
This patch will improve the variable auto-resume latency of an usb-port. The attempt to sync the start of root hub polling with resume time signaling finish was ruined by a later request to start immediate root hub polling. When xhci gets a port status change event interrupt due to PORT_PLC (port link state transition), linux Host controller driver drives the resume signalling on the bus for the amount of time defined by USB_REUME_TIMEOUT(40ms) macro. This 40ms delay for resume signalling is in acceptable limit, but it get worse when xhci goes for polling mode in order to detect other events on its ports and modify rh_timer timer with a variable time out of 1ms to (HZ/4)ms. drivers/usb/core/hcd.c line 799 mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)). Due to above variable timeout usb auto-resume latency varies from 40ms to ~300ms. Log Snippet: ~128ms latency [ 53.112049] hub 1-0:1.0: state 7 ports 12 chg 0000 evt 0000 [ 53.229200] hub 1-0:1.0: state 7 ports 12 chg 0000 evt 0004 [ 53.240177] usb 1-2: usb wakeup-resume [ 53.240195] usb 1-2: finish resume [ 53.240357] usb usb1-port2: resume, status 0 ----------------------------------------------------------------- ~300ms latency [ 59.946620] hub 1-0:1.0: state 7 ports 12 chg 0000 evt 0000 [ 59.979341] hub 1-0:1.0: state 7 ports 12 chg 0000 evt 0000 [ 60.229342] hub 1-0:1.0: state 7 ports 12 chg 0000 evt 0004 [ 60.251321] usb 1-2: usb wakeup-resume [ 60.251335] usb 1-2: finish resume [ 60.251539] usb usb1-port2: resume, status 0 This variable resume latency can be optimized, as in case of PORT_PLC change event rh_timer has already been modified with USB_RESUME_TIMEOUT (40ms) delay,leaving the rest to GetPortStatus and started polling for root hub status (invoking usb_hcd_poll_rh_status). We can avoid polling as we have already modified rh_timer with delay of 40ms. This patch set the HCD_FLAG_POLL_RH to hcd->flags after modification of rh_timer, and avoids polling of root hub status. so rh_timer can fire after 40ms and usb device auto-resuem latency will be around 40ms. [topic and first two senctences of commit message changed -Mathias] Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index a9443651ce0f..15afe1e37816 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1679,9 +1679,14 @@ static void handle_port_status(struct xhci_hcd *xhci,
bus_state->resume_done[faked_port_index] = jiffies +
msecs_to_jiffies(USB_RESUME_TIMEOUT);
set_bit(faked_port_index, &bus_state->resuming_ports);
+ /* Do the rest in GetPortStatus after resume time delay.
+ * Avoid polling roothub status before that so that a
+ * usb device auto-resume latency around ~40ms.
+ */
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
mod_timer(&hcd->rh_timer,
bus_state->resume_done[faked_port_index]);
- /* Do the rest in GetPortStatus */
+ bogus_port_status = true;
}
}