aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/at_hdmac.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 18:34:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 18:34:57 -0400
commitef08e78268423fc4d7fbc3e54bd9a67fc8da7cc5 (patch)
treed0561d3ef89c9cd277a38168e33850666cbd33c4 /drivers/dma/at_hdmac.c
parent71db34fc4330f7c784397acb9f1e6ee7f7b32eb2 (diff)
parent5b2e02e401deb44e7f5befe19404d8b2688efea4 (diff)
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
Pull slave-dmaengine update from Vinod Koul: "This includes the cookie cleanup by Russell, the addition of context parameter for dmaengine APIs, more arm dmaengine driver cleanup by moving code to dmaengine, this time for imx by Javier and pl330 by Boojin along with the usual driver fixes." Fix up some fairly trivial conflicts with various other cleanups. * 'next' of git://git.infradead.org/users/vkoul/slave-dma: (67 commits) dmaengine: imx: fix the build failure on x86_64 dmaengine: i.MX: Fix merge of cookie branch. dmaengine: i.MX: Add support for interleaved transfers. dmaengine: imx-dma: use 'dev_dbg' and 'dev_warn' for messages. dmaengine: imx-dma: remove 'imx_dmav1_baseaddr' and 'dma_clk'. dmaengine: imx-dma: remove unused arg of imxdma_sg_next. dmaengine: imx-dma: remove internal structure. dmaengine: imx-dma: remove 'resbytes' field of 'internal' structure. dmaengine: imx-dma: remove 'in_use' field of 'internal' structure. dmaengine: imx-dma: remove sg member from internal structure. dmaengine: imx-dma: remove 'imxdma_setup_sg_hw' function. dmaengine: imx-dma: remove 'imxdma_config_channel_hw' function. dmaengine: imx-dma: remove 'imxdma_setup_mem2mem_hw' function. dmaengine: imx-dma: remove dma_mode member of internal structure. dmaengine: imx-dma: remove data member from internal structure. dmaengine: imx-dma: merge old dma-v1.c with imx-dma.c dmaengine: at_hdmac: add slave config operation dmaengine: add context parameter to prep_slave_sg and prep_dma_cyclic dmaengine/dma_slave: introduce inline wrappers dma: imx-sdma: Treat firmware messages as warnings instead of erros ...
Diffstat (limited to 'drivers/dma/at_hdmac.c')
-rw-r--r--drivers/dma/at_hdmac.c111
1 files changed, 59 insertions, 52 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index f4aed5fc2cb6..7aa58d204892 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -27,6 +27,7 @@
27#include <linux/of_device.h> 27#include <linux/of_device.h>
28 28
29#include "at_hdmac_regs.h" 29#include "at_hdmac_regs.h"
30#include "dmaengine.h"
30 31
31/* 32/*
32 * Glossary 33 * Glossary
@@ -192,27 +193,6 @@ static void atc_desc_chain(struct at_desc **first, struct at_desc **prev,
192} 193}
193 194
194/** 195/**
195 * atc_assign_cookie - compute and assign new cookie
196 * @atchan: channel we work on
197 * @desc: descriptor to assign cookie for
198 *
199 * Called with atchan->lock held and bh disabled
200 */
201static dma_cookie_t
202atc_assign_cookie(struct at_dma_chan *atchan, struct at_desc *desc)
203{
204 dma_cookie_t cookie = atchan->chan_common.cookie;
205
206 if (++cookie < 0)
207 cookie = 1;
208
209 atchan->chan_common.cookie = cookie;
210 desc->txd.cookie = cookie;
211
212 return cookie;
213}
214
215/**
216 * atc_dostart - starts the DMA engine for real 196 * atc_dostart - starts the DMA engine for real
217 * @atchan: the channel we want to start 197 * @atchan: the channel we want to start
218 * @first: first descriptor in the list we want to begin with 198 * @first: first descriptor in the list we want to begin with
@@ -269,7 +249,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
269 dev_vdbg(chan2dev(&atchan->chan_common), 249 dev_vdbg(chan2dev(&atchan->chan_common),
270 "descriptor %u complete\n", txd->cookie); 250 "descriptor %u complete\n", txd->cookie);
271 251
272 atchan->completed_cookie = txd->cookie; 252 dma_cookie_complete(txd);
273 253
274 /* move children to free_list */ 254 /* move children to free_list */
275 list_splice_init(&desc->tx_list, &atchan->free_list); 255 list_splice_init(&desc->tx_list, &atchan->free_list);
@@ -547,7 +527,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
547 unsigned long flags; 527 unsigned long flags;
548 528
549 spin_lock_irqsave(&atchan->lock, flags); 529 spin_lock_irqsave(&atchan->lock, flags);
550 cookie = atc_assign_cookie(atchan, desc); 530 cookie = dma_cookie_assign(tx);
551 531
552 if (list_empty(&atchan->active_list)) { 532 if (list_empty(&atchan->active_list)) {
553 dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n", 533 dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
@@ -659,14 +639,16 @@ err_desc_get:
659 * @sg_len: number of entries in @scatterlist 639 * @sg_len: number of entries in @scatterlist
660 * @direction: DMA direction 640 * @direction: DMA direction
661 * @flags: tx descriptor status flags 641 * @flags: tx descriptor status flags
642 * @context: transaction context (ignored)
662 */ 643 */
663static struct dma_async_tx_descriptor * 644static struct dma_async_tx_descriptor *
664atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, 645atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
665 unsigned int sg_len, enum dma_transfer_direction direction, 646 unsigned int sg_len, enum dma_transfer_direction direction,
666 unsigned long flags) 647 unsigned long flags, void *context)
667{ 648{
668 struct at_dma_chan *atchan = to_at_dma_chan(chan); 649 struct at_dma_chan *atchan = to_at_dma_chan(chan);
669 struct at_dma_slave *atslave = chan->private; 650 struct at_dma_slave *atslave = chan->private;
651 struct dma_slave_config *sconfig = &atchan->dma_sconfig;
670 struct at_desc *first = NULL; 652 struct at_desc *first = NULL;
671 struct at_desc *prev = NULL; 653 struct at_desc *prev = NULL;
672 u32 ctrla; 654 u32 ctrla;
@@ -688,19 +670,18 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
688 return NULL; 670 return NULL;
689 } 671 }
690 672
691 reg_width = atslave->reg_width;
692
693 ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; 673 ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
694 ctrlb = ATC_IEN; 674 ctrlb = ATC_IEN;
695 675
696 switch (direction) { 676 switch (direction) {
697 case DMA_MEM_TO_DEV: 677 case DMA_MEM_TO_DEV:
678 reg_width = convert_buswidth(sconfig->dst_addr_width);
698 ctrla |= ATC_DST_WIDTH(reg_width); 679 ctrla |= ATC_DST_WIDTH(reg_width);
699 ctrlb |= ATC_DST_ADDR_MODE_FIXED 680 ctrlb |= ATC_DST_ADDR_MODE_FIXED
700 | ATC_SRC_ADDR_MODE_INCR 681 | ATC_SRC_ADDR_MODE_INCR
701 | ATC_FC_MEM2PER 682 | ATC_FC_MEM2PER
702 | ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF); 683 | ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF);
703 reg = atslave->tx_reg; 684 reg = sconfig->dst_addr;
704 for_each_sg(sgl, sg, sg_len, i) { 685 for_each_sg(sgl, sg, sg_len, i) {
705 struct at_desc *desc; 686 struct at_desc *desc;
706 u32 len; 687 u32 len;
@@ -728,13 +709,14 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
728 } 709 }
729 break; 710 break;
730 case DMA_DEV_TO_MEM: 711 case DMA_DEV_TO_MEM:
712 reg_width = convert_buswidth(sconfig->src_addr_width);
731 ctrla |= ATC_SRC_WIDTH(reg_width); 713 ctrla |= ATC_SRC_WIDTH(reg_width);
732 ctrlb |= ATC_DST_ADDR_MODE_INCR 714 ctrlb |= ATC_DST_ADDR_MODE_INCR
733 | ATC_SRC_ADDR_MODE_FIXED 715 | ATC_SRC_ADDR_MODE_FIXED
734 | ATC_FC_PER2MEM 716 | ATC_FC_PER2MEM
735 | ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF); 717 | ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF);
736 718
737 reg = atslave->rx_reg; 719 reg = sconfig->src_addr;
738 for_each_sg(sgl, sg, sg_len, i) { 720 for_each_sg(sgl, sg, sg_len, i) {
739 struct at_desc *desc; 721 struct at_desc *desc;
740 u32 len; 722 u32 len;
@@ -810,12 +792,15 @@ err_out:
810 * atc_dma_cyclic_fill_desc - Fill one period decriptor 792 * atc_dma_cyclic_fill_desc - Fill one period decriptor
811 */ 793 */
812static int 794static int
813atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc, 795atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
814 unsigned int period_index, dma_addr_t buf_addr, 796 unsigned int period_index, dma_addr_t buf_addr,
815 size_t period_len, enum dma_transfer_direction direction) 797 unsigned int reg_width, size_t period_len,
798 enum dma_transfer_direction direction)
816{ 799{
817 u32 ctrla; 800 struct at_dma_chan *atchan = to_at_dma_chan(chan);
818 unsigned int reg_width = atslave->reg_width; 801 struct at_dma_slave *atslave = chan->private;
802 struct dma_slave_config *sconfig = &atchan->dma_sconfig;
803 u32 ctrla;
819 804
820 /* prepare common CRTLA value */ 805 /* prepare common CRTLA value */
821 ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla 806 ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla
@@ -826,7 +811,7 @@ atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
826 switch (direction) { 811 switch (direction) {
827 case DMA_MEM_TO_DEV: 812 case DMA_MEM_TO_DEV:
828 desc->lli.saddr = buf_addr + (period_len * period_index); 813 desc->lli.saddr = buf_addr + (period_len * period_index);
829 desc->lli.daddr = atslave->tx_reg; 814 desc->lli.daddr = sconfig->dst_addr;
830 desc->lli.ctrla = ctrla; 815 desc->lli.ctrla = ctrla;
831 desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED 816 desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED
832 | ATC_SRC_ADDR_MODE_INCR 817 | ATC_SRC_ADDR_MODE_INCR
@@ -836,7 +821,7 @@ atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
836 break; 821 break;
837 822
838 case DMA_DEV_TO_MEM: 823 case DMA_DEV_TO_MEM:
839 desc->lli.saddr = atslave->rx_reg; 824 desc->lli.saddr = sconfig->src_addr;
840 desc->lli.daddr = buf_addr + (period_len * period_index); 825 desc->lli.daddr = buf_addr + (period_len * period_index);
841 desc->lli.ctrla = ctrla; 826 desc->lli.ctrla = ctrla;
842 desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR 827 desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR
@@ -860,16 +845,20 @@ atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
860 * @buf_len: total number of bytes for the entire buffer 845 * @buf_len: total number of bytes for the entire buffer
861 * @period_len: number of bytes for each period 846 * @period_len: number of bytes for each period
862 * @direction: transfer direction, to or from device 847 * @direction: transfer direction, to or from device
848 * @context: transfer context (ignored)
863 */ 849 */
864static struct dma_async_tx_descriptor * 850static struct dma_async_tx_descriptor *
865atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, 851atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
866 size_t period_len, enum dma_transfer_direction direction) 852 size_t period_len, enum dma_transfer_direction direction,
853 void *context)
867{ 854{
868 struct at_dma_chan *atchan = to_at_dma_chan(chan); 855 struct at_dma_chan *atchan = to_at_dma_chan(chan);
869 struct at_dma_slave *atslave = chan->private; 856 struct at_dma_slave *atslave = chan->private;
857 struct dma_slave_config *sconfig = &atchan->dma_sconfig;
870 struct at_desc *first = NULL; 858 struct at_desc *first = NULL;
871 struct at_desc *prev = NULL; 859 struct at_desc *prev = NULL;
872 unsigned long was_cyclic; 860 unsigned long was_cyclic;
861 unsigned int reg_width;
873 unsigned int periods = buf_len / period_len; 862 unsigned int periods = buf_len / period_len;
874 unsigned int i; 863 unsigned int i;
875 864
@@ -889,8 +878,13 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
889 return NULL; 878 return NULL;
890 } 879 }
891 880
881 if (sconfig->direction == DMA_MEM_TO_DEV)
882 reg_width = convert_buswidth(sconfig->dst_addr_width);
883 else
884 reg_width = convert_buswidth(sconfig->src_addr_width);
885
892 /* Check for too big/unaligned periods and unaligned DMA buffer */ 886 /* Check for too big/unaligned periods and unaligned DMA buffer */
893 if (atc_dma_cyclic_check_values(atslave->reg_width, buf_addr, 887 if (atc_dma_cyclic_check_values(reg_width, buf_addr,
894 period_len, direction)) 888 period_len, direction))
895 goto err_out; 889 goto err_out;
896 890
@@ -902,8 +896,8 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
902 if (!desc) 896 if (!desc)
903 goto err_desc_get; 897 goto err_desc_get;
904 898
905 if (atc_dma_cyclic_fill_desc(atslave, desc, i, buf_addr, 899 if (atc_dma_cyclic_fill_desc(chan, desc, i, buf_addr,
906 period_len, direction)) 900 reg_width, period_len, direction))
907 goto err_desc_get; 901 goto err_desc_get;
908 902
909 atc_desc_chain(&first, &prev, desc); 903 atc_desc_chain(&first, &prev, desc);
@@ -926,6 +920,23 @@ err_out:
926 return NULL; 920 return NULL;
927} 921}
928 922
923static int set_runtime_config(struct dma_chan *chan,
924 struct dma_slave_config *sconfig)
925{
926 struct at_dma_chan *atchan = to_at_dma_chan(chan);
927
928 /* Check if it is chan is configured for slave transfers */
929 if (!chan->private)
930 return -EINVAL;
931
932 memcpy(&atchan->dma_sconfig, sconfig, sizeof(*sconfig));
933
934 convert_burst(&atchan->dma_sconfig.src_maxburst);
935 convert_burst(&atchan->dma_sconfig.dst_maxburst);
936
937 return 0;
938}
939
929 940
930static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, 941static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
931 unsigned long arg) 942 unsigned long arg)
@@ -986,6 +997,8 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
986 clear_bit(ATC_IS_CYCLIC, &atchan->status); 997 clear_bit(ATC_IS_CYCLIC, &atchan->status);
987 998
988 spin_unlock_irqrestore(&atchan->lock, flags); 999 spin_unlock_irqrestore(&atchan->lock, flags);
1000 } else if (cmd == DMA_SLAVE_CONFIG) {
1001 return set_runtime_config(chan, (struct dma_slave_config *)arg);
989 } else { 1002 } else {
990 return -ENXIO; 1003 return -ENXIO;
991 } 1004 }
@@ -1016,26 +1029,20 @@ atc_tx_status(struct dma_chan *chan,
1016 1029
1017 spin_lock_irqsave(&atchan->lock, flags); 1030 spin_lock_irqsave(&atchan->lock, flags);
1018 1031
1019 last_complete = atchan->completed_cookie; 1032 ret = dma_cookie_status(chan, cookie, txstate);
1020 last_used = chan->cookie;
1021
1022 ret = dma_async_is_complete(cookie, last_complete, last_used);
1023 if (ret != DMA_SUCCESS) { 1033 if (ret != DMA_SUCCESS) {
1024 atc_cleanup_descriptors(atchan); 1034 atc_cleanup_descriptors(atchan);
1025 1035
1026 last_complete = atchan->completed_cookie; 1036 ret = dma_cookie_status(chan, cookie, txstate);
1027 last_used = chan->cookie;
1028
1029 ret = dma_async_is_complete(cookie, last_complete, last_used);
1030 } 1037 }
1031 1038
1039 last_complete = chan->completed_cookie;
1040 last_used = chan->cookie;
1041
1032 spin_unlock_irqrestore(&atchan->lock, flags); 1042 spin_unlock_irqrestore(&atchan->lock, flags);
1033 1043
1034 if (ret != DMA_SUCCESS) 1044 if (ret != DMA_SUCCESS)
1035 dma_set_tx_state(txstate, last_complete, last_used, 1045 dma_set_residue(txstate, atc_first_active(atchan)->len);
1036 atc_first_active(atchan)->len);
1037 else
1038 dma_set_tx_state(txstate, last_complete, last_used, 0);
1039 1046
1040 if (atc_chan_is_paused(atchan)) 1047 if (atc_chan_is_paused(atchan))
1041 ret = DMA_PAUSED; 1048 ret = DMA_PAUSED;
@@ -1129,7 +1136,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
1129 spin_lock_irqsave(&atchan->lock, flags); 1136 spin_lock_irqsave(&atchan->lock, flags);
1130 atchan->descs_allocated = i; 1137 atchan->descs_allocated = i;
1131 list_splice(&tmp_list, &atchan->free_list); 1138 list_splice(&tmp_list, &atchan->free_list);
1132 atchan->completed_cookie = chan->cookie = 1; 1139 dma_cookie_init(chan);
1133 spin_unlock_irqrestore(&atchan->lock, flags); 1140 spin_unlock_irqrestore(&atchan->lock, flags);
1134 1141
1135 /* channel parameters */ 1142 /* channel parameters */
@@ -1329,7 +1336,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
1329 struct at_dma_chan *atchan = &atdma->chan[i]; 1336 struct at_dma_chan *atchan = &atdma->chan[i];
1330 1337
1331 atchan->chan_common.device = &atdma->dma_common; 1338 atchan->chan_common.device = &atdma->dma_common;
1332 atchan->chan_common.cookie = atchan->completed_cookie = 1; 1339 dma_cookie_init(&atchan->chan_common);
1333 list_add_tail(&atchan->chan_common.device_node, 1340 list_add_tail(&atchan->chan_common.device_node,
1334 &atdma->dma_common.channels); 1341 &atdma->dma_common.channels);
1335 1342