]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/usb/gadget/s3c-hsotg.c
USB: s3c-hsotg: Ensure FIFOs are fully flushed after layout
[net-next-2.6.git] / 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);
 }
 
 /**