aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/coh901318.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/coh901318.c')
-rw-r--r--drivers/dma/coh901318.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 64a937262a40..f1bf4f74ad8f 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -80,18 +80,16 @@ struct coh901318_chan {
80static void coh901318_list_print(struct coh901318_chan *cohc, 80static void coh901318_list_print(struct coh901318_chan *cohc,
81 struct coh901318_lli *lli) 81 struct coh901318_lli *lli)
82{ 82{
83 struct coh901318_lli *l; 83 struct coh901318_lli *l = lli;
84 dma_addr_t addr = virt_to_phys(lli);
85 int i = 0; 84 int i = 0;
86 85
87 while (addr) { 86 while (l) {
88 l = phys_to_virt(addr);
89 dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x" 87 dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x"
90 ", dst 0x%x, link 0x%x link_virt 0x%p\n", 88 ", dst 0x%x, link 0x%x virt_link_addr 0x%p\n",
91 i, l, l->control, l->src_addr, l->dst_addr, 89 i, l, l->control, l->src_addr, l->dst_addr,
92 l->link_addr, phys_to_virt(l->link_addr)); 90 l->link_addr, l->virt_link_addr);
93 i++; 91 i++;
94 addr = l->link_addr; 92 l = l->virt_link_addr;
95 } 93 }
96} 94}
97 95
@@ -125,7 +123,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
125 goto err_kmalloc; 123 goto err_kmalloc;
126 tmp = dev_buf; 124 tmp = dev_buf;
127 125
128 tmp += sprintf(tmp, "DMA -- enable dma channels\n"); 126 tmp += sprintf(tmp, "DMA -- enabled dma channels\n");
129 127
130 for (i = 0; i < debugfs_dma_base->platform->max_channels; i++) 128 for (i = 0; i < debugfs_dma_base->platform->max_channels; i++)
131 if (started_channels & (1 << i)) 129 if (started_channels & (1 << i))
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
592 return cohd_que; 590 return cohd_que;
593} 591}
594 592
593/*
594 * This tasklet is called from the interrupt handler to
595 * handle each descriptor (DMA job) that is sent to a channel.
596 */
595static void dma_tasklet(unsigned long data) 597static void dma_tasklet(unsigned long data)
596{ 598{
597 struct coh901318_chan *cohc = (struct coh901318_chan *) data; 599 struct coh901318_chan *cohc = (struct coh901318_chan *) data;
@@ -600,9 +602,13 @@ static void dma_tasklet(unsigned long data)
600 dma_async_tx_callback callback; 602 dma_async_tx_callback callback;
601 void *callback_param; 603 void *callback_param;
602 604
605 dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d"
606 " nbr_active_done %ld\n", __func__,
607 cohc->id, cohc->nbr_active_done);
608
603 spin_lock_irqsave(&cohc->lock, flags); 609 spin_lock_irqsave(&cohc->lock, flags);
604 610
605 /* get first active entry from list */ 611 /* get first active descriptor entry from list */
606 cohd_fin = coh901318_first_active_get(cohc); 612 cohd_fin = coh901318_first_active_get(cohc);
607 613
608 BUG_ON(cohd_fin->pending_irqs == 0); 614 BUG_ON(cohd_fin->pending_irqs == 0);
@@ -636,10 +642,19 @@ static void dma_tasklet(unsigned long data)
636 coh901318_desc_free(cohc, cohd_fin); 642 coh901318_desc_free(cohc, cohd_fin);
637 } 643 }
638 644
645 /*
646 * If another interrupt fired while the tasklet was scheduling,
647 * we don't get called twice, so we have this number of active
648 * counter that keep track of the number of IRQs expected to
649 * be handled for this channel. If there happen to be more than
650 * one IRQ to be ack:ed, we simply schedule this tasklet again.
651 */
639 if (cohc->nbr_active_done) 652 if (cohc->nbr_active_done)
640 cohc->nbr_active_done--; 653 cohc->nbr_active_done--;
641 654
642 if (cohc->nbr_active_done) { 655 if (cohc->nbr_active_done) {
656 dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs "
657 "came in while we were scheduling this tasklet\n");
643 if (cohc_chan_conf(cohc)->priority_high) 658 if (cohc_chan_conf(cohc)->priority_high)
644 tasklet_hi_schedule(&cohc->tasklet); 659 tasklet_hi_schedule(&cohc->tasklet);
645 else 660 else
@@ -994,6 +1009,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
994 len += factor; 1009 len += factor;
995 } 1010 }
996 1011
1012 pr_debug("Allocate %d lli:s for this transfer\n", len);
997 data = coh901318_lli_alloc(&cohc->base->pool, len); 1013 data = coh901318_lli_alloc(&cohc->base->pool, len);
998 1014
999 if (data == NULL) 1015 if (data == NULL)
@@ -1092,9 +1108,8 @@ coh901318_terminate_all(struct dma_chan *chan)
1092 /* release the lli allocation*/ 1108 /* release the lli allocation*/
1093 coh901318_lli_free(&cohc->base->pool, &cohd->data); 1109 coh901318_lli_free(&cohc->base->pool, &cohd->data);
1094 1110
1095 coh901318_desc_remove(cohd);
1096
1097 /* return desc to free-list */ 1111 /* return desc to free-list */
1112 coh901318_desc_remove(cohd);
1098 coh901318_desc_free(cohc, cohd); 1113 coh901318_desc_free(cohc, cohd);
1099 } 1114 }
1100 1115
@@ -1102,9 +1117,8 @@ coh901318_terminate_all(struct dma_chan *chan)
1102 /* release the lli allocation*/ 1117 /* release the lli allocation*/
1103 coh901318_lli_free(&cohc->base->pool, &cohd->data); 1118 coh901318_lli_free(&cohc->base->pool, &cohd->data);
1104 1119
1105 coh901318_desc_remove(cohd);
1106
1107 /* return desc to free-list */ 1120 /* return desc to free-list */
1121 coh901318_desc_remove(cohd);
1108 coh901318_desc_free(cohc, cohd); 1122 coh901318_desc_free(cohc, cohd);
1109 } 1123 }
1110 1124
@@ -1259,7 +1273,7 @@ static int __init coh901318_probe(struct platform_device *pdev)
1259 if (err) 1273 if (err)
1260 goto err_register_memcpy; 1274 goto err_register_memcpy;
1261 1275
1262 dev_dbg(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n", 1276 dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
1263 (u32) base->virtbase); 1277 (u32) base->virtbase);
1264 1278
1265 return err; 1279 return err;