aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/fsldma.c
diff options
context:
space:
mode:
authorIra Snyder <iws@ovro.caltech.edu>2011-03-03 02:55:01 -0500
committerDan Williams <dan.j.williams@intel.com>2011-03-11 20:52:37 -0500
commita00ae34ac8bc8a5897d9b6b9b685c39b955b14b9 (patch)
tree72be720ffc981acbf15f6c8ef7381a5e38416e2e /drivers/dma/fsldma.c
parentdc8d4091575ba81e886ebcdfd1e559c981f82f86 (diff)
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>
Diffstat (limited to 'drivers/dma/fsldma.c')
-rw-r--r--drivers/dma/fsldma.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index d300de456c90..8670a5012122 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -221,13 +221,26 @@ static void dma_halt(struct fsldma_chan *chan)
221 u32 mode; 221 u32 mode;
222 int i; 222 int i;
223 223
224 /* read the mode register */
224 mode = DMA_IN(chan, &chan->regs->mr, 32); 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 DMA_OUT(chan, &chan->regs->mr, mode, 32); 241 DMA_OUT(chan, &chan->regs->mr, mode, 32);
230 242
243 /* wait for the DMA controller to become idle */
231 for (i = 0; i < 100; i++) { 244 for (i = 0; i < 100; i++) {
232 if (dma_is_idle(chan)) 245 if (dma_is_idle(chan))
233 return; 246 return;