musb:gadget: use pio mode for zero byte transfer in gadget mode
authorRavi B <ravibabu@ti.com>
Wed, 12 Oct 2011 05:59:23 +0000 (11:29 +0530)
committerVaibhav Hiremath <hvaibhav@ti.com>
Mon, 23 Jan 2012 19:14:32 +0000 (00:44 +0530)
The cppi41 txdma is unable to transfer zero byte length, this
workaround uses pio mode to transfer zero byte length.

Signed-off-by: Ravi B <ravibabu@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
drivers/usb/musb/musb_gadget.c

index 4e5ddf4917212dfd0ef50e8cc68e1b1f4c3a4062..16154d7e39c126734fc9f87322eab3a6d7a8f9df 100644 (file)
@@ -406,8 +406,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
                } else if (is_cppi_enabled(musb) || is_cppi41_enabled(musb)) {
                        /* program endpoint CSR first, then setup DMA */
                        csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
-                       csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
-                              MUSB_TXCSR_MODE;
+
+                       if (request_size == 0)
+                               csr &= ~(MUSB_TXCSR_DMAENAB |
+                                       MUSB_TXCSR_DMAMODE);
+                       else
+                               csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
+                                      MUSB_TXCSR_MODE;
                        musb_writew(epio, MUSB_TXCSR,
                                (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
                                        | csr);
@@ -426,17 +431,22 @@ static void txstate(struct musb *musb, struct musb_request *req)
                         * unreliable except for the last-packet-is-already-
                         * short case.
                         */
-                       use_dma = use_dma && c->channel_program(
+                       /* for zero byte transfer use pio mode */
+                       if (request_size == 0)
+                               use_dma = 0;
+                       else {
+                               use_dma = use_dma && c->channel_program(
                                        musb_ep->dma, musb_ep->packet_sz,
                                        0,
                                        request->dma + request->actual,
                                        request_size);
-                       if (!use_dma) {
-                               c->channel_release(musb_ep->dma);
-                               musb_ep->dma = NULL;
-                               csr &= ~MUSB_TXCSR_DMAENAB;
-                               musb_writew(epio, MUSB_TXCSR, csr);
+                               if (!use_dma) {
+                                       c->channel_release(musb_ep->dma);
+                                       musb_ep->dma = NULL;
+                                       csr &= ~MUSB_TXCSR_DMAENAB;
+                                       musb_writew(epio, MUSB_TXCSR, csr);
                                /* invariant: prequest->buf is non-null */
+                               }
                        }
                } else if (tusb_dma_omap(musb)) {
                        use_dma = use_dma && c->channel_program(