usb: musb: gadget: clear TXPKTRDY flag when set FLUSHFIFO
authorYauheni Kaliuta <yauheni.kaliuta@nokia.com>
Wed, 8 Jun 2011 14:12:02 +0000 (17:12 +0300)
committerFelipe Balbi <balbi@ti.com>
Thu, 9 Jun 2011 09:01:03 +0000 (12:01 +0300)
Fixes mis-use of MUSB's hardware feature where it won't
flush FIFOs when TXPKTRDY flag was set before and we are
flushing setting both FLUSHFIFO and TXPKTRDY.

In other words, we need to ensure that when we try to
flush FIFOs, we don't accidentaly set TXPKTRDY bit too
due to a read-back of the register.

The MUSB Programming Guide says "May be set simultaneously
with TxPktRdy to abort the packet that is currently being
loaded into the FIFO". This is a situation where TXPKTRDY
hasn't been set yet, but some data already loaded into the
fifo. It looks, that if TXPKTRDY has been set before, and
there is no loading in progress, but we set FLUSHFIFO with
the TXPKTRDY, controller tries to use the same logic to
abort loading and as the result just does nothing (because
there is no packet been loaded currently)

Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
[ balbi@ti.com : fixed one whitespace git complained about
 improved the commit log slightly ]

Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/musb/musb_gadget.c

index 0a50a35e185351f0732602c7d5b04e4f4173d3d3..6aeb363e63e7c143fdfb35ae52f167fe8f37cf3a 100644 (file)
@@ -1524,6 +1524,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
                csr = musb_readw(epio, MUSB_TXCSR);
                if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
                        csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
+                       /*
+                        * Setting both TXPKTRDY and FLUSHFIFO makes controller
+                        * to interrupt current FIFO loading, but not flushing
+                        * the already loaded ones.
+                        */
+                       csr &= ~MUSB_TXCSR_TXPKTRDY;
                        musb_writew(epio, MUSB_TXCSR, csr);
                        /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
                        musb_writew(epio, MUSB_TXCSR, csr);