int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
                struct dwc3_gadget_ep_cmd_params *params)
 {
+       const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
        struct dwc3             *dwc = dep->dwc;
        u32                     timeout = 500;
        u32                     reg;
        dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
        dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
 
-       dwc3_writel(dep->regs, DWC3_DEPCMD, cmd | DWC3_DEPCMD_CMDACT);
+       /*
+        * Synopsys Databook 2.60a states in section 6.3.2.5.6 of that if we're
+        * not relying on XferNotReady, we can make use of a special "No
+        * Response Update Transfer" command where we should clear both CmdAct
+        * and CmdIOC bits.
+        *
+        * With this, we don't need to wait for command completion and can
+        * straight away issue further commands to the endpoint.
+        *
+        * NOTICE: We're making an assumption that control endpoints will never
+        * make use of Update Transfer command. This is a safe assumption
+        * because we can never have more than one request at a time with
+        * Control Endpoints. If anybody changes that assumption, this chunk
+        * needs to be updated accordingly.
+        */
+       if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_UPDATETRANSFER &&
+                       !usb_endpoint_xfer_isoc(desc))
+               cmd &= ~(DWC3_DEPCMD_CMDIOC | DWC3_DEPCMD_CMDACT);
+       else
+               cmd |= DWC3_DEPCMD_CMDACT;
+
+       dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
        do {
                reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
                if (!(reg & DWC3_DEPCMD_CMDACT)) {