From 58450a28b9ec46b94022261942fc3515433324c1 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Thu, 3 Oct 2019 18:55:48 +0530 Subject: [PATCH] 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: Pratham Pratap --- drivers/usb/dwc3/gadget.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 77952ea656fd..401b9271a455 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2031,7 +2031,6 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) * device controller. */ dwc3_stop_active_transfers(dwc); - dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEAR, 0); reg &= ~DWC3_DCTL_RUN_STOP; @@ -2041,14 +2040,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");