aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch
new file mode 100644
index 0000000000..09fc0a17d0
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0009-usb-musb_host-fix-ep0-fifo-flushing.patch
@@ -0,0 +1,93 @@
+From 48ce47b15bfd420982ee275c595a9139eb6fabf7 Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+Date: Thu, 26 Mar 2009 17:38:30 -0700
+Subject: [PATCH] usb: musb_host, fix ep0 fifo flushing
+
+The MUSB host side can't share generic TX FIFO flush logic
+with EP0; the EP0 TX status register bits are different
+from those for other entpoints.
+
+Resolve this issue by providing a new EP0-specific routine
+to flush and reset the FIFO, which pays careful attention to
+restrictions listed in the latest programmer's guide. This
+gets rid of an open issue whereby the usbtest control write
+test (#14) failed.
+
+Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+---
+ drivers/usb/musb/musb_host.c | 38 +++++++++++++++++++++++++-------------
+ 1 files changed, 25 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index ff09595..a5d75aa 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -125,6 +125,29 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
+ }
+ }
+
++static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep)
++{
++ void __iomem *epio = ep->regs;
++ u16 csr;
++ int retries = 5;
++
++ /* scrub any data left in the fifo */
++ do {
++ csr = musb_readw(epio, MUSB_TXCSR);
++ if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY)))
++ break;
++ musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO);
++ csr = musb_readw(epio, MUSB_TXCSR);
++ udelay(10);
++ } while (--retries);
++
++ WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n",
++ ep->epnum, csr);
++
++ /* and reset for the next transfer */
++ musb_writew(epio, MUSB_TXCSR, 0);
++}
++
+ /*
+ * Start transmit. Caller is responsible for locking shared resources.
+ * musb must be locked.
+@@ -693,11 +716,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
+ musb_writew(epio, MUSB_TXCSR, csr);
+ csr = musb_readw(epio, MUSB_TXCSR);
+ } else {
+- /* endpoint 0: just flush */
+- musb_writew(epio, MUSB_CSR0,
+- csr | MUSB_CSR0_FLUSHFIFO);
+- musb_writew(epio, MUSB_CSR0,
+- csr | MUSB_CSR0_FLUSHFIFO);
++ musb_h_ep0_flush_fifo(hw_ep);
+ }
+
+ /* target addr and (for multipoint) hub addr/port */
+@@ -1063,11 +1082,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
+ csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
+ musb_writew(epio, MUSB_CSR0, csr);
+ } else {
+- csr |= MUSB_CSR0_FLUSHFIFO;
+- musb_writew(epio, MUSB_CSR0, csr);
+- musb_writew(epio, MUSB_CSR0, csr);
+- csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
+- musb_writew(epio, MUSB_CSR0, csr);
++ musb_h_ep0_flush_fifo(hw_ep);
+ }
+
+ musb_writeb(epio, MUSB_NAKLIMIT0, 0);
+@@ -1081,9 +1096,6 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
+ * SHOULD NEVER HAPPEN! */
+ ERR("no URB for end 0\n");
+
+- musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
+- musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
+- musb_writew(epio, MUSB_CSR0, 0);
+
+ goto done;
+ }
+--
+1.6.0.4
+