diff options
author | NeilBrown <neilb@suse.de> | 2009-09-23 04:31:11 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-09-23 04:31:11 -0400 |
commit | 4b3df5668c8ebaebd8d66a5a94374be3e3b2ef0c (patch) | |
tree | 51a231742e211143f5845edf4b09d1712dcd2771 /drivers/dma/at_hdmac.c | |
parent | 1ef04fefe2241087d9db7e9615c3f11b516e36cf (diff) | |
parent | 1f6672d44c1ae7408b43c06170ec34eb0a0e9b9f (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx into for-linus
Diffstat (limited to 'drivers/dma/at_hdmac.c')
-rw-r--r-- | drivers/dma/at_hdmac.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index c8522e6f1ad2..7585c4164bd5 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -87,6 +87,7 @@ static struct at_desc *atc_alloc_descriptor(struct dma_chan *chan, | |||
87 | desc = dma_pool_alloc(atdma->dma_desc_pool, gfp_flags, &phys); | 87 | desc = dma_pool_alloc(atdma->dma_desc_pool, gfp_flags, &phys); |
88 | if (desc) { | 88 | if (desc) { |
89 | memset(desc, 0, sizeof(struct at_desc)); | 89 | memset(desc, 0, sizeof(struct at_desc)); |
90 | INIT_LIST_HEAD(&desc->tx_list); | ||
90 | dma_async_tx_descriptor_init(&desc->txd, chan); | 91 | dma_async_tx_descriptor_init(&desc->txd, chan); |
91 | /* txd.flags will be overwritten in prep functions */ | 92 | /* txd.flags will be overwritten in prep functions */ |
92 | desc->txd.flags = DMA_CTRL_ACK; | 93 | desc->txd.flags = DMA_CTRL_ACK; |
@@ -150,11 +151,11 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) | |||
150 | struct at_desc *child; | 151 | struct at_desc *child; |
151 | 152 | ||
152 | spin_lock_bh(&atchan->lock); | 153 | spin_lock_bh(&atchan->lock); |
153 | list_for_each_entry(child, &desc->txd.tx_list, desc_node) | 154 | list_for_each_entry(child, &desc->tx_list, desc_node) |
154 | dev_vdbg(chan2dev(&atchan->chan_common), | 155 | dev_vdbg(chan2dev(&atchan->chan_common), |
155 | "moving child desc %p to freelist\n", | 156 | "moving child desc %p to freelist\n", |
156 | child); | 157 | child); |
157 | list_splice_init(&desc->txd.tx_list, &atchan->free_list); | 158 | list_splice_init(&desc->tx_list, &atchan->free_list); |
158 | dev_vdbg(chan2dev(&atchan->chan_common), | 159 | dev_vdbg(chan2dev(&atchan->chan_common), |
159 | "moving desc %p to freelist\n", desc); | 160 | "moving desc %p to freelist\n", desc); |
160 | list_add(&desc->desc_node, &atchan->free_list); | 161 | list_add(&desc->desc_node, &atchan->free_list); |
@@ -247,30 +248,33 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) | |||
247 | param = txd->callback_param; | 248 | param = txd->callback_param; |
248 | 249 | ||
249 | /* move children to free_list */ | 250 | /* move children to free_list */ |
250 | list_splice_init(&txd->tx_list, &atchan->free_list); | 251 | list_splice_init(&desc->tx_list, &atchan->free_list); |
251 | /* move myself to free_list */ | 252 | /* move myself to free_list */ |
252 | list_move(&desc->desc_node, &atchan->free_list); | 253 | list_move(&desc->desc_node, &atchan->free_list); |
253 | 254 | ||
254 | /* unmap dma addresses */ | 255 | /* unmap dma addresses */ |
255 | if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { | 256 | if (!atchan->chan_common.private) { |
256 | if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) | 257 | struct device *parent = chan2parent(&atchan->chan_common); |
257 | dma_unmap_single(chan2parent(&atchan->chan_common), | 258 | if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { |
258 | desc->lli.daddr, | 259 | if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) |
259 | desc->len, DMA_FROM_DEVICE); | 260 | dma_unmap_single(parent, |
260 | else | 261 | desc->lli.daddr, |
261 | dma_unmap_page(chan2parent(&atchan->chan_common), | 262 | desc->len, DMA_FROM_DEVICE); |
262 | desc->lli.daddr, | 263 | else |
263 | desc->len, DMA_FROM_DEVICE); | 264 | dma_unmap_page(parent, |
264 | } | 265 | desc->lli.daddr, |
265 | if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { | 266 | desc->len, DMA_FROM_DEVICE); |
266 | if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) | 267 | } |
267 | dma_unmap_single(chan2parent(&atchan->chan_common), | 268 | if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { |
268 | desc->lli.saddr, | 269 | if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) |
269 | desc->len, DMA_TO_DEVICE); | 270 | dma_unmap_single(parent, |
270 | else | 271 | desc->lli.saddr, |
271 | dma_unmap_page(chan2parent(&atchan->chan_common), | 272 | desc->len, DMA_TO_DEVICE); |
272 | desc->lli.saddr, | 273 | else |
273 | desc->len, DMA_TO_DEVICE); | 274 | dma_unmap_page(parent, |
275 | desc->lli.saddr, | ||
276 | desc->len, DMA_TO_DEVICE); | ||
277 | } | ||
274 | } | 278 | } |
275 | 279 | ||
276 | /* | 280 | /* |
@@ -334,7 +338,7 @@ static void atc_cleanup_descriptors(struct at_dma_chan *atchan) | |||
334 | /* This one is currently in progress */ | 338 | /* This one is currently in progress */ |
335 | return; | 339 | return; |
336 | 340 | ||
337 | list_for_each_entry(child, &desc->txd.tx_list, desc_node) | 341 | list_for_each_entry(child, &desc->tx_list, desc_node) |
338 | if (!(child->lli.ctrla & ATC_DONE)) | 342 | if (!(child->lli.ctrla & ATC_DONE)) |
339 | /* Currently in progress */ | 343 | /* Currently in progress */ |
340 | return; | 344 | return; |
@@ -407,7 +411,7 @@ static void atc_handle_error(struct at_dma_chan *atchan) | |||
407 | dev_crit(chan2dev(&atchan->chan_common), | 411 | dev_crit(chan2dev(&atchan->chan_common), |
408 | " cookie: %d\n", bad_desc->txd.cookie); | 412 | " cookie: %d\n", bad_desc->txd.cookie); |
409 | atc_dump_lli(atchan, &bad_desc->lli); | 413 | atc_dump_lli(atchan, &bad_desc->lli); |
410 | list_for_each_entry(child, &bad_desc->txd.tx_list, desc_node) | 414 | list_for_each_entry(child, &bad_desc->tx_list, desc_node) |
411 | atc_dump_lli(atchan, &child->lli); | 415 | atc_dump_lli(atchan, &child->lli); |
412 | 416 | ||
413 | /* Pretend the descriptor completed successfully */ | 417 | /* Pretend the descriptor completed successfully */ |
@@ -587,7 +591,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
587 | prev->lli.dscr = desc->txd.phys; | 591 | prev->lli.dscr = desc->txd.phys; |
588 | /* insert the link descriptor to the LD ring */ | 592 | /* insert the link descriptor to the LD ring */ |
589 | list_add_tail(&desc->desc_node, | 593 | list_add_tail(&desc->desc_node, |
590 | &first->txd.tx_list); | 594 | &first->tx_list); |
591 | } | 595 | } |
592 | prev = desc; | 596 | prev = desc; |
593 | } | 597 | } |
@@ -646,8 +650,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
646 | 650 | ||
647 | reg_width = atslave->reg_width; | 651 | reg_width = atslave->reg_width; |
648 | 652 | ||
649 | sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction); | ||
650 | |||
651 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; | 653 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; |
652 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN; | 654 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN; |
653 | 655 | ||
@@ -687,7 +689,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
687 | prev->lli.dscr = desc->txd.phys; | 689 | prev->lli.dscr = desc->txd.phys; |
688 | /* insert the link descriptor to the LD ring */ | 690 | /* insert the link descriptor to the LD ring */ |
689 | list_add_tail(&desc->desc_node, | 691 | list_add_tail(&desc->desc_node, |
690 | &first->txd.tx_list); | 692 | &first->tx_list); |
691 | } | 693 | } |
692 | prev = desc; | 694 | prev = desc; |
693 | total_len += len; | 695 | total_len += len; |
@@ -729,7 +731,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
729 | prev->lli.dscr = desc->txd.phys; | 731 | prev->lli.dscr = desc->txd.phys; |
730 | /* insert the link descriptor to the LD ring */ | 732 | /* insert the link descriptor to the LD ring */ |
731 | list_add_tail(&desc->desc_node, | 733 | list_add_tail(&desc->desc_node, |
732 | &first->txd.tx_list); | 734 | &first->tx_list); |
733 | } | 735 | } |
734 | prev = desc; | 736 | prev = desc; |
735 | total_len += len; | 737 | total_len += len; |