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 <[email protected]>
---
 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to