--- /dev/null
+From c4e3ef5685393c5051b52cf1e94b8891d49793ab Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 8 Dec 2022 16:50:35 -0800
+Subject: usb: dwc3: gadget: Ignore End Transfer delay on teardown
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit c4e3ef5685393c5051b52cf1e94b8891d49793ab upstream.
+
+If we delay sending End Transfer for Setup TRB to be prepared, we need
+to check if the End Transfer was in preparation for a driver
+teardown/soft-disconnect. In those cases, just send the End Transfer
+command without delay.
+
+In the case of soft-disconnect, there's a very small chance the command
+may not go through immediately. But should it happen, the Setup TRB will
+be prepared during the polling of the controller halted state, allowing
+the command to go through then.
+
+In the case of disabling endpoint due to reconfiguration (e.g.
+set_interface(alt-setting) or usb reset), then it's driven by the host.
+Typically the host wouldn't immediately cancel the control request and
+send another control transfer to trigger the End Transfer command
+timeout.
+
+Fixes: 4db0fbb60136 ("usb: dwc3: gadget: Don't delay End Transfer on delayed_status")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/f1617a323e190b9cc408fb8b65456e32b5814113.1670546756.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1701,6 +1701,7 @@ static int __dwc3_stop_active_transfer(s
+ dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+ }
+
++ dep->flags &= ~DWC3_EP_DELAY_STOP;
+ return ret;
+ }
+
+@@ -3710,8 +3711,10 @@ void dwc3_stop_active_transfer(struct dw
+ if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
+ return;
+
++ if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
++ return;
++
+ if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+- (dep->flags & DWC3_EP_DELAY_STOP) ||
+ (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+ return;
+