dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
 }
 
+static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg,
+                       u32 epctl_reg)
+{
+       u32 ctrl;
+
+       ctrl = dwc2_readl(hsotg->regs + epctl_reg);
+       if (ctrl & DXEPCTL_EOFRNUM)
+               ctrl |= DXEPCTL_SETEVENFR;
+       else
+               ctrl |= DXEPCTL_SETODDFR;
+       dwc2_writel(ctrl, hsotg->regs + epctl_reg);
+}
+
 /**
  * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
  * @hsotg: The device instance
                return;
        }
 
+       /*
+        * Slave mode OUT transfers do not go through XferComplete so
+        * adjust the ISOC parity here.
+        */
+       if (!using_dma(hsotg)) {
+               hs_ep->has_correct_parity = 1;
+               if (hs_ep->isochronous && hs_ep->interval == 1)
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum));
+       }
+
        dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
 }
 
                ints &= ~DXEPINT_XFERCOMPL;
 
        if (ints & DXEPINT_XFERCOMPL) {
-               if (hs_ep->isochronous && hs_ep->interval == 1) {
-                       if (ctrl & DXEPCTL_EOFRNUM)
-                               ctrl |= DXEPCTL_SETEVENFR;
-                       else
-                               ctrl |= DXEPCTL_SETODDFR;
-                       dwc2_writel(ctrl, hsotg->regs + epctl_reg);
-               }
+               hs_ep->has_correct_parity = 1;
+               if (hs_ep->isochronous && hs_ep->interval == 1)
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
 
                dev_dbg(hsotg->dev,
                        "%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n",
                GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF |
                GINTSTS_USBRST | GINTSTS_RESETDET |
                GINTSTS_ENUMDONE | GINTSTS_OTGINT |
-               GINTSTS_USBSUSP | GINTSTS_WKUPINT;
+               GINTSTS_USBSUSP | GINTSTS_WKUPINT |
+               GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT;
 
        if (hsotg->core_params->external_id_pin_ctl <= 0)
                intmsk |= GINTSTS_CONIDSTSCHNG;
                dwc2_hsotg_dump(hsotg);
        }
 
+       if (gintsts & GINTSTS_INCOMPL_SOIN) {
+               u32 idx, epctl_reg;
+               struct dwc2_hsotg_ep *hs_ep;
+
+               dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOIN\n", __func__);
+               for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+                       hs_ep = hsotg->eps_in[idx];
+
+                       if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+                               continue;
+
+                       epctl_reg = DIEPCTL(idx);
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+               }
+               dwc2_writel(GINTSTS_INCOMPL_SOIN, hsotg->regs + GINTSTS);
+       }
+
+       if (gintsts & GINTSTS_INCOMPL_SOOUT) {
+               u32 idx, epctl_reg;
+               struct dwc2_hsotg_ep *hs_ep;
+
+               dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOOUT\n", __func__);
+               for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+                       hs_ep = hsotg->eps_out[idx];
+
+                       if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+                               continue;
+
+                       epctl_reg = DOEPCTL(idx);
+                       dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+               }
+               dwc2_writel(GINTSTS_INCOMPL_SOOUT, hsotg->regs + GINTSTS);
+       }
+
        /*
         * if we've had fifo events, we should try and go around the
         * loop again to see if there's any point in returning yet.
        hs_ep->periodic = 0;
        hs_ep->halted = 0;
        hs_ep->interval = desc->bInterval;
+       hs_ep->has_correct_parity = 0;
 
        if (hs_ep->interval > 1 && hs_ep->mc > 1)
                dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");