USB: s3c-hsotg: Ensure FIFOs are fully flushed after layout
authorBen Dooks <ben-linux@fluff.org>
Tue, 25 May 2010 04:36:52 +0000 (05:36 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 4 Jun 2010 20:16:19 +0000 (13:16 -0700)
According to the design guide, if the FIFO layout is changed, then the
FIFOs must be flushed to ensure all FIFO pointers are correct.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/s3c-hsotg.c

index 31d19e1f261d3f9b25ab6f968842682b4cb174d0..26193eceb3231d48c06e98b29a09cf9849b319f5 100644 (file)
@@ -300,6 +300,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
        unsigned int ep;
        unsigned int addr;
        unsigned int size;
+       int timeout;
        u32 val;
 
        /* the ryu 2.6.24 release ahs
@@ -335,6 +336,31 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
 
                writel(val, hsotg->regs + S3C_DPTXFSIZn(ep));
        }
+
+       /* according to p428 of the design guide, we need to ensure that
+        * all fifos are flushed before continuing */
+
+       writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh |
+              S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL);
+
+       /* wait until the fifos are both flushed */
+       timeout = 100;
+       while (1) {
+               val = readl(hsotg->regs + S3C_GRSTCTL);
+
+               if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0)
+                       break;
+
+               if (--timeout == 0) {
+                       dev_err(hsotg->dev,
+                               "%s: timeout flushing fifos (GRSTCTL=%08x)\n",
+                               __func__, val);
+               }
+
+               udelay(1);
+       }
+
+       dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout);
 }
 
 /**