From 286fd3fcbf748c2a7fa204bcb4618e6fe60c3ea1 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 8 Nov 2016 15:42:13 -0800 Subject: [PATCH 1/2] usb: core: Replace msleep with usleep_range Since usleep_range provides better accuracy in comparison to msleep. This helps in reducing the latency of host bus resume. Change-Id: Ie8d5231327fcc27ab2a28542e0d96687abb9aace Signed-off-by: Hemant Kumar --- drivers/usb/core/hub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 269c1ee2da44..515d34c091e1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3434,7 +3434,8 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) /* drive resume for USB_RESUME_TIMEOUT msec */ dev_dbg(&udev->dev, "usb %sresume\n", (PMSG_IS_AUTO(msg) ? "auto-" : "")); - msleep(USB_RESUME_TIMEOUT); + usleep_range(USB_RESUME_TIMEOUT * 1000, + (USB_RESUME_TIMEOUT + 1) * 1000); /* Virtual root hubs can trigger on GET_PORT_STATUS to * stop resume signaling. Then finish the resume @@ -3443,7 +3444,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) status = hub_port_status(hub, port1, &portstatus, &portchange); /* TRSMRCY = 10 msec */ - msleep(10); + usleep_range(10000, 10500); } SuspendCleared: From 49ba0d0ad43d530f141ab3995cdd7d7c5e00230d Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 8 Nov 2016 15:25:25 -0800 Subject: [PATCH 2/2] usb: core: Add support to skip extended bus resume delay By default skip_extended_resume_delay module parameter allows to skip extra 40ms delay upon usb bus resume. This delay was added on top of host bus resume which is driven for 20ms. Skipping extra delay reduces over all bus resume latency. Change-Id: I31a83abc057c345f29d204a63e7571b880678e69 Signed-off-by: Hemant Kumar --- drivers/usb/core/hub.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 515d34c091e1..5839111ab4e0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -48,6 +48,11 @@ static void hub_event(struct work_struct *work); /* synchronize hub-port add/remove and peering operations */ DEFINE_MUTEX(usb_port_peer_mutex); +static bool skip_extended_resume_delay = 1; +module_param(skip_extended_resume_delay, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(skip_extended_resume_delay, + "removes extra delay added to finish bus resume"); + /* cycle leds on hubs that aren't blinking for attention */ static bool blinkenlights = 0; module_param(blinkenlights, bool, S_IRUGO); @@ -3434,8 +3439,9 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) /* drive resume for USB_RESUME_TIMEOUT msec */ dev_dbg(&udev->dev, "usb %sresume\n", (PMSG_IS_AUTO(msg) ? "auto-" : "")); - usleep_range(USB_RESUME_TIMEOUT * 1000, - (USB_RESUME_TIMEOUT + 1) * 1000); + if (!skip_extended_resume_delay) + usleep_range(USB_RESUME_TIMEOUT * 1000, + (USB_RESUME_TIMEOUT + 1) * 1000); /* Virtual root hubs can trigger on GET_PORT_STATUS to * stop resume signaling. Then finish the resume