DOEPINTn.SetUp also indicates an OUT token for the data stage, so instead use DOEPINTn.StupPktRcvd. Moreover, check DOEPINTn.StupPktRcvd on DOEPINTn.XferComp as described in programming guide. Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@xxxxxxxxx> --- drivers/usb/dwc2/gadget.c | 83 ++++++++++++++++++++++++----------------------- drivers/usb/dwc2/hw.h | 1 + 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5d3af1d..d89c341 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1811,35 +1811,54 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, __func__, idx, dir_in ? "in" : "out", ints); if (ints & DXEPINT_XFERCOMPL) { - if (hs_ep->isochronous && hs_ep->interval == 1) { - if (ctrl & DXEPCTL_EOFRNUM) - ctrl |= DXEPCTL_SETEVENFR; - else - ctrl |= DXEPCTL_SETODDFR; - writel(ctrl, hsotg->regs + epctl_reg); - } + if (ints & DXEPINT_SETUP_RCVD) { /* Setup or Timeout */ + dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); - dev_dbg(hsotg->dev, - "%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n", - __func__, readl(hsotg->regs + epctl_reg), - readl(hsotg->regs + epsiz_reg)); + if (using_dma(hsotg) && idx == 0) { + /* + * this is the notification we've received a + * setup packet. In non-DMA mode we'd get this + * from the RXFIFO, instead we need to process + * the setup here. + */ - /* - * we get OutDone from the FIFO, so we only need to look - * at completing IN requests here - */ - if (dir_in) { - s3c_hsotg_complete_in(hsotg, hs_ep); + if (dir_in) + WARN_ON_ONCE(1); + else + s3c_hsotg_handle_outdone(hsotg, + 0, true); + } + } else { + if (hs_ep->isochronous && hs_ep->interval == 1) { + if (ctrl & DXEPCTL_EOFRNUM) + ctrl |= DXEPCTL_SETEVENFR; + else + ctrl |= DXEPCTL_SETODDFR; + writel(ctrl, hsotg->regs + epctl_reg); + } + + dev_dbg(hsotg->dev, + "%s: XferCompl:DxEPCTL=0x%08x,DXEPTSIZ=%08x\n", + __func__, readl(hsotg->regs + epctl_reg), + readl(hsotg->regs + epsiz_reg)); - if (idx == 0 && !hs_ep->req) - s3c_hsotg_enqueue_setup(hsotg); - } else if (using_dma(hsotg)) { /* - * We're using DMA, we need to fire an OutDone here - * as we ignore the RXFIFO. + * we get OutDone from the FIFO, so we only need to look + * at completing IN requests here */ + if (dir_in) { + s3c_hsotg_complete_in(hsotg, hs_ep); - s3c_hsotg_handle_outdone(hsotg, idx, false); + if (idx == 0 && !hs_ep->req) + s3c_hsotg_enqueue_setup(hsotg); + } else if (using_dma(hsotg)) { + /* + * We're using DMA, we need to fire an OutDone + * here as we ignore the RXFIFO. + */ + + s3c_hsotg_handle_outdone(hsotg, idx, false); + } } } @@ -1864,24 +1883,6 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, if (ints & DXEPINT_AHBERR) dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); - if (ints & DXEPINT_SETUP) { /* Setup or Timeout */ - dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); - - if (using_dma(hsotg) && idx == 0) { - /* - * this is the notification we've received a - * setup packet. In non-DMA mode we'd get this - * from the RXFIFO, instead we need to process - * the setup here. - */ - - if (dir_in) - WARN_ON_ONCE(1); - else - s3c_hsotg_handle_outdone(hsotg, 0, true); - } - } - if (ints & DXEPINT_BACK2BACKSETUP) dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index 51248b9..d018ebe 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h @@ -541,6 +541,7 @@ #define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) #define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) +#define DXEPINT_SETUP_RCVD (1 << 15) #define DXEPINT_INEPNAKEFF (1 << 6) #define DXEPINT_BACK2BACKSETUP (1 << 6) #define DXEPINT_INTKNEPMIS (1 << 5) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html