Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68d796a5 authored by Hemant Kumar's avatar Hemant Kumar
Browse files

USB: xhci: Ensure 10 msec delay between bus states



Software must wait for at least 10 msec after a port
indicates that it is suspended before initiating a port
resume.  The current code uses jiffies and fails to give
the delay if suspend and resume happens at the timer tick
boundaries.

The correct implementation would be ensuring this delay by
using hrtimers or ktime_get(). This involves changing many
drivers. Hence workaround it by increasing the state change
delay to 2 jiffies.

CRs-Fixed: 625003
Change-Id: Ibb9f07d2d84e5ad8f09ed3232ad88b73833e8d7c
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 7198e5fb
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1306,6 +1306,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
	max_ports = xhci_get_ports(hcd, &port_array);
	bus_state = &xhci->bus_state[hcd_index(hcd)];

	if (time_before_eq(jiffies, bus_state->next_statechange))
		usleep_range(10000, 11000);

	spin_lock_irqsave(&xhci->lock, flags);

	if (hcd->self.root_hub->do_remote_wakeup) {
@@ -1398,8 +1401,8 @@ int xhci_bus_resume(struct usb_hcd *hcd)
	max_ports = xhci_get_ports(hcd, &port_array);
	bus_state = &xhci->bus_state[hcd_index(hcd)];

	if (time_before(jiffies, bus_state->next_statechange))
		msleep(5);
	if (time_before_eq(jiffies, bus_state->next_statechange))
		usleep_range(10000, 11000);

	spin_lock_irqsave(&xhci->lock, flags);
	if (!HCD_HW_ACCESSIBLE(hcd)) {
+5 −0
Original line number Diff line number Diff line
@@ -629,11 +629,16 @@ static int mxhci_hsic_bus_resume(struct usb_hcd *hcd)
{
	int ret;
	struct mxhci_hsic_hcd *mxhci = hcd_to_hsic(hcd->primary_hcd);
	struct xhci_bus_state *bus_state;

	if (!usb_hcd_is_primary_hcd(hcd))
		return 0;

	if (mxhci->resume_gpio) {
		bus_state = &mxhci->xhci->bus_state[hcd_index(hcd)];
		if (time_before_eq(jiffies, bus_state->next_statechange))
			usleep_range(10000, 11000);

		xhci_dbg_log_event(&dbg_hsic, NULL, "resume gpio high",
				readl_relaxed(MSM_HSIC_PORTSC));
		gpio_direction_output(mxhci->resume_gpio, 1);