}
+static int dwc_otg_wait_bit_set(volatile uint32_t *reg,
+ uint32_t bit, uint32_t timeout)
+{
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ if (DWC_READ_REG32(reg) & bit)
+ return 0;
+
+ dwc_udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void dwc_otg_pcd_ep_stop_transfer(dwc_otg_core_if_t
+ *core_if, dwc_ep_t *ep)
+{
+ depctl_data_t depctl = {.d32 = 0 };
+
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ depctl.d32 = DWC_READ_REG32(&core_if->dev_if->
+ in_ep_regs[ep->num]->
+ diepctl);
+ else
+ depctl.d32 = DWC_READ_REG32(&core_if->dev_if->
+ out_ep_regs[ep->num]->
+ doepctl);
+
+ if (ep->is_in == 1) {
+ diepint_data_t diepint = {.d32 = 0 };
+
+ depctl.b.snak = 1;
+ DWC_WRITE_REG32(&core_if->dev_if->
+ in_ep_regs[ep->num]->diepctl,
+ depctl.d32);
+
+ diepint.b.inepnakeff = 1;
+ /* Wait for Nak effect */
+ if (dwc_otg_wait_bit_set(&core_if->dev_if->
+ in_ep_regs[ep->num]
+ ->diepint,
+ diepint.d32,
+ 100)) {
+ DWC_WARN("%s: timeout diepctl.snak\n",
+ __func__);
+ } else {
+ DWC_WRITE_REG32(&core_if->dev_if->
+ in_ep_regs[ep->num]->
+ diepint, diepint.d32);
+ }
+
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ DWC_WRITE_REG32(&core_if->dev_if->
+ in_ep_regs[ep->num]->diepctl,
+ depctl.d32);
+
+ diepint.d32 = 0;
+ diepint.b.epdisabled = 1;
+ if (dwc_otg_wait_bit_set(&core_if->dev_if->
+ in_ep_regs[ep->num]
+ ->diepint,
+ diepint.d32,
+ 100)) {
+ DWC_WARN("%s: timeout diepctl.epdis\n",
+ __func__);
+ } else {
+ DWC_WRITE_REG32(&core_if->dev_if->
+ in_ep_regs[ep->num]->
+ diepint, diepint.d32);
+ }
+ } else {
+ dctl_data_t dctl = {.d32 = 0 };
+ gintmsk_data_t gintsts = {.d32 = 0 };
+ doepint_data_t doepint = {.d32 = 0 };
+
+ dctl.b.sgoutnak = 1;
+ DWC_MODIFY_REG32(&core_if->dev_if->
+ dev_global_regs->dctl, 0, dctl.d32);
+
+ /* Wait for global nak to take effect */
+ gintsts.d32 = 0;
+ gintsts.b.goutnakeff = 1;
+ if (dwc_otg_wait_bit_set(&core_if->core_global_regs->
+ gintsts, gintsts.d32,
+ 100)) {
+ DWC_WARN("%s: timeout dctl.sgoutnak\n",
+ __func__);
+ } else {
+ DWC_WRITE_REG32(&core_if->core_global_regs
+ ->gintsts, gintsts.d32);
+ }
+
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->
+ doepctl, depctl.d32);
+
+ doepint.b.epdisabled = 1;
+ if (dwc_otg_wait_bit_set(&core_if->dev_if
+ ->out_ep_regs[ep->num]
+ ->doepint, doepint.d32,
+ 100)) {
+ DWC_WARN("%s: timeout doepctl.epdis\n",
+ __func__);
+ } else {
+ DWC_WRITE_REG32(&core_if->dev_if->
+ out_ep_regs[ep->num]->
+ doepint, doepint.d32);
+ }
+
+ dctl.d32 = 0;
+ dctl.b.cgoutnak = 1;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
+ dctl, 0, dctl.d32);
+ }
+}
+
/******************************************************************************/
#ifdef DWC_UTE_PER_IO
}
if (!DWC_CIRCLEQ_EMPTY_ENTRY(req, queue_entry)) {
+ dwc_otg_pcd_ep_stop_transfer(GET_CORE_IF(pcd),
+ &ep->dwc_ep);
+ /* Flush the Tx FIFO */
+ if (ep->dwc_ep.is_in) {
+ dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd),
+ ep->dwc_ep.tx_fifo_num);
+ release_perio_tx_fifo(GET_CORE_IF(pcd),
+ ep->dwc_ep.tx_fifo_num);
+ release_tx_fifo(GET_CORE_IF(pcd),
+ ep->dwc_ep.tx_fifo_num);
+ }
+
dwc_otg_request_done(ep, req, -DWC_E_RESTART);
} else {
req = NULL;