From c96e31252110a84dcc44412e8a7b456b33c3e298 Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 24 Sep 2024 15:02:08 +0530 Subject: [PATCH] usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG DWC3 programming guide mentions that when operating in USB2.0 speeds, if GUSB2PHYCFG[6] or GUSB2PHYCFG[8] is set, it must be cleared prior to issuing commands and may be set again after the command completes. But currently while issuing EndXfer command without CmdIOC set, we wait for 1ms after GUSB2PHYCFG is restored. This results in cases where EndXfer command doesn't get completed and causes SMMU faults since requests are unmapped afterwards. Hence restore GUSB2PHYCFG after waiting for EndXfer command completion. Cc: stable@vger.kernel.org Fixes: 1d26ba0944d3 ("usb: dwc3: Wait unconditionally after issuing EndXfer command") Signed-off-by: Prashanth K Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20240924093208.2524531-1-quic_prashk@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 10178e5eda5a..4959c26d3b71 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -438,6 +438,10 @@ skip_status: dwc3_gadget_ep_get_transfer_index(dep); } + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && + !(cmd & DWC3_DEPCMD_CMDIOC)) + mdelay(1); + if (saved_config) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= saved_config; @@ -1715,12 +1719,10 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int WARN_ON_ONCE(ret); dep->resource_index = 0; - if (!interrupt) { - mdelay(1); + if (!interrupt) dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - } else if (!ret) { + else if (!ret) dep->flags |= DWC3_EP_END_TRANSFER_PENDING; - } dep->flags &= ~DWC3_EP_DELAY_STOP; return ret; -- 2.51.0