summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorBen Dooks2010-05-25 06:36:52 +0200
committerGreg Kroah-Hartman2010-06-04 22:16:19 +0200
commit1703a6d3c38944731ba23594843a704d828266f3 (patch)
treeac9907c3100e98e1626e1d3b2675913c27b69c76 /drivers/usb
parentUSB: s3c-hsotg: SoftDisconnect minimum 3ms (diff)
downloadkernel-qcow2-linux-1703a6d3c38944731ba23594843a704d828266f3.tar.gz
kernel-qcow2-linux-1703a6d3c38944731ba23594843a704d828266f3.tar.xz
kernel-qcow2-linux-1703a6d3c38944731ba23594843a704d828266f3.zip
USB: s3c-hsotg: Ensure FIFOs are fully flushed after layout
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 31d19e1f261d..26193eceb323 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -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);
}
/**