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

Commit 0a77934a authored by Pratham Pratap's avatar Pratham Pratap
Browse files

usb: dwc3: gadget: Clear pending events when stopping controller



After clearing run/stop bit there might be events still pending
with the controller which will not allow the controller to be
halted. Fix this by simply clearing GEVNTCOUNT(n) by reading and
writing back the counts.

Change-Id: Id93df8effe73b1765cced65590679b7df6c232da
Signed-off-by: default avatarPratham Pratap <prathampratap@codeaurora.org>
parent 771efa0c
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -899,8 +899,6 @@ static void dwc3_stop_active_transfers_to_halt(struct dwc3 *dwc)
		}
	}

	dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEAR, 0);

	dbg_log_string("DONE");
}

@@ -2129,14 +2127,25 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)

	dwc3_writel(dwc->regs, DWC3_DCTL, reg);

	/* Controller is not halted until the events are acknowledged */
	if (!is_on) {
		/*
		 * Clear out any pending events (i.e. End Transfer Command
		 * Complete).
		 */
		reg1 = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
		reg1 &= DWC3_GEVNTCOUNT_MASK;
		dbg_log_string("remaining EVNTCOUNT(0)=%d", reg1);
		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg1);
		dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEAR, 0);
		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_CLEAR_DB, 0);
	}

	do {
		reg = dwc3_readl(dwc->regs, DWC3_DSTS);
		reg &= DWC3_DSTS_DEVCTRLHLT;
	} while (--timeout && !(!is_on ^ !reg));

	if (!is_on)
		dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_CLEAR_DB, 0);

	if (!timeout) {
		dev_err(dwc->dev, "failed to %s controller\n",
				is_on ? "start" : "stop");