Commit a00ae34ac8bc8a5897d9b6b9b685c39b955b14b9

Authored by Ira Snyder
Committed by Dan Williams
1 parent dc8d409157

fsldma: make halt behave nicely on all supported controllers

The original dma_halt() function set the CA (channel abort) bit on both
the 83xx and 85xx controllers. This is incorrect on the 83xx, where this
bit means TEM (transfer error mask) instead. The 83xx doesn't support
channel abort, so we only do this operation on 85xx.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Showing 1 changed file with 16 additions and 3 deletions Side-by-side Diff

drivers/dma/fsldma.c
... ... @@ -221,13 +221,26 @@
221 221 u32 mode;
222 222 int i;
223 223  
  224 + /* read the mode register */
224 225 mode = DMA_IN(chan, &chan->regs->mr, 32);
225   - mode |= FSL_DMA_MR_CA;
226   - DMA_OUT(chan, &chan->regs->mr, mode, 32);
227 226  
228   - mode &= ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA);
  227 + /*
  228 + * The 85xx controller supports channel abort, which will stop
  229 + * the current transfer. On 83xx, this bit is the transfer error
  230 + * mask bit, which should not be changed.
  231 + */
  232 + if ((chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) {
  233 + mode |= FSL_DMA_MR_CA;
  234 + DMA_OUT(chan, &chan->regs->mr, mode, 32);
  235 +
  236 + mode &= ~FSL_DMA_MR_CA;
  237 + }
  238 +
  239 + /* stop the DMA controller */
  240 + mode &= ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN);
229 241 DMA_OUT(chan, &chan->regs->mr, mode, 32);
230 242  
  243 + /* wait for the DMA controller to become idle */
231 244 for (i = 0; i < 100; i++) {
232 245 if (dma_is_idle(chan))
233 246 return;