From 0f70e8cea3ac6a765289811c590a16934bf47711 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 15 Dec 2010 18:50:16 +0100 Subject: dmaengine: at_hdmac: use dma_address to program DMA hardware In atc_prep_slave_sg() function we use dma_address field of scatterlist with sg_dma_address() macro instead of sg_phys(). DMA address is already computed by dma_map_sg() or another mapping function in calling driver. Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e0..6eea8883ecf 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -670,7 +670,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!desc) goto err_desc_get; - mem = sg_phys(sg); + mem = sg_dma_address(sg); len = sg_dma_len(sg); mem_width = 2; if (unlikely(mem & 3 || len & 3)) @@ -712,7 +712,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!desc) goto err_desc_get; - mem = sg_phys(sg); + mem = sg_dma_address(sg); len = sg_dma_len(sg); mem_width = 2; if (unlikely(mem & 3 || len & 3)) -- cgit v1.2.3 From ebcf9b80f9657f44fcb60ee17abe14eadebf3386 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 12 Jan 2011 15:39:06 +0100 Subject: dmaengine: at_hdmac: trivial add precision to unmapping comment Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 6eea8883ecf..73a470b4809 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -253,7 +253,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) /* move myself to free_list */ list_move(&desc->desc_node, &atchan->free_list); - /* unmap dma addresses */ + /* unmap dma addresses (not on slave channels) */ if (!atchan->chan_common.private) { struct device *parent = chan2parent(&atchan->chan_common); if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { -- cgit v1.2.3 From 58344f25cf5f3453bfcf4b845ea9ec71153e45c3 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 12 Jan 2011 15:39:07 +0100 Subject: dmaengine: at_hdmac: no need set ACK in new descriptor Following descriptor flow in at_hdmac driver, descriptor comming from atc_desc_get() as already DMA_CTRL_ACK flag set. No need to set it again. Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 73a470b4809..c6ddd6ffb8f 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -583,7 +583,6 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, desc->lli.ctrlb = ctrlb; desc->txd.cookie = 0; - async_tx_ack(&desc->txd); if (!first) { first = desc; -- cgit v1.2.3 From 93d0bec2be4b0f036a27da207ecab97fc3d3bbbe Mon Sep 17 00:00:00 2001 From: Eric Xu Date: Wed, 12 Jan 2011 15:39:08 +0100 Subject: dmaengine: at_hdmac: use subsys_initcall instead of module_init Use subsys_initcall instead of module_init in order to keep DMA engine rolling before other peripheral drivers. Signed-off-by: Eric Xu Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index c6ddd6ffb8f..e25c4ad0106 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1209,7 +1209,7 @@ static int __init at_dma_init(void) { return platform_driver_probe(&at_dma_driver, at_dma_probe); } -module_init(at_dma_init); +subsys_initcall(at_dma_init); static void __exit at_dma_exit(void) { -- cgit v1.2.3 From 568f7f0c2e597671d3e646e0b85c95c4a5756fef Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 12 Jan 2011 15:39:09 +0100 Subject: dmaengine: at_hdmac: flags located in first descriptor Place flags on first descriptor of chain instead of last. This is the one used by atc_chain_complete() function while unmapping. Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index e25c4ad0106..3938db21083 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -603,7 +603,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, /* set end-of-link to the last link descriptor of list*/ set_desc_eol(desc); - desc->txd.flags = flags; /* client is in control of this ack */ + first->txd.flags = flags; /* client is in control of this ack */ return &first->txd; @@ -748,8 +748,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, first->txd.cookie = -EBUSY; first->len = total_len; - /* last link descriptor of list is responsible of flags */ - prev->txd.flags = flags; /* client is in control of this ack */ + /* first link descriptor of list is responsible of flags */ + first->txd.flags = flags; /* client is in control of this ack */ return &first->txd; -- cgit v1.2.3 From dda36f9821321edf65d69da5c0807df7e73d26fc Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 12 Jan 2011 15:39:10 +0100 Subject: dmaengine: at_hdmac: fix race while monitoring channel status We were reading channel status then taking a lock. This lead to a race because this lock may delay us and then make this channel not idle anymore. Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma/at_hdmac.c') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 3938db21083..40f2bf4ae47 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -853,11 +853,11 @@ static void atc_issue_pending(struct dma_chan *chan) dev_vdbg(chan2dev(chan), "issue_pending\n"); + spin_lock_bh(&atchan->lock); if (!atc_chan_is_enabled(atchan)) { - spin_lock_bh(&atchan->lock); atc_advance_work(atchan); - spin_unlock_bh(&atchan->lock); } + spin_unlock_bh(&atchan->lock); } /** -- cgit v1.2.3