summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/cppi_dma.c
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-03-27 04:26:40 +0300
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-17 21:50:25 +0400
commitc7bbc056a92476b3b3d70a8df7cc746ac5d56de7 (patch)
tree2d7254ae97e2af4068a5b2a81118d3b72c1550c8 /drivers/usb/musb/cppi_dma.c
parent78322c1a64387673f46afb8b5e31edec94e9603d (diff)
downloadlinux-c7bbc056a92476b3b3d70a8df7cc746ac5d56de7.tar.xz
USB: musb: bugfixes for multi-packet TXDMA support
We really want to use DMA mode 1 for all multi-packet transfers; that's one IRQ on DMA completion, instead of one per packet. There is an important issue with such transfers, especially on the host side: when such transfers end with a full-size packet, we must defer musb_dma_completion() calls until the FIFO empties. Else we report URB completions too soon, and may clobber data in the FIFO fifo when writing the next packet (losing data). The Inventra DMA support uses DMA mode 1, but it ignores that issue. The CPPI DMA support uses mode 0, but doesn't handle its TXPKTRDY interrupts quite right either; it can get stale "packet ready" interrupts, and report transfer completion too early using slightly different code paths, also losing data. So I'm solving it in a generic way -- by adding a sort of the "interrupt filter" into musb_host_tx(), catching these cases where a DMA completion IRQ doesn't suffice and removing some needlessly controller-specific logic. When a TXDMA interrupt happens and DMA request mode 1 is active, that filter resets to mode 0 and defers URB completion processing until TXPKTRDY, unless the FIFO is already empty. Related filtering logic in Inventra and CPPI code gets removed. Since it should be competely safe now to use the DMA request mode 1 for host side transfers with the CPPI DMA controller, set it in musb_h_tx_dma_start() ... now renamed (and shared). [ dbrownell@users.sourceforge.net: don't introduce more CamElCase; use more concise explanations ] Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb/cppi_dma.c')
-rw-r--r--drivers/usb/musb/cppi_dma.c22
1 files changed, 1 insertions, 21 deletions
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 569ef0fed0f6..30e24891ed62 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -1228,27 +1228,7 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx)
hw_ep = tx_ch->hw_ep;
- /* Peripheral role never repurposes the
- * endpoint, so immediate completion is
- * safe. Host role waits for the fifo
- * to empty (TXPKTRDY irq) before going
- * to the next queued bulk transfer.
- */
- if (is_host_active(cppi->musb)) {
-#if 0
- /* WORKAROUND because we may
- * not always get TXKPTRDY ...
- */
- int csr;
-
- csr = musb_readw(hw_ep->regs,
- MUSB_TXCSR);
- if (csr & MUSB_TXCSR_TXPKTRDY)
-#endif
- completed = false;
- }
- if (completed)
- musb_dma_completion(musb, index + 1, 1);
+ musb_dma_completion(musb, index + 1, 1);
} else {
/* Bigger transfer than we could fit in