aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/imx-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/imx-dma.c')
-rw-r--r--drivers/dma/imx-dma.c64
1 files changed, 18 insertions, 46 deletions
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 6e03f928ca81..629be353c63a 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -111,29 +111,6 @@ enum imxdma_prep_type {
111 IMXDMA_DESC_CYCLIC, 111 IMXDMA_DESC_CYCLIC,
112}; 112};
113 113
114/*
115 * struct imxdma_channel_internal - i.MX specific DMA extension
116 * @name: name specified by DMA client
117 * @irq_handler: client callback for end of transfer
118 * @err_handler: client callback for error condition
119 * @data: clients context data for callbacks
120 * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
121 * @sg: pointer to the actual read/written chunk for scatter-gather emulation
122 * @resbytes: total residual number of bytes to transfer
123 * (it can be lower or same as sum of SG mapped chunk sizes)
124 * @sgcount: number of chunks to be read/written
125 *
126 * Structure is used for IMX DMA processing. It would be probably good
127 * @struct dma_struct in the future for external interfacing and use
128 * @struct imxdma_channel_internal only as extension to it.
129 */
130
131struct imxdma_channel_internal {
132 struct timer_list watchdog;
133
134 int hw_chaining;
135};
136
137struct imxdma_desc { 114struct imxdma_desc {
138 struct list_head node; 115 struct list_head node;
139 struct dma_async_tx_descriptor desc; 116 struct dma_async_tx_descriptor desc;
@@ -156,7 +133,8 @@ struct imxdma_desc {
156}; 133};
157 134
158struct imxdma_channel { 135struct imxdma_channel {
159 struct imxdma_channel_internal internal; 136 int hw_chaining;
137 struct timer_list watchdog;
160 struct imxdma_engine *imxdma; 138 struct imxdma_engine *imxdma;
161 unsigned int channel; 139 unsigned int channel;
162 140
@@ -217,10 +195,10 @@ static unsigned imx_dmav1_readl(unsigned offset)
217 return __raw_readl(imx_dmav1_baseaddr + offset); 195 return __raw_readl(imx_dmav1_baseaddr + offset);
218} 196}
219 197
220static int imxdma_hw_chain(struct imxdma_channel_internal *imxdma) 198static int imxdma_hw_chain(struct imxdma_channel *imxdmac)
221{ 199{
222 if (cpu_is_mx27()) 200 if (cpu_is_mx27())
223 return imxdma->hw_chaining; 201 return imxdmac->hw_chaining;
224 else 202 else
225 return 0; 203 return 0;
226} 204}
@@ -269,7 +247,7 @@ static void imxdma_enable_hw(struct imxdma_desc *d)
269 CCR_ACRPT, DMA_CCR(channel)); 247 CCR_ACRPT, DMA_CCR(channel));
270 248
271 if ((cpu_is_mx21() || cpu_is_mx27()) && 249 if ((cpu_is_mx21() || cpu_is_mx27()) &&
272 d->sg && imxdma_hw_chain(&imxdmac->internal)) { 250 d->sg && imxdma_hw_chain(imxdmac)) {
273 d->sg = sg_next(d->sg); 251 d->sg = sg_next(d->sg);
274 if (d->sg) { 252 if (d->sg) {
275 u32 tmp; 253 u32 tmp;
@@ -290,8 +268,8 @@ static void imxdma_disable_hw(struct imxdma_channel *imxdmac)
290 268
291 pr_debug("imxdma%d: imx_dma_disable\n", channel); 269 pr_debug("imxdma%d: imx_dma_disable\n", channel);
292 270
293 if (imxdma_hw_chain(&imxdmac->internal)) 271 if (imxdma_hw_chain(imxdmac))
294 del_timer(&imxdmac->internal.watchdog); 272 del_timer(&imxdmac->watchdog);
295 273
296 local_irq_save(flags); 274 local_irq_save(flags);
297 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR); 275 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
@@ -316,7 +294,6 @@ static void imxdma_watchdog(unsigned long data)
316static irqreturn_t imxdma_err_handler(int irq, void *dev_id) 294static irqreturn_t imxdma_err_handler(int irq, void *dev_id)
317{ 295{
318 struct imxdma_engine *imxdma = dev_id; 296 struct imxdma_engine *imxdma = dev_id;
319 struct imxdma_channel_internal *internal;
320 unsigned int err_mask; 297 unsigned int err_mask;
321 int i, disr; 298 int i, disr;
322 int errcode; 299 int errcode;
@@ -336,7 +313,6 @@ static irqreturn_t imxdma_err_handler(int irq, void *dev_id)
336 for (i = 0; i < IMX_DMA_CHANNELS; i++) { 313 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
337 if (!(err_mask & (1 << i))) 314 if (!(err_mask & (1 << i)))
338 continue; 315 continue;
339 internal = &imxdma->channel[i].internal;
340 errcode = 0; 316 errcode = 0;
341 317
342 if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) { 318 if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
@@ -370,7 +346,6 @@ static irqreturn_t imxdma_err_handler(int irq, void *dev_id)
370 346
371static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) 347static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
372{ 348{
373 struct imxdma_channel_internal *imxdma = &imxdmac->internal;
374 int chno = imxdmac->channel; 349 int chno = imxdmac->channel;
375 struct imxdma_desc *desc; 350 struct imxdma_desc *desc;
376 351
@@ -394,11 +369,11 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
394 369
395 tmp = imx_dmav1_readl(DMA_CCR(chno)); 370 tmp = imx_dmav1_readl(DMA_CCR(chno));
396 371
397 if (imxdma_hw_chain(imxdma)) { 372 if (imxdma_hw_chain(imxdmac)) {
398 /* FIXME: The timeout should probably be 373 /* FIXME: The timeout should probably be
399 * configurable 374 * configurable
400 */ 375 */
401 mod_timer(&imxdma->watchdog, 376 mod_timer(&imxdmac->watchdog,
402 jiffies + msecs_to_jiffies(500)); 377 jiffies + msecs_to_jiffies(500));
403 378
404 tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT; 379 tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
@@ -417,8 +392,8 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
417 return; 392 return;
418 } 393 }
419 394
420 if (imxdma_hw_chain(imxdma)) { 395 if (imxdma_hw_chain(imxdmac)) {
421 del_timer(&imxdma->watchdog); 396 del_timer(&imxdmac->watchdog);
422 return; 397 return;
423 } 398 }
424 } 399 }
@@ -432,7 +407,6 @@ out:
432static irqreturn_t dma_irq_handler(int irq, void *dev_id) 407static irqreturn_t dma_irq_handler(int irq, void *dev_id)
433{ 408{
434 struct imxdma_engine *imxdma = dev_id; 409 struct imxdma_engine *imxdma = dev_id;
435 struct imxdma_channel_internal *internal;
436 int i, disr; 410 int i, disr;
437 411
438 if (cpu_is_mx21() || cpu_is_mx27()) 412 if (cpu_is_mx21() || cpu_is_mx27())
@@ -445,10 +419,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
445 419
446 imx_dmav1_writel(disr, DMA_DISR); 420 imx_dmav1_writel(disr, DMA_DISR);
447 for (i = 0; i < IMX_DMA_CHANNELS; i++) { 421 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
448 if (disr & (1 << i)) { 422 if (disr & (1 << i))
449 internal = &imxdma->channel[i].internal;
450 dma_irq_handle_channel(&imxdma->channel[i]); 423 dma_irq_handle_channel(&imxdma->channel[i]);
451 }
452 } 424 }
453 425
454 return IRQ_HANDLED; 426 return IRQ_HANDLED;
@@ -591,8 +563,8 @@ static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
591 break; 563 break;
592 } 564 }
593 565
594 imxdmac->internal.hw_chaining = 1; 566 imxdmac->hw_chaining = 1;
595 if (!imxdma_hw_chain(&imxdmac->internal)) 567 if (!imxdma_hw_chain(imxdmac))
596 return -EINVAL; 568 return -EINVAL;
597 imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) | 569 imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) |
598 ((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) | 570 ((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) |
@@ -917,7 +889,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
917 /* Initialize channel parameters */ 889 /* Initialize channel parameters */
918 for (i = 0; i < IMX_DMA_CHANNELS; i++) { 890 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
919 struct imxdma_channel *imxdmac = &imxdma->channel[i]; 891 struct imxdma_channel *imxdmac = &imxdma->channel[i];
920 memset(&imxdmac->internal, 0, sizeof(imxdmac->internal)); 892
921 if (cpu_is_mx21() || cpu_is_mx27()) { 893 if (cpu_is_mx21() || cpu_is_mx27()) {
922 ret = request_irq(MX2x_INT_DMACH0 + i, 894 ret = request_irq(MX2x_INT_DMACH0 + i,
923 dma_irq_handler, 0, "DMA", imxdma); 895 dma_irq_handler, 0, "DMA", imxdma);
@@ -926,9 +898,9 @@ static int __init imxdma_probe(struct platform_device *pdev)
926 MX2x_INT_DMACH0 + i, i); 898 MX2x_INT_DMACH0 + i, i);
927 goto err_init; 899 goto err_init;
928 } 900 }
929 init_timer(&imxdmac->internal.watchdog); 901 init_timer(&imxdmac->watchdog);
930 imxdmac->internal.watchdog.function = &imxdma_watchdog; 902 imxdmac->watchdog.function = &imxdma_watchdog;
931 imxdmac->internal.watchdog.data = (unsigned long)imxdmac; 903 imxdmac->watchdog.data = (unsigned long)imxdmac;
932 } 904 }
933 905
934 imxdmac->imxdma = imxdma; 906 imxdmac->imxdma = imxdma;