#define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09
 #define DWC3_DGCMD_ALL_FIFO_FLUSH      0x0a
 #define DWC3_DGCMD_SET_ENDPOINT_NRDY   0x0c
+#define DWC3_DGCMD_SET_ENDPOINT_PRIME  0x0d
 #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK        0x10
 
 #define DWC3_DGCMD_STATUS(n)           (((n) >> 12) & 0x0F)
 #define DWC3_EP_PENDING_REQUEST        BIT(5)
 #define DWC3_EP_DELAY_START    BIT(6)
 #define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
+#define DWC3_EP_IGNORE_NEXT_NOSTREAM   BIT(8)
+#define DWC3_EP_FORCE_RESTART_STREAM   BIT(9)
+#define DWC3_EP_FIRST_STREAM_PRIMED    BIT(10)
 
        /* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN                BIT(31)
 #define DEPEVT_STREAMEVT_FOUND         1
 #define DEPEVT_STREAMEVT_NOTFOUND      2
 
+/* Stream event parameter */
+#define DEPEVT_STREAM_PRIME            0xfffe
+#define DEPEVT_STREAM_NOSTREAM         0x0
+
 /* Control-only Status */
 #define DEPEVT_STATUS_CONTROL_DATA     1
 #define DEPEVT_STATUS_CONTROL_STATUS   2
 
        return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms);
 }
 
+static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+               bool interrupt);
+
 /**
  * __dwc3_gadget_ep_enable - initializes a hw endpoint
  * @dep: endpoint to be initialized
         * Issue StartTransfer here with no-op TRB so we can always rely on No
         * Response Update Transfer command.
         */
-       if ((usb_endpoint_xfer_bulk(desc) && !dep->stream_capable) ||
+       if (usb_endpoint_xfer_bulk(desc) ||
                        usb_endpoint_xfer_int(desc)) {
                struct dwc3_gadget_ep_cmd_params params;
                struct dwc3_trb *trb;
                ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
                if (ret < 0)
                        return ret;
+
+               if (dep->stream_capable) {
+                       /*
+                        * For streams, at start, there maybe a race where the
+                        * host primes the endpoint before the function driver
+                        * queues a request to initiate a stream. In that case,
+                        * the controller will not see the prime to generate the
+                        * ERDY and start stream. To workaround this, issue a
+                        * no-op TRB as normal, but end it immediately. As a
+                        * result, when the function driver queues the request,
+                        * the next START_TRANSFER command will cause the
+                        * controller to generate an ERDY to initiate the
+                        * stream.
+                        */
+                       dwc3_stop_active_transfer(dep, true, true);
+
+                       /*
+                        * All stream eps will reinitiate stream on NoStream
+                        * rejection until we can determine that the host can
+                        * prime after the first transfer.
+                        */
+                       dep->flags |= DWC3_EP_FORCE_RESTART_STREAM;
+               }
        }
 
 out:
        return 0;
 }
 
-static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
-               bool interrupt);
 static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
        struct dwc3_request             *req;
        (void) __dwc3_gadget_start_isoc(dep);
 }
 
+static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep,
+               const struct dwc3_event_depevt *event)
+{
+       struct dwc3 *dwc = dep->dwc;
+
+       if (event->status == DEPEVT_STREAMEVT_FOUND) {
+               dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
+               goto out;
+       }
+
+       /* Note: NoStream rejection event param value is 0 and not 0xFFFF */
+       switch (event->parameters) {
+       case DEPEVT_STREAM_PRIME:
+               /*
+                * If the host can properly transition the endpoint state from
+                * idle to prime after a NoStream rejection, there's no need to
+                * force restarting the endpoint to reinitiate the stream. To
+                * simplify the check, assume the host follows the USB spec if
+                * it primed the endpoint more than once.
+                */
+               if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM) {
+                       if (dep->flags & DWC3_EP_FIRST_STREAM_PRIMED)
+                               dep->flags &= ~DWC3_EP_FORCE_RESTART_STREAM;
+                       else
+                               dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
+               }
+
+               break;
+       case DEPEVT_STREAM_NOSTREAM:
+               if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
+                   !(dep->flags & DWC3_EP_FORCE_RESTART_STREAM) ||
+                   !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE))
+                       break;
+
+               /*
+                * If the host rejects a stream due to no active stream, by the
+                * USB and xHCI spec, the endpoint will be put back to idle
+                * state. When the host is ready (buffer added/updated), it will
+                * prime the endpoint to inform the usb device controller. This
+                * triggers the device controller to issue ERDY to restart the
+                * stream. However, some hosts don't follow this and keep the
+                * endpoint in the idle state. No prime will come despite host
+                * streams are updated, and the device controller will not be
+                * triggered to generate ERDY to move the next stream data. To
+                * workaround this and maintain compatibility with various
+                * hosts, force to reinitate the stream until the host is ready
+                * instead of waiting for the host to prime the endpoint.
+                */
+               dep->flags |= DWC3_EP_DELAY_START;
+               dwc3_stop_active_transfer(dep, true, true);
+               return;
+       }
+
+out:
+       dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+}
+
 static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
                const struct dwc3_event_depevt *event)
 {
                dwc3_gadget_endpoint_transfer_complete(dep, event);
                break;
        case DWC3_DEPEVT_STREAMEVT:
+               dwc3_gadget_endpoint_stream_event(dep, event);
+               break;
        case DWC3_DEPEVT_RXTXFIFOEVT:
                break;
        }
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
+       /*
+        * The END_TRANSFER command will cause the controller to generate a
+        * NoStream Event, and it's not due to the host DP NoStream rejection.
+        * Ignore the next NoStream event.
+        */
+       if (dep->stream_capable)
+               dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
+
        if (!interrupt)
                dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
        else