if (is_dma_capable() && ep->dma) {
                struct dma_controller   *c = ep->musb->dma_controller;
                int value;
+
                if (ep->is_in) {
+                       /*
+                        * The programming guide says that we must not clear
+                        * the DMAMODE bit before DMAENAB, so we only
+                        * clear it in the second write...
+                        */
                        musb_writew(epio, MUSB_TXCSR,
-                                       0 | MUSB_TXCSR_FLUSHFIFO);
+                                   MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
                        musb_writew(epio, MUSB_TXCSR,
                                        0 | MUSB_TXCSR_FLUSHFIFO);
                } else {
                  |     IN token(s) are recd from Host.
                  |             -> DMA interrupt on completion
                  |                calls TxAvail.
-                 |                   -> stop DMA, ~DmaEenab,
+                 |                   -> stop DMA, ~DMAENAB,
                  |                   -> set TxPktRdy for last short pkt or zlp
                  |                   -> Complete Request
                  |                   -> Continue next request (call txstate)
                                        request->dma, request_size);
                        if (use_dma) {
                                if (musb_ep->dma->desired_mode == 0) {
-                                       /* ASSERT: DMAENAB is clear */
-                                       csr &= ~(MUSB_TXCSR_AUTOSET |
-                                                       MUSB_TXCSR_DMAMODE);
+                                       /*
+                                        * We must not clear the DMAMODE bit
+                                        * before the DMAENAB bit -- and the
+                                        * latter doesn't always get cleared
+                                        * before we get here...
+                                        */
+                                       csr &= ~(MUSB_TXCSR_AUTOSET
+                                               | MUSB_TXCSR_DMAENAB);
+                                       musb_writew(epio, MUSB_TXCSR, csr
+                                               | MUSB_TXCSR_P_WZC_BITS);
+                                       csr &= ~MUSB_TXCSR_DMAMODE;
                                        csr |= (MUSB_TXCSR_DMAENAB |
                                                        MUSB_TXCSR_MODE);
                                        /* against programming guide */
 
 #elif defined(CONFIG_USB_TI_CPPI_DMA)
                /* program endpoint CSR first, then setup DMA */
-               csr &= ~(MUSB_TXCSR_AUTOSET
-                               | MUSB_TXCSR_DMAMODE
-                               | MUSB_TXCSR_P_UNDERRUN
-                               | MUSB_TXCSR_TXPKTRDY);
+               csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
                csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
                musb_writew(epio, MUSB_TXCSR,
                        (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
                if (!use_dma) {
                        c->channel_release(musb_ep->dma);
                        musb_ep->dma = NULL;
-                       /* ASSERT: DMAENAB clear */
-                       csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
+                       csr &= ~MUSB_TXCSR_DMAENAB;
+                       musb_writew(epio, MUSB_TXCSR, csr);
                        /* invariant: prequest->buf is non-null */
                }
 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
 
                csr = musb_readw(ep->regs, MUSB_TXCSR);
                if (csr & MUSB_TXCSR_MODE) {
                        musb_h_tx_flush_fifo(ep);
+                       csr = musb_readw(ep->regs, MUSB_TXCSR);
                        musb_writew(ep->regs, MUSB_TXCSR,
-                                       MUSB_TXCSR_FRCDATATOG);
+                                   csr | MUSB_TXCSR_FRCDATATOG);
                }
-               /* clear mode (and everything else) to enable Rx */
+
+               /*
+                * Clear the MODE bit (and everything else) to enable Rx.
+                * NOTE: we mustn't clear the DMAMODE bit before DMAENAB.
+                */
+               if (csr & MUSB_TXCSR_DMAMODE)
+                       musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE);
                musb_writew(ep->regs, MUSB_TXCSR, 0);
 
        /* scrub all previous state, clearing toggle */
 
                /* general endpoint setup */
                if (epnum) {
-                       /* ASSERT:  TXCSR_DMAENAB was already cleared */
-
                        /* flush all old state, set default */
                        musb_h_tx_flush_fifo(hw_ep);
+
+                       /*
+                        * We must not clear the DMAMODE bit before or in
+                        * the same cycle with the DMAENAB bit, so we clear
+                        * the latter first...
+                        */
                        csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
-                                       | MUSB_TXCSR_DMAMODE
+                                       | MUSB_TXCSR_AUTOSET
+                                       | MUSB_TXCSR_DMAENAB
                                        | MUSB_TXCSR_FRCDATATOG
                                        | MUSB_TXCSR_H_RXSTALL
                                        | MUSB_TXCSR_H_ERROR
                                        );
                        csr |= MUSB_TXCSR_MODE;
 
-                       if (usb_gettoggle(urb->dev,
-                                       qh->epnum, 1))
+                       if (usb_gettoggle(urb->dev, qh->epnum, 1))
                                csr |= MUSB_TXCSR_H_WR_DATATOGGLE
                                        | MUSB_TXCSR_H_DATATOGGLE;
                        else
                                csr |= MUSB_TXCSR_CLRDATATOG;
 
-                       /* twice in case of double packet buffering */
                        musb_writew(epio, MUSB_TXCSR, csr);
                        /* REVISIT may need to clear FLUSHFIFO ... */
+                       csr &= ~MUSB_TXCSR_DMAMODE;
                        musb_writew(epio, MUSB_TXCSR, csr);
                        csr = musb_readw(epio, MUSB_TXCSR);
                } else {
 
 #ifdef CONFIG_USB_INVENTRA_DMA
                if (dma_channel) {
-
-                       /* clear previous state */
-                       csr = musb_readw(epio, MUSB_TXCSR);
-                       csr &= ~(MUSB_TXCSR_AUTOSET
-                               | MUSB_TXCSR_DMAMODE
-                               | MUSB_TXCSR_DMAENAB);
-                       csr |= MUSB_TXCSR_MODE;
-                       musb_writew(epio, MUSB_TXCSR,
-                               csr | MUSB_TXCSR_MODE);
-
                        qh->segsize = min(len, dma_channel->max_len);
-
                        if (qh->segsize <= packet_sz)
                                dma_channel->desired_mode = 0;
                        else
                                dma_channel->desired_mode = 1;
 
-
                        if (dma_channel->desired_mode == 0) {
-                               csr &= ~(MUSB_TXCSR_AUTOSET
-                                       | MUSB_TXCSR_DMAMODE);
+                               /* Against the programming guide */
                                csr |= (MUSB_TXCSR_DMAENAB);
-                                       /* against programming guide */
                        } else
                                csr |= (MUSB_TXCSR_AUTOSET
                                        | MUSB_TXCSR_DMAENAB
                                        | MUSB_TXCSR_DMAMODE);
-
                        musb_writew(epio, MUSB_TXCSR, csr);
 
                        dma_ok = dma_controller->channel_program(
                                else
                                        hw_ep->rx_channel = NULL;
                                dma_channel = NULL;
+
+                               /*
+                                * The programming guide says that we must
+                                * clear the DMAENAB bit before DMAMODE...
+                                */
+                               csr = musb_readw(epio, MUSB_TXCSR);
+                               csr &= ~(MUSB_TXCSR_DMAENAB
+                                               | MUSB_TXCSR_AUTOSET);
+                               musb_writew(epio, MUSB_TXCSR, csr);
+                               csr &= ~MUSB_TXCSR_DMAMODE;
+                               musb_writew(epio, MUSB_TXCSR, csr);
                        }
                }
 #endif
                /* candidate for DMA */
                if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
 
-                       /* program endpoint CSRs first, then setup DMA.
-                        * assume CPPI setup succeeds.
-                        * defer enabling dma.
-                        */
-                       csr = musb_readw(epio, MUSB_TXCSR);
-                       csr &= ~(MUSB_TXCSR_AUTOSET
-                                       | MUSB_TXCSR_DMAMODE
-                                       | MUSB_TXCSR_DMAENAB);
-                       csr |= MUSB_TXCSR_MODE;
-                       musb_writew(epio, MUSB_TXCSR,
-                               csr | MUSB_TXCSR_MODE);
-
+                       /* Defer enabling DMA */
                        dma_channel->actual_len = 0L;
                        qh->segsize = len;
 
                }
 
                if (load_count) {
-                       /* ASSERT:  TXCSR_DMAENAB was already cleared */
-
                        /* PIO to load FIFO */
                        qh->segsize = load_count;
                        musb_write_fifo(hw_ep, load_count, buf);
-                       csr = musb_readw(epio, MUSB_TXCSR);
-                       csr &= ~(MUSB_TXCSR_DMAENAB
-                               | MUSB_TXCSR_DMAMODE
-                               | MUSB_TXCSR_AUTOSET);
-                       /* write CSR */
-                       csr |= MUSB_TXCSR_MODE;
-
-                       if (epnum)
-                               musb_writew(epio, MUSB_TXCSR, csr);
                }
 
                /* re-enable interrupt */
 
        void __iomem *mbase = musb_channel->controller->base;
 
        u8 bchannel = musb_channel->idx;
+       int offset;
        u16 csr;
 
        if (channel->status == MUSB_DMA_STATUS_BUSY) {
                if (musb_channel->transmit) {
-
-                       csr = musb_readw(mbase,
-                               MUSB_EP_OFFSET(musb_channel->epnum,
-                                               MUSB_TXCSR));
-                       csr &= ~(MUSB_TXCSR_AUTOSET |
-                                MUSB_TXCSR_DMAENAB |
-                                MUSB_TXCSR_DMAMODE);
-                       musb_writew(mbase,
-                               MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
-                               csr);
+                       offset = MUSB_EP_OFFSET(musb_channel->epnum,
+                                               MUSB_TXCSR);
+
+                       /*
+                        * The programming guide says that we must clear
+                        * the DMAENAB bit before the DMAMODE bit...
+                        */
+                       csr = musb_readw(mbase, offset);
+                       csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
+                       musb_writew(mbase, offset, csr);
+                       csr &= ~MUSB_TXCSR_DMAMODE;
+                       musb_writew(mbase, offset, csr);
                } else {
-                       csr = musb_readw(mbase,
-                               MUSB_EP_OFFSET(musb_channel->epnum,
-                                               MUSB_RXCSR));
+                       offset = MUSB_EP_OFFSET(musb_channel->epnum,
+                                               MUSB_RXCSR);
+
+                       csr = musb_readw(mbase, offset);
                        csr &= ~(MUSB_RXCSR_AUTOCLEAR |
                                 MUSB_RXCSR_DMAENAB |
                                 MUSB_RXCSR_DMAMODE);
-                       musb_writew(mbase,
-                               MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
-                               csr);
+                       musb_writew(mbase, offset, csr);
                }
 
                musb_writew(mbase,
                                        && ((channel->desired_mode == 0)
                                            || (channel->actual_len &
                                            (musb_channel->max_packet_sz - 1)))
-                                        ) {
+                                   ) {
+                                       u8  epnum  = musb_channel->epnum;
+                                       int offset = MUSB_EP_OFFSET(epnum,
+                                                                   MUSB_TXCSR);
+                                       u16 txcsr;
+
+                                       /*
+                                        * The programming guide says that we
+                                        * must clear DMAENAB before DMAMODE.
+                                        */
+                                       musb_ep_select(mbase, epnum);
+                                       txcsr = musb_readw(mbase, offset);
+                                       txcsr &= ~(MUSB_TXCSR_DMAENAB
+                                                       | MUSB_TXCSR_AUTOSET);
+                                       musb_writew(mbase, offset, txcsr);
                                        /* Send out the packet */
-                                       musb_ep_select(mbase,
-                                               musb_channel->epnum);
-                                       musb_writew(mbase, MUSB_EP_OFFSET(
-                                                       musb_channel->epnum,
-                                                       MUSB_TXCSR),
-                                               MUSB_TXCSR_TXPKTRDY);
+                                       txcsr &= ~MUSB_TXCSR_DMAMODE;
+                                       txcsr |=  MUSB_TXCSR_TXPKTRDY;
+                                       musb_writew(mbase, offset, txcsr);
                                }
                                musb_dma_completion(musb, musb_channel->epnum,
                                                    musb_channel->transmit);