diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index a411682e7f44..00348d6d479b 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -736,6 +736,7 @@ struct dwc3_ep {
 #define DWC3_EP_FIRST_STREAM_PRIMED	BIT(10)
 #define DWC3_EP_PENDING_CLEAR_STALL	BIT(11)
 #define DWC3_EP_TXFIFO_RESIZED		BIT(12)
+#define DWC3_EP_PENDING_DEQUEUE		BIT(13)
 
 	/* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN			BIT(31)
@@ -1272,6 +1273,7 @@ struct dwc3 {
 	unsigned		delayed_status:1;
 	unsigned		ep0_bounced:1;
 	unsigned		ep0_expect_in:1;
+	unsigned		ep_dequeue_pending:1;
 	unsigned		has_hibernation:1;
 	unsigned		sysdev_is_parent:1;
 	unsigned		has_lpm_erratum:1;
@@ -1553,6 +1555,7 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd,
 void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc);
 void dwc3_ep0_stall_and_restart(struct dwc3 *dwc);
 void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep);
+int dwc3_gadget_check_ep_dequeue(struct dwc3 *dwc);
 #else
 static inline int dwc3_gadget_init(struct dwc3 *dwc)
 { return 0; }
@@ -1579,6 +1582,8 @@ static inline void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 static inline void dwc3_ep0_end_control_data(struct dwc3 *dwc,
 					     struct dwc3_ep *dep)
 { }
+static inline int dwc3_gadget_check_ep_dequeue(struct dwc3 *dwc)
+{ return 0; }
 #endif
 
 #if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index a2cc94c25dcf..99202f5a613e 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -243,6 +243,7 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 
 	dwc->ep0state = EP0_SETUP_PHASE;
 	complete(&dwc->ep0_in_setup);
+	dwc3_gadget_check_ep_dequeue(dwc);
 	if (dwc->softconnect)
 		dwc3_ep0_out_start(dwc);
 }
@@ -925,6 +926,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
 	dwc->ep0state = EP0_SETUP_PHASE;
 	complete(&dwc->ep0_in_setup);
+	dwc3_gadget_check_ep_dequeue(dwc);
 	if (dwc->softconnect)
 		dwc3_ep0_out_start(dwc);
 }
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f6801199440c..0c89baedf220 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -654,7 +654,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
 	return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, &params);
 }
 
-static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+static int dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 		bool interrupt);
 
 /**
@@ -1081,6 +1081,31 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
 	return ret;
 }
 
+int dwc3_gadget_check_ep_dequeue(struct dwc3 *dwc)
+{
+	struct dwc3_ep *dep;
+	int ret = 0;
+	int i;
+
+	if (!dwc->ep_dequeue_pending)
+		return 0;
+
+	for (i = 0; i < dwc->num_eps; i++) {
+		dep = dwc->eps[i];
+		if (dep->flags & DWC3_EP_PENDING_DEQUEUE) {
+			ret = dwc3_stop_active_transfer(dep, false, true);
+			if (ret)
+				goto exit;
+
+			dep->flags &= ~DWC3_EP_PENDING_DEQUEUE;
+		}
+	}
+
+	dwc->ep_dequeue_pending = 0;
+exit:
+	return ret;
+}
+
 static int dwc3_gadget_ep_disable(struct usb_ep *ep)
 {
 	struct dwc3_ep			*dep;
@@ -2033,10 +2058,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 	list_for_each_entry(r, &dep->started_list, list) {
 		if (r == req) {
 			struct dwc3_request *t;
-
-			/* wait until it is processed */
-			dwc3_stop_active_transfer(dep, true, true);
-
 			/*
 			 * Remove any started request if the transfer is
 			 * cancelled.
@@ -2045,6 +2066,12 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 				dwc3_gadget_move_cancelled_request(r,
 						DWC3_REQUEST_STATUS_DEQUEUED);
 
+			ret = dwc3_stop_active_transfer(dep, false, true);
+			if (ret == -ETIMEDOUT) {
+				dep->flags |= DWC3_EP_PENDING_DEQUEUE;
+				dwc->ep_dequeue_pending = 1;
+			}
+
 			dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
 
 			goto out;
@@ -2319,6 +2346,7 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
 			continue;
 
 		dwc3_remove_requests(dwc, dep);
+		dep->flags &= ~DWC3_EP_PENDING_DEQUEUE;
 	}
 }
 
@@ -2715,6 +2743,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
 	dwc->ep0state = EP0_SETUP_PHASE;
 	dwc->link_state = DWC3_LINK_STATE_SS_DIS;
 	dwc->delayed_status = false;
+	dwc->ep_dequeue_pending = 0;
 	dwc3_ep0_out_start(dwc);
 
 	dwc3_gadget_enable_irq(dwc);
@@ -3433,6 +3462,7 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep,
 	if (dep->stream_capable)
 		dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
 
+	dep->flags &= ~DWC3_EP_PENDING_DEQUEUE;
 	dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
 	dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 	dwc3_gadget_ep_cleanup_cancelled_requests(dep);
@@ -3609,7 +3639,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)
 	}
 }
 
-static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+static int dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 	bool interrupt)
 {
 	struct dwc3_gadget_ep_cmd_params params;
@@ -3620,7 +3650,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 
 	if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
 	    (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
-		return;
+		return 0;
 
 	/*
 	 * NOTICE: We are violating what the Databook says about the
@@ -3671,6 +3701,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 				dwc3_ep0_out_start(dwc);
 				goto retry;
 			}
+		} else {
+			return ret;
 		}
 	}
 	dep->resource_index = 0;
@@ -3679,6 +3711,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 	else
 		dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+	return ret;
 }
 
 static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
