aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/omap-dma.c78
1 files changed, 14 insertions, 64 deletions
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 48f77c289cd3..9794b073d7d7 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -28,8 +28,6 @@
28struct omap_dmadev { 28struct omap_dmadev {
29 struct dma_device ddev; 29 struct dma_device ddev;
30 spinlock_t lock; 30 spinlock_t lock;
31 struct tasklet_struct task;
32 struct list_head pending;
33 void __iomem *base; 31 void __iomem *base;
34 const struct omap_dma_reg *reg_map; 32 const struct omap_dma_reg *reg_map;
35 struct omap_system_dma_plat_info *plat; 33 struct omap_system_dma_plat_info *plat;
@@ -42,7 +40,6 @@ struct omap_dmadev {
42 40
43struct omap_chan { 41struct omap_chan {
44 struct virt_dma_chan vc; 42 struct virt_dma_chan vc;
45 struct list_head node;
46 void __iomem *channel_base; 43 void __iomem *channel_base;
47 const struct omap_dma_reg *reg_map; 44 const struct omap_dma_reg *reg_map;
48 uint32_t ccr; 45 uint32_t ccr;
@@ -454,33 +451,6 @@ static void omap_dma_callback(int ch, u16 status, void *data)
454 spin_unlock_irqrestore(&c->vc.lock, flags); 451 spin_unlock_irqrestore(&c->vc.lock, flags);
455} 452}
456 453
457/*
458 * This callback schedules all pending channels. We could be more
459 * clever here by postponing allocation of the real DMA channels to
460 * this point, and freeing them when our virtual channel becomes idle.
461 *
462 * We would then need to deal with 'all channels in-use'
463 */
464static void omap_dma_sched(unsigned long data)
465{
466 struct omap_dmadev *d = (struct omap_dmadev *)data;
467 LIST_HEAD(head);
468
469 spin_lock_irq(&d->lock);
470 list_splice_tail_init(&d->pending, &head);
471 spin_unlock_irq(&d->lock);
472
473 while (!list_empty(&head)) {
474 struct omap_chan *c = list_first_entry(&head,
475 struct omap_chan, node);
476
477 spin_lock_irq(&c->vc.lock);
478 list_del_init(&c->node);
479 omap_dma_start_desc(c);
480 spin_unlock_irq(&c->vc.lock);
481 }
482}
483
484static irqreturn_t omap_dma_irq(int irq, void *devid) 454static irqreturn_t omap_dma_irq(int irq, void *devid)
485{ 455{
486 struct omap_dmadev *od = devid; 456 struct omap_dmadev *od = devid;
@@ -703,8 +673,14 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
703 struct omap_chan *c = to_omap_dma_chan(chan); 673 struct omap_chan *c = to_omap_dma_chan(chan);
704 struct virt_dma_desc *vd; 674 struct virt_dma_desc *vd;
705 enum dma_status ret; 675 enum dma_status ret;
676 uint32_t ccr;
706 unsigned long flags; 677 unsigned long flags;
707 678
679 ccr = omap_dma_chan_read(c, CCR);
680 /* The channel is no longer active, handle the completion right away */
681 if (!(ccr & CCR_ENABLE))
682 omap_dma_callback(c->dma_ch, 0, c);
683
708 ret = dma_cookie_status(chan, cookie, txstate); 684 ret = dma_cookie_status(chan, cookie, txstate);
709 if (ret == DMA_COMPLETE || !txstate) 685 if (ret == DMA_COMPLETE || !txstate)
710 return ret; 686 return ret;
@@ -719,7 +695,7 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
719 695
720 if (d->dir == DMA_MEM_TO_DEV) 696 if (d->dir == DMA_MEM_TO_DEV)
721 pos = omap_dma_get_src_pos(c); 697 pos = omap_dma_get_src_pos(c);
722 else if (d->dir == DMA_DEV_TO_MEM) 698 else if (d->dir == DMA_DEV_TO_MEM || d->dir == DMA_MEM_TO_MEM)
723 pos = omap_dma_get_dst_pos(c); 699 pos = omap_dma_get_dst_pos(c);
724 else 700 else
725 pos = 0; 701 pos = 0;
@@ -739,22 +715,8 @@ static void omap_dma_issue_pending(struct dma_chan *chan)
739 unsigned long flags; 715 unsigned long flags;
740 716
741 spin_lock_irqsave(&c->vc.lock, flags); 717 spin_lock_irqsave(&c->vc.lock, flags);
742 if (vchan_issue_pending(&c->vc) && !c->desc) { 718 if (vchan_issue_pending(&c->vc) && !c->desc)
743 /* 719 omap_dma_start_desc(c);
744 * c->cyclic is used only by audio and in this case the DMA need
745 * to be started without delay.
746 */
747 if (!c->cyclic) {
748 struct omap_dmadev *d = to_omap_dma_dev(chan->device);
749 spin_lock(&d->lock);
750 if (list_empty(&c->node))
751 list_add_tail(&c->node, &d->pending);
752 spin_unlock(&d->lock);
753 tasklet_schedule(&d->task);
754 } else {
755 omap_dma_start_desc(c);
756 }
757 }
758 spin_unlock_irqrestore(&c->vc.lock, flags); 720 spin_unlock_irqrestore(&c->vc.lock, flags);
759} 721}
760 722
@@ -768,7 +730,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
768 struct scatterlist *sgent; 730 struct scatterlist *sgent;
769 struct omap_desc *d; 731 struct omap_desc *d;
770 dma_addr_t dev_addr; 732 dma_addr_t dev_addr;
771 unsigned i, j = 0, es, en, frame_bytes; 733 unsigned i, es, en, frame_bytes;
772 u32 burst; 734 u32 burst;
773 735
774 if (dir == DMA_DEV_TO_MEM) { 736 if (dir == DMA_DEV_TO_MEM) {
@@ -845,13 +807,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
845 en = burst; 807 en = burst;
846 frame_bytes = es_bytes[es] * en; 808 frame_bytes = es_bytes[es] * en;
847 for_each_sg(sgl, sgent, sglen, i) { 809 for_each_sg(sgl, sgent, sglen, i) {
848 d->sg[j].addr = sg_dma_address(sgent); 810 d->sg[i].addr = sg_dma_address(sgent);
849 d->sg[j].en = en; 811 d->sg[i].en = en;
850 d->sg[j].fn = sg_dma_len(sgent) / frame_bytes; 812 d->sg[i].fn = sg_dma_len(sgent) / frame_bytes;
851 j++;
852 } 813 }
853 814
854 d->sglen = j; 815 d->sglen = sglen;
855 816
856 return vchan_tx_prep(&c->vc, &d->vd, tx_flags); 817 return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
857} 818}
@@ -1018,17 +979,11 @@ static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config
1018static int omap_dma_terminate_all(struct dma_chan *chan) 979static int omap_dma_terminate_all(struct dma_chan *chan)
1019{ 980{
1020 struct omap_chan *c = to_omap_dma_chan(chan); 981 struct omap_chan *c = to_omap_dma_chan(chan);
1021 struct omap_dmadev *d = to_omap_dma_dev(c->vc.chan.device);
1022 unsigned long flags; 982 unsigned long flags;
1023 LIST_HEAD(head); 983 LIST_HEAD(head);
1024 984
1025 spin_lock_irqsave(&c->vc.lock, flags); 985 spin_lock_irqsave(&c->vc.lock, flags);
1026 986
1027 /* Prevent this channel being scheduled */
1028 spin_lock(&d->lock);
1029 list_del_init(&c->node);
1030 spin_unlock(&d->lock);
1031
1032 /* 987 /*
1033 * Stop DMA activity: we assume the callback will not be called 988 * Stop DMA activity: we assume the callback will not be called
1034 * after omap_dma_stop() returns (even if it does, it will see 989 * after omap_dma_stop() returns (even if it does, it will see
@@ -1102,14 +1057,12 @@ static int omap_dma_chan_init(struct omap_dmadev *od)
1102 c->reg_map = od->reg_map; 1057 c->reg_map = od->reg_map;
1103 c->vc.desc_free = omap_dma_desc_free; 1058 c->vc.desc_free = omap_dma_desc_free;
1104 vchan_init(&c->vc, &od->ddev); 1059 vchan_init(&c->vc, &od->ddev);
1105 INIT_LIST_HEAD(&c->node);
1106 1060
1107 return 0; 1061 return 0;
1108} 1062}
1109 1063
1110static void omap_dma_free(struct omap_dmadev *od) 1064static void omap_dma_free(struct omap_dmadev *od)
1111{ 1065{
1112 tasklet_kill(&od->task);
1113 while (!list_empty(&od->ddev.channels)) { 1066 while (!list_empty(&od->ddev.channels)) {
1114 struct omap_chan *c = list_first_entry(&od->ddev.channels, 1067 struct omap_chan *c = list_first_entry(&od->ddev.channels,
1115 struct omap_chan, vc.chan.device_node); 1068 struct omap_chan, vc.chan.device_node);
@@ -1165,12 +1118,9 @@ static int omap_dma_probe(struct platform_device *pdev)
1165 od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; 1118 od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
1166 od->ddev.dev = &pdev->dev; 1119 od->ddev.dev = &pdev->dev;
1167 INIT_LIST_HEAD(&od->ddev.channels); 1120 INIT_LIST_HEAD(&od->ddev.channels);
1168 INIT_LIST_HEAD(&od->pending);
1169 spin_lock_init(&od->lock); 1121 spin_lock_init(&od->lock);
1170 spin_lock_init(&od->irq_lock); 1122 spin_lock_init(&od->irq_lock);
1171 1123
1172 tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
1173
1174 od->dma_requests = OMAP_SDMA_REQUESTS; 1124 od->dma_requests = OMAP_SDMA_REQUESTS;
1175 if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node, 1125 if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
1176 "dma-requests", 1126 "dma-requests",