diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2010-03-26 19:50:49 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2010-03-26 19:50:49 -0400 |
commit | 0793448187643b50af89d36b08470baf45a3cab4 (patch) | |
tree | b3313ff58d47e26a8cf707d196177effa1aadfbe | |
parent | c3635c78e500a52c9fcd55de381a72928d9e054d (diff) |
DMAENGINE: generic channel status v2
Convert the device_is_tx_complete() operation on the
DMA engine to a generic device_tx_status()operation which
can return three states, DMA_TX_RUNNING, DMA_TX_COMPLETE,
DMA_TX_PAUSED.
[dan.j.williams@intel.com: update for timberdale]
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Maciej Sosnowski <maciej.sosnowski@intel.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Li Yang <leoli@freescale.com>
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Cc: Magnus Damm <damm@opensource.se>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
Cc: Joe Perches <joe@perches.com>
Cc: Roland Dreier <rdreier@cisco.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | arch/arm/mach-u300/include/mach/coh901318.h | 7 | ||||
-rw-r--r-- | drivers/dma/at_hdmac.c | 29 | ||||
-rw-r--r-- | drivers/dma/coh901318.c | 25 | ||||
-rw-r--r-- | drivers/dma/dmaengine.c | 2 | ||||
-rw-r--r-- | drivers/dma/dw_dmac.c | 17 | ||||
-rw-r--r-- | drivers/dma/fsldma.c | 19 | ||||
-rw-r--r-- | drivers/dma/ioat/dma.c | 12 | ||||
-rw-r--r-- | drivers/dma/ioat/dma.h | 22 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v2.c | 2 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 20 | ||||
-rw-r--r-- | drivers/dma/iop-adma.c | 44 | ||||
-rw-r--r-- | drivers/dma/ipu/ipu_idmac.c | 15 | ||||
-rw-r--r-- | drivers/dma/mpc512x_dma.c | 16 | ||||
-rw-r--r-- | drivers/dma/mv_xor.c | 32 | ||||
-rw-r--r-- | drivers/dma/ppc4xx/adma.c | 27 | ||||
-rw-r--r-- | drivers/dma/shdma.c | 17 | ||||
-rw-r--r-- | drivers/dma/timb_dma.c | 15 | ||||
-rw-r--r-- | drivers/dma/txx9dmac.c | 16 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 38 |
19 files changed, 203 insertions, 172 deletions
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 43ec040e765b..193da2df732c 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h | |||
@@ -103,13 +103,6 @@ struct coh901318_platform { | |||
103 | }; | 103 | }; |
104 | 104 | ||
105 | /** | 105 | /** |
106 | * coh901318_get_bytes_left() - Get number of bytes left on a current transfer | ||
107 | * @chan: dma channel handle | ||
108 | * return number of bytes left, or negative on error | ||
109 | */ | ||
110 | u32 coh901318_get_bytes_left(struct dma_chan *chan); | ||
111 | |||
112 | /** | ||
113 | * coh901318_filter_id() - DMA channel filter function | 106 | * coh901318_filter_id() - DMA channel filter function |
114 | * @chan: dma channel handle | 107 | * @chan: dma channel handle |
115 | * @chan_id: id of dma channel to be filter out | 108 | * @chan_id: id of dma channel to be filter out |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index f9143cf9e50a..ff75cf18d32e 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -798,29 +798,25 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) | |||
798 | } | 798 | } |
799 | 799 | ||
800 | /** | 800 | /** |
801 | * atc_is_tx_complete - poll for transaction completion | 801 | * atc_tx_status - poll for transaction completion |
802 | * @chan: DMA channel | 802 | * @chan: DMA channel |
803 | * @cookie: transaction identifier to check status of | 803 | * @cookie: transaction identifier to check status of |
804 | * @done: if not %NULL, updated with last completed transaction | 804 | * @txstate: if not %NULL updated with transaction state |
805 | * @used: if not %NULL, updated with last used transaction | ||
806 | * | 805 | * |
807 | * If @done and @used are passed in, upon return they reflect the driver | 806 | * If @txstate is passed in, upon return it reflect the driver |
808 | * internal state and can be used with dma_async_is_complete() to check | 807 | * internal state and can be used with dma_async_is_complete() to check |
809 | * the status of multiple cookies without re-checking hardware state. | 808 | * the status of multiple cookies without re-checking hardware state. |
810 | */ | 809 | */ |
811 | static enum dma_status | 810 | static enum dma_status |
812 | atc_is_tx_complete(struct dma_chan *chan, | 811 | atc_tx_status(struct dma_chan *chan, |
813 | dma_cookie_t cookie, | 812 | dma_cookie_t cookie, |
814 | dma_cookie_t *done, dma_cookie_t *used) | 813 | struct dma_tx_state *txstate) |
815 | { | 814 | { |
816 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | 815 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
817 | dma_cookie_t last_used; | 816 | dma_cookie_t last_used; |
818 | dma_cookie_t last_complete; | 817 | dma_cookie_t last_complete; |
819 | enum dma_status ret; | 818 | enum dma_status ret; |
820 | 819 | ||
821 | dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", | ||
822 | cookie, done ? *done : 0, used ? *used : 0); | ||
823 | |||
824 | spin_lock_bh(&atchan->lock); | 820 | spin_lock_bh(&atchan->lock); |
825 | 821 | ||
826 | last_complete = atchan->completed_cookie; | 822 | last_complete = atchan->completed_cookie; |
@@ -838,10 +834,15 @@ atc_is_tx_complete(struct dma_chan *chan, | |||
838 | 834 | ||
839 | spin_unlock_bh(&atchan->lock); | 835 | spin_unlock_bh(&atchan->lock); |
840 | 836 | ||
841 | if (done) | 837 | if (txstate) { |
842 | *done = last_complete; | 838 | txstate->last = last_complete; |
843 | if (used) | 839 | txstate->used = last_used; |
844 | *used = last_used; | 840 | txstate->residue = 0; |
841 | } | ||
842 | |||
843 | dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", | ||
844 | cookie, last_complete ? last_complete : 0, | ||
845 | last_used ? last_used : 0); | ||
845 | 846 | ||
846 | return ret; | 847 | return ret; |
847 | } | 848 | } |
@@ -1087,7 +1088,7 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1087 | /* set base routines */ | 1088 | /* set base routines */ |
1088 | atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; | 1089 | atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; |
1089 | atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; | 1090 | atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; |
1090 | atdma->dma_common.device_is_tx_complete = atc_is_tx_complete; | 1091 | atdma->dma_common.device_tx_status = atc_tx_status; |
1091 | atdma->dma_common.device_issue_pending = atc_issue_pending; | 1092 | atdma->dma_common.device_issue_pending = atc_issue_pending; |
1092 | atdma->dma_common.dev = &pdev->dev; | 1093 | atdma->dma_common.dev = &pdev->dev; |
1093 | 1094 | ||
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 53c54e034aa3..309db3beef16 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
@@ -426,7 +426,7 @@ static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) | |||
426 | * absolute measures, but for a rough guess you can still call | 426 | * absolute measures, but for a rough guess you can still call |
427 | * it. | 427 | * it. |
428 | */ | 428 | */ |
429 | u32 coh901318_get_bytes_left(struct dma_chan *chan) | 429 | static u32 coh901318_get_bytes_left(struct dma_chan *chan) |
430 | { | 430 | { |
431 | struct coh901318_chan *cohc = to_coh901318_chan(chan); | 431 | struct coh901318_chan *cohc = to_coh901318_chan(chan); |
432 | struct coh901318_desc *cohd; | 432 | struct coh901318_desc *cohd; |
@@ -503,8 +503,6 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) | |||
503 | 503 | ||
504 | return left; | 504 | return left; |
505 | } | 505 | } |
506 | EXPORT_SYMBOL(coh901318_get_bytes_left); | ||
507 | |||
508 | 506 | ||
509 | /* | 507 | /* |
510 | * Pauses a transfer without losing data. Enables power save. | 508 | * Pauses a transfer without losing data. Enables power save. |
@@ -1136,9 +1134,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
1136 | } | 1134 | } |
1137 | 1135 | ||
1138 | static enum dma_status | 1136 | static enum dma_status |
1139 | coh901318_is_tx_complete(struct dma_chan *chan, | 1137 | coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, |
1140 | dma_cookie_t cookie, dma_cookie_t *done, | 1138 | struct dma_tx_state *txstate) |
1141 | dma_cookie_t *used) | ||
1142 | { | 1139 | { |
1143 | struct coh901318_chan *cohc = to_coh901318_chan(chan); | 1140 | struct coh901318_chan *cohc = to_coh901318_chan(chan); |
1144 | dma_cookie_t last_used; | 1141 | dma_cookie_t last_used; |
@@ -1150,10 +1147,14 @@ coh901318_is_tx_complete(struct dma_chan *chan, | |||
1150 | 1147 | ||
1151 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 1148 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
1152 | 1149 | ||
1153 | if (done) | 1150 | if (txstate) { |
1154 | *done = last_complete; | 1151 | txstate->last = last_complete; |
1155 | if (used) | 1152 | txstate->used = last_used; |
1156 | *used = last_used; | 1153 | txstate->residue = coh901318_get_bytes_left(chan); |
1154 | } | ||
1155 | |||
1156 | if (ret == DMA_IN_PROGRESS && cohc->stopped) | ||
1157 | ret = DMA_PAUSED; | ||
1157 | 1158 | ||
1158 | return ret; | 1159 | return ret; |
1159 | } | 1160 | } |
@@ -1356,7 +1357,7 @@ static int __init coh901318_probe(struct platform_device *pdev) | |||
1356 | base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; | 1357 | base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; |
1357 | base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; | 1358 | base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; |
1358 | base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; | 1359 | base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; |
1359 | base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; | 1360 | base->dma_slave.device_tx_status = coh901318_tx_status; |
1360 | base->dma_slave.device_issue_pending = coh901318_issue_pending; | 1361 | base->dma_slave.device_issue_pending = coh901318_issue_pending; |
1361 | base->dma_slave.device_control = coh901318_control; | 1362 | base->dma_slave.device_control = coh901318_control; |
1362 | base->dma_slave.dev = &pdev->dev; | 1363 | base->dma_slave.dev = &pdev->dev; |
@@ -1376,7 +1377,7 @@ static int __init coh901318_probe(struct platform_device *pdev) | |||
1376 | base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; | 1377 | base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; |
1377 | base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; | 1378 | base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; |
1378 | base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; | 1379 | base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; |
1379 | base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; | 1380 | base->dma_memcpy.device_tx_status = coh901318_tx_status; |
1380 | base->dma_memcpy.device_issue_pending = coh901318_issue_pending; | 1381 | base->dma_memcpy.device_issue_pending = coh901318_issue_pending; |
1381 | base->dma_memcpy.device_control = coh901318_control; | 1382 | base->dma_memcpy.device_control = coh901318_control; |
1382 | base->dma_memcpy.dev = &pdev->dev; | 1383 | base->dma_memcpy.dev = &pdev->dev; |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ffc4ee9c5e21..790caeeb4ccd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -698,7 +698,7 @@ int dma_async_device_register(struct dma_device *device) | |||
698 | 698 | ||
699 | BUG_ON(!device->device_alloc_chan_resources); | 699 | BUG_ON(!device->device_alloc_chan_resources); |
700 | BUG_ON(!device->device_free_chan_resources); | 700 | BUG_ON(!device->device_free_chan_resources); |
701 | BUG_ON(!device->device_is_tx_complete); | 701 | BUG_ON(!device->device_tx_status); |
702 | BUG_ON(!device->device_issue_pending); | 702 | BUG_ON(!device->device_issue_pending); |
703 | BUG_ON(!device->dev); | 703 | BUG_ON(!device->dev); |
704 | 704 | ||
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 8a6b85f61176..263b70ee8562 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -819,9 +819,9 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) | |||
819 | } | 819 | } |
820 | 820 | ||
821 | static enum dma_status | 821 | static enum dma_status |
822 | dwc_is_tx_complete(struct dma_chan *chan, | 822 | dwc_tx_status(struct dma_chan *chan, |
823 | dma_cookie_t cookie, | 823 | dma_cookie_t cookie, |
824 | dma_cookie_t *done, dma_cookie_t *used) | 824 | struct dma_tx_state *txstate) |
825 | { | 825 | { |
826 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 826 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
827 | dma_cookie_t last_used; | 827 | dma_cookie_t last_used; |
@@ -841,10 +841,11 @@ dwc_is_tx_complete(struct dma_chan *chan, | |||
841 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 841 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
842 | } | 842 | } |
843 | 843 | ||
844 | if (done) | 844 | if (txstate) { |
845 | *done = last_complete; | 845 | txstate->last = last_complete; |
846 | if (used) | 846 | txstate->used = last_used; |
847 | *used = last_used; | 847 | txstate->residue = 0; |
848 | } | ||
848 | 849 | ||
849 | return ret; | 850 | return ret; |
850 | } | 851 | } |
@@ -1346,7 +1347,7 @@ static int __init dw_probe(struct platform_device *pdev) | |||
1346 | dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; | 1347 | dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; |
1347 | dw->dma.device_control = dwc_control; | 1348 | dw->dma.device_control = dwc_control; |
1348 | 1349 | ||
1349 | dw->dma.device_is_tx_complete = dwc_is_tx_complete; | 1350 | dw->dma.device_tx_status = dwc_tx_status; |
1350 | dw->dma.device_issue_pending = dwc_issue_pending; | 1351 | dw->dma.device_issue_pending = dwc_issue_pending; |
1351 | 1352 | ||
1352 | dma_writel(dw, CFG, DW_CFG_DMA_EN); | 1353 | dma_writel(dw, CFG, DW_CFG_DMA_EN); |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 714fc46e7695..ca5e8a3dce72 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -971,13 +971,12 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) | |||
971 | } | 971 | } |
972 | 972 | ||
973 | /** | 973 | /** |
974 | * fsl_dma_is_complete - Determine the DMA status | 974 | * fsl_tx_status - Determine the DMA status |
975 | * @chan : Freescale DMA channel | 975 | * @chan : Freescale DMA channel |
976 | */ | 976 | */ |
977 | static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, | 977 | static enum dma_status fsl_tx_status(struct dma_chan *dchan, |
978 | dma_cookie_t cookie, | 978 | dma_cookie_t cookie, |
979 | dma_cookie_t *done, | 979 | struct dma_tx_state *txstate) |
980 | dma_cookie_t *used) | ||
981 | { | 980 | { |
982 | struct fsldma_chan *chan = to_fsl_chan(dchan); | 981 | struct fsldma_chan *chan = to_fsl_chan(dchan); |
983 | dma_cookie_t last_used; | 982 | dma_cookie_t last_used; |
@@ -988,11 +987,11 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, | |||
988 | last_used = dchan->cookie; | 987 | last_used = dchan->cookie; |
989 | last_complete = chan->completed_cookie; | 988 | last_complete = chan->completed_cookie; |
990 | 989 | ||
991 | if (done) | 990 | if (txstate) { |
992 | *done = last_complete; | 991 | txstate->last = last_complete; |
993 | 992 | txstate->used = last_used; | |
994 | if (used) | 993 | txstate->residue = 0; |
995 | *used = last_used; | 994 | } |
996 | 995 | ||
997 | return dma_async_is_complete(cookie, last_complete, last_used); | 996 | return dma_async_is_complete(cookie, last_complete, last_used); |
998 | } | 997 | } |
@@ -1336,7 +1335,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, | |||
1336 | fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; | 1335 | fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; |
1337 | fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; | 1336 | fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; |
1338 | fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; | 1337 | fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; |
1339 | fdev->common.device_is_tx_complete = fsl_dma_is_complete; | 1338 | fdev->common.device_tx_status = fsl_tx_status; |
1340 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; | 1339 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; |
1341 | fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; | 1340 | fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; |
1342 | fdev->common.device_control = fsl_dma_device_control; | 1341 | fdev->common.device_control = fsl_dma_device_control; |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 0099340b9616..59cebbfc89ec 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -726,18 +726,18 @@ static void ioat1_timer_event(unsigned long data) | |||
726 | } | 726 | } |
727 | 727 | ||
728 | enum dma_status | 728 | enum dma_status |
729 | ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, | 729 | ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, |
730 | dma_cookie_t *done, dma_cookie_t *used) | 730 | struct dma_tx_state *txstate) |
731 | { | 731 | { |
732 | struct ioat_chan_common *chan = to_chan_common(c); | 732 | struct ioat_chan_common *chan = to_chan_common(c); |
733 | struct ioatdma_device *device = chan->device; | 733 | struct ioatdma_device *device = chan->device; |
734 | 734 | ||
735 | if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) | 735 | if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) |
736 | return DMA_SUCCESS; | 736 | return DMA_SUCCESS; |
737 | 737 | ||
738 | device->cleanup_fn((unsigned long) c); | 738 | device->cleanup_fn((unsigned long) c); |
739 | 739 | ||
740 | return ioat_is_complete(c, cookie, done, used); | 740 | return ioat_tx_status(c, cookie, txstate); |
741 | } | 741 | } |
742 | 742 | ||
743 | static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat) | 743 | static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat) |
@@ -857,7 +857,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device) | |||
857 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); | 857 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); |
858 | 858 | ||
859 | if (tmo == 0 || | 859 | if (tmo == 0 || |
860 | dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) | 860 | dma->device_tx_status(dma_chan, cookie, NULL) |
861 | != DMA_SUCCESS) { | 861 | != DMA_SUCCESS) { |
862 | dev_err(dev, "Self-test copy timed out, disabling\n"); | 862 | dev_err(dev, "Self-test copy timed out, disabling\n"); |
863 | err = -ENODEV; | 863 | err = -ENODEV; |
@@ -1198,7 +1198,7 @@ int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca) | |||
1198 | dma->device_issue_pending = ioat1_dma_memcpy_issue_pending; | 1198 | dma->device_issue_pending = ioat1_dma_memcpy_issue_pending; |
1199 | dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources; | 1199 | dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources; |
1200 | dma->device_free_chan_resources = ioat1_dma_free_chan_resources; | 1200 | dma->device_free_chan_resources = ioat1_dma_free_chan_resources; |
1201 | dma->device_is_tx_complete = ioat_is_dma_complete; | 1201 | dma->device_tx_status = ioat_dma_tx_status; |
1202 | 1202 | ||
1203 | err = ioat_probe(device); | 1203 | err = ioat_probe(device); |
1204 | if (err) | 1204 | if (err) |
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..23399672239e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -142,15 +142,14 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | /** | 144 | /** |
145 | * ioat_is_complete - poll the status of an ioat transaction | 145 | * ioat_tx_status - poll the status of an ioat transaction |
146 | * @c: channel handle | 146 | * @c: channel handle |
147 | * @cookie: transaction identifier | 147 | * @cookie: transaction identifier |
148 | * @done: if set, updated with last completed transaction | 148 | * @txstate: if set, updated with the transaction state |
149 | * @used: if set, updated with last used transaction | ||
150 | */ | 149 | */ |
151 | static inline enum dma_status | 150 | static inline enum dma_status |
152 | ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, | 151 | ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, |
153 | dma_cookie_t *done, dma_cookie_t *used) | 152 | struct dma_tx_state *txstate) |
154 | { | 153 | { |
155 | struct ioat_chan_common *chan = to_chan_common(c); | 154 | struct ioat_chan_common *chan = to_chan_common(c); |
156 | dma_cookie_t last_used; | 155 | dma_cookie_t last_used; |
@@ -159,10 +158,11 @@ ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, | |||
159 | last_used = c->cookie; | 158 | last_used = c->cookie; |
160 | last_complete = chan->completed_cookie; | 159 | last_complete = chan->completed_cookie; |
161 | 160 | ||
162 | if (done) | 161 | if (txstate) { |
163 | *done = last_complete; | 162 | txstate->last = last_complete; |
164 | if (used) | 163 | txstate->used = last_used; |
165 | *used = last_used; | 164 | txstate->residue = 0; |
165 | } | ||
166 | 166 | ||
167 | return dma_async_is_complete(cookie, last_complete, last_used); | 167 | return dma_async_is_complete(cookie, last_complete, last_used); |
168 | } | 168 | } |
@@ -338,8 +338,8 @@ struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, | |||
338 | unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); | 338 | unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); |
339 | void ioat_init_channel(struct ioatdma_device *device, | 339 | void ioat_init_channel(struct ioatdma_device *device, |
340 | struct ioat_chan_common *chan, int idx); | 340 | struct ioat_chan_common *chan, int idx); |
341 | enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, | 341 | enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, |
342 | dma_cookie_t *done, dma_cookie_t *used); | 342 | struct dma_tx_state *txstate); |
343 | void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, | 343 | void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, |
344 | size_t len, struct ioat_dma_descriptor *hw); | 344 | size_t len, struct ioat_dma_descriptor *hw); |
345 | bool ioat_cleanup_preamble(struct ioat_chan_common *chan, | 345 | bool ioat_cleanup_preamble(struct ioat_chan_common *chan, |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 1ed5d66d7dca..f540e0be7f31 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -854,7 +854,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) | |||
854 | dma->device_issue_pending = ioat2_issue_pending; | 854 | dma->device_issue_pending = ioat2_issue_pending; |
855 | dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; | 855 | dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; |
856 | dma->device_free_chan_resources = ioat2_free_chan_resources; | 856 | dma->device_free_chan_resources = ioat2_free_chan_resources; |
857 | dma->device_is_tx_complete = ioat_is_dma_complete; | 857 | dma->device_tx_status = ioat_tx_status; |
858 | 858 | ||
859 | err = ioat_probe(device); | 859 | err = ioat_probe(device); |
860 | if (err) | 860 | if (err) |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 26febc56dab1..d1adbf35268c 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -438,17 +438,17 @@ static void ioat3_timer_event(unsigned long data) | |||
438 | } | 438 | } |
439 | 439 | ||
440 | static enum dma_status | 440 | static enum dma_status |
441 | ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, | 441 | ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie, |
442 | dma_cookie_t *done, dma_cookie_t *used) | 442 | struct dma_tx_state *txstate) |
443 | { | 443 | { |
444 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); | 444 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); |
445 | 445 | ||
446 | if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) | 446 | if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) |
447 | return DMA_SUCCESS; | 447 | return DMA_SUCCESS; |
448 | 448 | ||
449 | ioat3_cleanup_poll(ioat); | 449 | ioat3_cleanup_poll(ioat); |
450 | 450 | ||
451 | return ioat_is_complete(c, cookie, done, used); | 451 | return ioat_tx_status(c, cookie, txstate); |
452 | } | 452 | } |
453 | 453 | ||
454 | static struct dma_async_tx_descriptor * | 454 | static struct dma_async_tx_descriptor * |
@@ -976,7 +976,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) | |||
976 | 976 | ||
977 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); | 977 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); |
978 | 978 | ||
979 | if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 979 | if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
980 | dev_err(dev, "Self-test xor timed out\n"); | 980 | dev_err(dev, "Self-test xor timed out\n"); |
981 | err = -ENODEV; | 981 | err = -ENODEV; |
982 | goto free_resources; | 982 | goto free_resources; |
@@ -1030,7 +1030,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) | |||
1030 | 1030 | ||
1031 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); | 1031 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); |
1032 | 1032 | ||
1033 | if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1033 | if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1034 | dev_err(dev, "Self-test validate timed out\n"); | 1034 | dev_err(dev, "Self-test validate timed out\n"); |
1035 | err = -ENODEV; | 1035 | err = -ENODEV; |
1036 | goto free_resources; | 1036 | goto free_resources; |
@@ -1071,7 +1071,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) | |||
1071 | 1071 | ||
1072 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); | 1072 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); |
1073 | 1073 | ||
1074 | if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1074 | if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1075 | dev_err(dev, "Self-test memset timed out\n"); | 1075 | dev_err(dev, "Self-test memset timed out\n"); |
1076 | err = -ENODEV; | 1076 | err = -ENODEV; |
1077 | goto free_resources; | 1077 | goto free_resources; |
@@ -1114,7 +1114,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) | |||
1114 | 1114 | ||
1115 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); | 1115 | tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); |
1116 | 1116 | ||
1117 | if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1117 | if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1118 | dev_err(dev, "Self-test 2nd validate timed out\n"); | 1118 | dev_err(dev, "Self-test 2nd validate timed out\n"); |
1119 | err = -ENODEV; | 1119 | err = -ENODEV; |
1120 | goto free_resources; | 1120 | goto free_resources; |
@@ -1258,11 +1258,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1258 | 1258 | ||
1259 | 1259 | ||
1260 | if (is_raid_device) { | 1260 | if (is_raid_device) { |
1261 | dma->device_is_tx_complete = ioat3_is_complete; | 1261 | dma->device_tx_status = ioat3_tx_status; |
1262 | device->cleanup_fn = ioat3_cleanup_event; | 1262 | device->cleanup_fn = ioat3_cleanup_event; |
1263 | device->timer_fn = ioat3_timer_event; | 1263 | device->timer_fn = ioat3_timer_event; |
1264 | } else { | 1264 | } else { |
1265 | dma->device_is_tx_complete = ioat_is_dma_complete; | 1265 | dma->device_tx_status = ioat_dma_tx_status; |
1266 | device->cleanup_fn = ioat2_cleanup_event; | 1266 | device->cleanup_fn = ioat2_cleanup_event; |
1267 | device->timer_fn = ioat2_timer_event; | 1267 | device->timer_fn = ioat2_timer_event; |
1268 | } | 1268 | } |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ca6e6a0cb793..ee40dbba1879 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -893,14 +893,14 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan) | |||
893 | } | 893 | } |
894 | 894 | ||
895 | /** | 895 | /** |
896 | * iop_adma_is_complete - poll the status of an ADMA transaction | 896 | * iop_adma_status - poll the status of an ADMA transaction |
897 | * @chan: ADMA channel handle | 897 | * @chan: ADMA channel handle |
898 | * @cookie: ADMA transaction identifier | 898 | * @cookie: ADMA transaction identifier |
899 | * @txstate: a holder for the current state of the channel or NULL | ||
899 | */ | 900 | */ |
900 | static enum dma_status iop_adma_is_complete(struct dma_chan *chan, | 901 | static enum dma_status iop_adma_status(struct dma_chan *chan, |
901 | dma_cookie_t cookie, | 902 | dma_cookie_t cookie, |
902 | dma_cookie_t *done, | 903 | struct dma_tx_state *txstate) |
903 | dma_cookie_t *used) | ||
904 | { | 904 | { |
905 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); | 905 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); |
906 | dma_cookie_t last_used; | 906 | dma_cookie_t last_used; |
@@ -910,10 +910,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, | |||
910 | last_used = chan->cookie; | 910 | last_used = chan->cookie; |
911 | last_complete = iop_chan->completed_cookie; | 911 | last_complete = iop_chan->completed_cookie; |
912 | 912 | ||
913 | if (done) | 913 | if (txstate) { |
914 | *done = last_complete; | 914 | txstate->last = last_complete; |
915 | if (used) | 915 | txstate->used = last_used; |
916 | *used = last_used; | 916 | txstate->residue = 0; |
917 | } | ||
917 | 918 | ||
918 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 919 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
919 | if (ret == DMA_SUCCESS) | 920 | if (ret == DMA_SUCCESS) |
@@ -924,10 +925,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, | |||
924 | last_used = chan->cookie; | 925 | last_used = chan->cookie; |
925 | last_complete = iop_chan->completed_cookie; | 926 | last_complete = iop_chan->completed_cookie; |
926 | 927 | ||
927 | if (done) | 928 | if (txstate) { |
928 | *done = last_complete; | 929 | txstate->last = last_complete; |
929 | if (used) | 930 | txstate->used = last_used; |
930 | *used = last_used; | 931 | txstate->residue = 0; |
932 | } | ||
931 | 933 | ||
932 | return dma_async_is_complete(cookie, last_complete, last_used); | 934 | return dma_async_is_complete(cookie, last_complete, last_used); |
933 | } | 935 | } |
@@ -1042,7 +1044,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) | |||
1042 | iop_adma_issue_pending(dma_chan); | 1044 | iop_adma_issue_pending(dma_chan); |
1043 | msleep(1); | 1045 | msleep(1); |
1044 | 1046 | ||
1045 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 1047 | if (iop_adma_status(dma_chan, cookie, NULL) != |
1046 | DMA_SUCCESS) { | 1048 | DMA_SUCCESS) { |
1047 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1049 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1048 | "Self-test copy timed out, disabling\n"); | 1050 | "Self-test copy timed out, disabling\n"); |
@@ -1142,7 +1144,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) | |||
1142 | iop_adma_issue_pending(dma_chan); | 1144 | iop_adma_issue_pending(dma_chan); |
1143 | msleep(8); | 1145 | msleep(8); |
1144 | 1146 | ||
1145 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 1147 | if (iop_adma_status(dma_chan, cookie, NULL) != |
1146 | DMA_SUCCESS) { | 1148 | DMA_SUCCESS) { |
1147 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1149 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1148 | "Self-test xor timed out, disabling\n"); | 1150 | "Self-test xor timed out, disabling\n"); |
@@ -1189,7 +1191,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) | |||
1189 | iop_adma_issue_pending(dma_chan); | 1191 | iop_adma_issue_pending(dma_chan); |
1190 | msleep(8); | 1192 | msleep(8); |
1191 | 1193 | ||
1192 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1194 | if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1193 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1195 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1194 | "Self-test zero sum timed out, disabling\n"); | 1196 | "Self-test zero sum timed out, disabling\n"); |
1195 | err = -ENODEV; | 1197 | err = -ENODEV; |
@@ -1213,7 +1215,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) | |||
1213 | iop_adma_issue_pending(dma_chan); | 1215 | iop_adma_issue_pending(dma_chan); |
1214 | msleep(8); | 1216 | msleep(8); |
1215 | 1217 | ||
1216 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1218 | if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1217 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1219 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1218 | "Self-test memset timed out, disabling\n"); | 1220 | "Self-test memset timed out, disabling\n"); |
1219 | err = -ENODEV; | 1221 | err = -ENODEV; |
@@ -1245,7 +1247,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) | |||
1245 | iop_adma_issue_pending(dma_chan); | 1247 | iop_adma_issue_pending(dma_chan); |
1246 | msleep(8); | 1248 | msleep(8); |
1247 | 1249 | ||
1248 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1250 | if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { |
1249 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1251 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1250 | "Self-test non-zero sum timed out, disabling\n"); | 1252 | "Self-test non-zero sum timed out, disabling\n"); |
1251 | err = -ENODEV; | 1253 | err = -ENODEV; |
@@ -1340,7 +1342,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) | |||
1340 | iop_adma_issue_pending(dma_chan); | 1342 | iop_adma_issue_pending(dma_chan); |
1341 | msleep(8); | 1343 | msleep(8); |
1342 | 1344 | ||
1343 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 1345 | if (iop_adma_status(dma_chan, cookie, NULL) != |
1344 | DMA_SUCCESS) { | 1346 | DMA_SUCCESS) { |
1345 | dev_err(dev, "Self-test pq timed out, disabling\n"); | 1347 | dev_err(dev, "Self-test pq timed out, disabling\n"); |
1346 | err = -ENODEV; | 1348 | err = -ENODEV; |
@@ -1377,7 +1379,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) | |||
1377 | iop_adma_issue_pending(dma_chan); | 1379 | iop_adma_issue_pending(dma_chan); |
1378 | msleep(8); | 1380 | msleep(8); |
1379 | 1381 | ||
1380 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 1382 | if (iop_adma_status(dma_chan, cookie, NULL) != |
1381 | DMA_SUCCESS) { | 1383 | DMA_SUCCESS) { |
1382 | dev_err(dev, "Self-test pq-zero-sum timed out, disabling\n"); | 1384 | dev_err(dev, "Self-test pq-zero-sum timed out, disabling\n"); |
1383 | err = -ENODEV; | 1385 | err = -ENODEV; |
@@ -1409,7 +1411,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) | |||
1409 | iop_adma_issue_pending(dma_chan); | 1411 | iop_adma_issue_pending(dma_chan); |
1410 | msleep(8); | 1412 | msleep(8); |
1411 | 1413 | ||
1412 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 1414 | if (iop_adma_status(dma_chan, cookie, NULL) != |
1413 | DMA_SUCCESS) { | 1415 | DMA_SUCCESS) { |
1414 | dev_err(dev, "Self-test !pq-zero-sum timed out, disabling\n"); | 1416 | dev_err(dev, "Self-test !pq-zero-sum timed out, disabling\n"); |
1415 | err = -ENODEV; | 1417 | err = -ENODEV; |
@@ -1507,7 +1509,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) | |||
1507 | /* set base routines */ | 1509 | /* set base routines */ |
1508 | dma_dev->device_alloc_chan_resources = iop_adma_alloc_chan_resources; | 1510 | dma_dev->device_alloc_chan_resources = iop_adma_alloc_chan_resources; |
1509 | dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; | 1511 | dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; |
1510 | dma_dev->device_is_tx_complete = iop_adma_is_complete; | 1512 | dma_dev->device_tx_status = iop_adma_status; |
1511 | dma_dev->device_issue_pending = iop_adma_issue_pending; | 1513 | dma_dev->device_issue_pending = iop_adma_issue_pending; |
1512 | dma_dev->dev = &pdev->dev; | 1514 | dma_dev->dev = &pdev->dev; |
1513 | 1515 | ||
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 39e7fb2a90e3..b9cef8b1701c 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c | |||
@@ -1646,15 +1646,16 @@ static void idmac_free_chan_resources(struct dma_chan *chan) | |||
1646 | tasklet_schedule(&to_ipu(idmac)->tasklet); | 1646 | tasklet_schedule(&to_ipu(idmac)->tasklet); |
1647 | } | 1647 | } |
1648 | 1648 | ||
1649 | static enum dma_status idmac_is_tx_complete(struct dma_chan *chan, | 1649 | static enum dma_status idmac_tx_status(struct dma_chan *chan, |
1650 | dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) | 1650 | dma_cookie_t cookie, struct dma_tx_state *txstate) |
1651 | { | 1651 | { |
1652 | struct idmac_channel *ichan = to_idmac_chan(chan); | 1652 | struct idmac_channel *ichan = to_idmac_chan(chan); |
1653 | 1653 | ||
1654 | if (done) | 1654 | if (txstate) { |
1655 | *done = ichan->completed; | 1655 | txstate->last = ichan->completed; |
1656 | if (used) | 1656 | txstate->used = chan->cookie; |
1657 | *used = chan->cookie; | 1657 | txstate->residue = 0; |
1658 | } | ||
1658 | if (cookie != chan->cookie) | 1659 | if (cookie != chan->cookie) |
1659 | return DMA_ERROR; | 1660 | return DMA_ERROR; |
1660 | return DMA_SUCCESS; | 1661 | return DMA_SUCCESS; |
@@ -1673,7 +1674,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) | |||
1673 | dma->dev = ipu->dev; | 1674 | dma->dev = ipu->dev; |
1674 | dma->device_alloc_chan_resources = idmac_alloc_chan_resources; | 1675 | dma->device_alloc_chan_resources = idmac_alloc_chan_resources; |
1675 | dma->device_free_chan_resources = idmac_free_chan_resources; | 1676 | dma->device_free_chan_resources = idmac_free_chan_resources; |
1676 | dma->device_is_tx_complete = idmac_is_tx_complete; | 1677 | dma->device_tx_status = idmac_tx_status; |
1677 | dma->device_issue_pending = idmac_issue_pending; | 1678 | dma->device_issue_pending = idmac_issue_pending; |
1678 | 1679 | ||
1679 | /* Compulsory for DMA_SLAVE fields */ | 1680 | /* Compulsory for DMA_SLAVE fields */ |
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3fdf1f46bd63..cb3a8e94ea48 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c | |||
@@ -540,8 +540,8 @@ static void mpc_dma_issue_pending(struct dma_chan *chan) | |||
540 | 540 | ||
541 | /* Check request completion status */ | 541 | /* Check request completion status */ |
542 | static enum dma_status | 542 | static enum dma_status |
543 | mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, | 543 | mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, |
544 | dma_cookie_t *done, dma_cookie_t *used) | 544 | struct dma_tx_state *txstate) |
545 | { | 545 | { |
546 | struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); | 546 | struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); |
547 | unsigned long flags; | 547 | unsigned long flags; |
@@ -553,11 +553,11 @@ mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, | |||
553 | last_complete = mchan->completed_cookie; | 553 | last_complete = mchan->completed_cookie; |
554 | spin_unlock_irqrestore(&mchan->lock, flags); | 554 | spin_unlock_irqrestore(&mchan->lock, flags); |
555 | 555 | ||
556 | if (done) | 556 | if (txstate) { |
557 | *done = last_complete; | 557 | txstate->last = last_complete; |
558 | 558 | txstate->used = last_used; | |
559 | if (used) | 559 | txstate->residue = 0; |
560 | *used = last_used; | 560 | } |
561 | 561 | ||
562 | return dma_async_is_complete(cookie, last_complete, last_used); | 562 | return dma_async_is_complete(cookie, last_complete, last_used); |
563 | } | 563 | } |
@@ -693,7 +693,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, | |||
693 | dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; | 693 | dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; |
694 | dma->device_free_chan_resources = mpc_dma_free_chan_resources; | 694 | dma->device_free_chan_resources = mpc_dma_free_chan_resources; |
695 | dma->device_issue_pending = mpc_dma_issue_pending; | 695 | dma->device_issue_pending = mpc_dma_issue_pending; |
696 | dma->device_is_tx_complete = mpc_dma_is_tx_complete; | 696 | dma->device_tx_status = mpc_dma_tx_status; |
697 | dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; | 697 | dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; |
698 | 698 | ||
699 | INIT_LIST_HEAD(&dma->channels); | 699 | INIT_LIST_HEAD(&dma->channels); |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10c1ff1..79fb1dea691b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -809,14 +809,14 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) | |||
809 | } | 809 | } |
810 | 810 | ||
811 | /** | 811 | /** |
812 | * mv_xor_is_complete - poll the status of an XOR transaction | 812 | * mv_xor_status - poll the status of an XOR transaction |
813 | * @chan: XOR channel handle | 813 | * @chan: XOR channel handle |
814 | * @cookie: XOR transaction identifier | 814 | * @cookie: XOR transaction identifier |
815 | * @txstate: XOR transactions state holder (or NULL) | ||
815 | */ | 816 | */ |
816 | static enum dma_status mv_xor_is_complete(struct dma_chan *chan, | 817 | static enum dma_status mv_xor_status(struct dma_chan *chan, |
817 | dma_cookie_t cookie, | 818 | dma_cookie_t cookie, |
818 | dma_cookie_t *done, | 819 | struct dma_tx_state *txstate) |
819 | dma_cookie_t *used) | ||
820 | { | 820 | { |
821 | struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); | 821 | struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); |
822 | dma_cookie_t last_used; | 822 | dma_cookie_t last_used; |
@@ -826,10 +826,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, | |||
826 | last_used = chan->cookie; | 826 | last_used = chan->cookie; |
827 | last_complete = mv_chan->completed_cookie; | 827 | last_complete = mv_chan->completed_cookie; |
828 | mv_chan->is_complete_cookie = cookie; | 828 | mv_chan->is_complete_cookie = cookie; |
829 | if (done) | 829 | if (txstate) { |
830 | *done = last_complete; | 830 | txstate->last = last_complete; |
831 | if (used) | 831 | txstate->used = last_used; |
832 | *used = last_used; | 832 | txstate->residue = 0; |
833 | } | ||
833 | 834 | ||
834 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 835 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
835 | if (ret == DMA_SUCCESS) { | 836 | if (ret == DMA_SUCCESS) { |
@@ -841,10 +842,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, | |||
841 | last_used = chan->cookie; | 842 | last_used = chan->cookie; |
842 | last_complete = mv_chan->completed_cookie; | 843 | last_complete = mv_chan->completed_cookie; |
843 | 844 | ||
844 | if (done) | 845 | if (txstate) { |
845 | *done = last_complete; | 846 | txstate->last = last_complete; |
846 | if (used) | 847 | txstate->used = last_used; |
847 | *used = last_used; | 848 | txstate->residue = 0; |
849 | } | ||
848 | 850 | ||
849 | return dma_async_is_complete(cookie, last_complete, last_used); | 851 | return dma_async_is_complete(cookie, last_complete, last_used); |
850 | } | 852 | } |
@@ -974,7 +976,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) | |||
974 | async_tx_ack(tx); | 976 | async_tx_ack(tx); |
975 | msleep(1); | 977 | msleep(1); |
976 | 978 | ||
977 | if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != | 979 | if (mv_xor_status(dma_chan, cookie, NULL) != |
978 | DMA_SUCCESS) { | 980 | DMA_SUCCESS) { |
979 | dev_printk(KERN_ERR, dma_chan->device->dev, | 981 | dev_printk(KERN_ERR, dma_chan->device->dev, |
980 | "Self-test copy timed out, disabling\n"); | 982 | "Self-test copy timed out, disabling\n"); |
@@ -1072,7 +1074,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) | |||
1072 | async_tx_ack(tx); | 1074 | async_tx_ack(tx); |
1073 | msleep(8); | 1075 | msleep(8); |
1074 | 1076 | ||
1075 | if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != | 1077 | if (mv_xor_status(dma_chan, cookie, NULL) != |
1076 | DMA_SUCCESS) { | 1078 | DMA_SUCCESS) { |
1077 | dev_printk(KERN_ERR, dma_chan->device->dev, | 1079 | dev_printk(KERN_ERR, dma_chan->device->dev, |
1078 | "Self-test xor timed out, disabling\n"); | 1080 | "Self-test xor timed out, disabling\n"); |
@@ -1167,7 +1169,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) | |||
1167 | /* set base routines */ | 1169 | /* set base routines */ |
1168 | dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; | 1170 | dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; |
1169 | dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; | 1171 | dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; |
1170 | dma_dev->device_is_tx_complete = mv_xor_is_complete; | 1172 | dma_dev->device_tx_status = mv_xor_status; |
1171 | dma_dev->device_issue_pending = mv_xor_issue_pending; | 1173 | dma_dev->device_issue_pending = mv_xor_issue_pending; |
1172 | dma_dev->dev = &pdev->dev; | 1174 | dma_dev->dev = &pdev->dev; |
1173 | 1175 | ||
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index e69d87f24a25..d9a54c018652 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -3934,12 +3934,13 @@ static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan) | |||
3934 | } | 3934 | } |
3935 | 3935 | ||
3936 | /** | 3936 | /** |
3937 | * ppc440spe_adma_is_complete - poll the status of an ADMA transaction | 3937 | * ppc440spe_adma_tx_status - poll the status of an ADMA transaction |
3938 | * @chan: ADMA channel handle | 3938 | * @chan: ADMA channel handle |
3939 | * @cookie: ADMA transaction identifier | 3939 | * @cookie: ADMA transaction identifier |
3940 | * @txstate: a holder for the current state of the channel | ||
3940 | */ | 3941 | */ |
3941 | static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, | 3942 | static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, |
3942 | dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) | 3943 | dma_cookie_t cookie, struct dma_tx_state *txstate) |
3943 | { | 3944 | { |
3944 | struct ppc440spe_adma_chan *ppc440spe_chan; | 3945 | struct ppc440spe_adma_chan *ppc440spe_chan; |
3945 | dma_cookie_t last_used; | 3946 | dma_cookie_t last_used; |
@@ -3950,10 +3951,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, | |||
3950 | last_used = chan->cookie; | 3951 | last_used = chan->cookie; |
3951 | last_complete = ppc440spe_chan->completed_cookie; | 3952 | last_complete = ppc440spe_chan->completed_cookie; |
3952 | 3953 | ||
3953 | if (done) | 3954 | if (txstate) { |
3954 | *done = last_complete; | 3955 | txstate->last = last_complete; |
3955 | if (used) | 3956 | txstate->used = last_used; |
3956 | *used = last_used; | 3957 | txstate->residue = 0; |
3958 | } | ||
3957 | 3959 | ||
3958 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 3960 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
3959 | if (ret == DMA_SUCCESS) | 3961 | if (ret == DMA_SUCCESS) |
@@ -3964,10 +3966,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, | |||
3964 | last_used = chan->cookie; | 3966 | last_used = chan->cookie; |
3965 | last_complete = ppc440spe_chan->completed_cookie; | 3967 | last_complete = ppc440spe_chan->completed_cookie; |
3966 | 3968 | ||
3967 | if (done) | 3969 | if (txstate) { |
3968 | *done = last_complete; | 3970 | txstate->last = last_complete; |
3969 | if (used) | 3971 | txstate->used = last_used; |
3970 | *used = last_used; | 3972 | txstate->residue = 0; |
3973 | } | ||
3971 | 3974 | ||
3972 | return dma_async_is_complete(cookie, last_complete, last_used); | 3975 | return dma_async_is_complete(cookie, last_complete, last_used); |
3973 | } | 3976 | } |
@@ -4179,7 +4182,7 @@ static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev) | |||
4179 | ppc440spe_adma_alloc_chan_resources; | 4182 | ppc440spe_adma_alloc_chan_resources; |
4180 | adev->common.device_free_chan_resources = | 4183 | adev->common.device_free_chan_resources = |
4181 | ppc440spe_adma_free_chan_resources; | 4184 | ppc440spe_adma_free_chan_resources; |
4182 | adev->common.device_is_tx_complete = ppc440spe_adma_is_complete; | 4185 | adev->common.device_tx_status = ppc440spe_adma_tx_status; |
4183 | adev->common.device_issue_pending = ppc440spe_adma_issue_pending; | 4186 | adev->common.device_issue_pending = ppc440spe_adma_issue_pending; |
4184 | 4187 | ||
4185 | /* Set prep routines based on capability */ | 4188 | /* Set prep routines based on capability */ |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index ce28c1e22825..8aeda9ceb225 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -738,10 +738,9 @@ static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) | |||
738 | sh_chan_xfer_ld_queue(sh_chan); | 738 | sh_chan_xfer_ld_queue(sh_chan); |
739 | } | 739 | } |
740 | 740 | ||
741 | static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, | 741 | static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, |
742 | dma_cookie_t cookie, | 742 | dma_cookie_t cookie, |
743 | dma_cookie_t *done, | 743 | struct dma_tx_state *txstate) |
744 | dma_cookie_t *used) | ||
745 | { | 744 | { |
746 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 745 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
747 | dma_cookie_t last_used; | 746 | dma_cookie_t last_used; |
@@ -754,11 +753,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, | |||
754 | last_complete = sh_chan->completed_cookie; | 753 | last_complete = sh_chan->completed_cookie; |
755 | BUG_ON(last_complete < 0); | 754 | BUG_ON(last_complete < 0); |
756 | 755 | ||
757 | if (done) | 756 | if (txstate) { |
758 | *done = last_complete; | 757 | txstate->last = last_complete; |
759 | 758 | txstate->used = last_used; | |
760 | if (used) | 759 | txstate->residue = 0; |
761 | *used = last_used; | 760 | } |
762 | 761 | ||
763 | spin_lock_bh(&sh_chan->desc_lock); | 762 | spin_lock_bh(&sh_chan->desc_lock); |
764 | 763 | ||
@@ -1030,7 +1029,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1030 | = sh_dmae_alloc_chan_resources; | 1029 | = sh_dmae_alloc_chan_resources; |
1031 | shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; | 1030 | shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; |
1032 | shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; | 1031 | shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; |
1033 | shdev->common.device_is_tx_complete = sh_dmae_is_complete; | 1032 | shdev->common.device_tx_status = sh_dmae_tx_status; |
1034 | shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; | 1033 | shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; |
1035 | 1034 | ||
1036 | /* Compulsory for DMA_SLAVE fields */ | 1035 | /* Compulsory for DMA_SLAVE fields */ |
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 7c06471ef863..8fc28814561a 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c | |||
@@ -511,8 +511,8 @@ static void td_free_chan_resources(struct dma_chan *chan) | |||
511 | } | 511 | } |
512 | } | 512 | } |
513 | 513 | ||
514 | static enum dma_status td_is_tx_complete(struct dma_chan *chan, | 514 | static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, |
515 | dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) | 515 | struct dma_tx_state *txstate) |
516 | { | 516 | { |
517 | struct timb_dma_chan *td_chan = | 517 | struct timb_dma_chan *td_chan = |
518 | container_of(chan, struct timb_dma_chan, chan); | 518 | container_of(chan, struct timb_dma_chan, chan); |
@@ -527,10 +527,11 @@ static enum dma_status td_is_tx_complete(struct dma_chan *chan, | |||
527 | 527 | ||
528 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 528 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
529 | 529 | ||
530 | if (done) | 530 | if (txstate) { |
531 | *done = last_complete; | 531 | txstate->last = last_complete; |
532 | if (used) | 532 | txstate->used = last_used; |
533 | *used = last_used; | 533 | txstate->residue = 0; |
534 | } | ||
534 | 535 | ||
535 | dev_dbg(chan2dev(chan), | 536 | dev_dbg(chan2dev(chan), |
536 | "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", | 537 | "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", |
@@ -742,7 +743,7 @@ static int __devinit td_probe(struct platform_device *pdev) | |||
742 | 743 | ||
743 | td->dma.device_alloc_chan_resources = td_alloc_chan_resources; | 744 | td->dma.device_alloc_chan_resources = td_alloc_chan_resources; |
744 | td->dma.device_free_chan_resources = td_free_chan_resources; | 745 | td->dma.device_free_chan_resources = td_free_chan_resources; |
745 | td->dma.device_is_tx_complete = td_is_tx_complete; | 746 | td->dma.device_tx_status = td_tx_status; |
746 | td->dma.device_issue_pending = td_issue_pending; | 747 | td->dma.device_issue_pending = td_issue_pending; |
747 | 748 | ||
748 | dma_cap_set(DMA_SLAVE, td->dma.cap_mask); | 749 | dma_cap_set(DMA_SLAVE, td->dma.cap_mask); |
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e528e15f44ab..a44e422cbc27 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c | |||
@@ -967,9 +967,8 @@ static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) | |||
967 | } | 967 | } |
968 | 968 | ||
969 | static enum dma_status | 969 | static enum dma_status |
970 | txx9dmac_is_tx_complete(struct dma_chan *chan, | 970 | txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, |
971 | dma_cookie_t cookie, | 971 | struct dma_tx_state *txstate) |
972 | dma_cookie_t *done, dma_cookie_t *used) | ||
973 | { | 972 | { |
974 | struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); | 973 | struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); |
975 | dma_cookie_t last_used; | 974 | dma_cookie_t last_used; |
@@ -991,10 +990,11 @@ txx9dmac_is_tx_complete(struct dma_chan *chan, | |||
991 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 990 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
992 | } | 991 | } |
993 | 992 | ||
994 | if (done) | 993 | if (txstate) { |
995 | *done = last_complete; | 994 | txstate->last = last_complete; |
996 | if (used) | 995 | txstate->used = last_used; |
997 | *used = last_used; | 996 | txstate->residue = 0; |
997 | } | ||
998 | 998 | ||
999 | return ret; | 999 | return ret; |
1000 | } | 1000 | } |
@@ -1160,7 +1160,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) | |||
1160 | dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; | 1160 | dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; |
1161 | dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; | 1161 | dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; |
1162 | dc->dma.device_control = txx9dmac_control; | 1162 | dc->dma.device_control = txx9dmac_control; |
1163 | dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; | 1163 | dc->dma.device_tx_status = txx9dmac_tx_status; |
1164 | dc->dma.device_issue_pending = txx9dmac_issue_pending; | 1164 | dc->dma.device_issue_pending = txx9dmac_issue_pending; |
1165 | if (pdata && pdata->memcpy_chan == ch) { | 1165 | if (pdata && pdata->memcpy_chan == ch) { |
1166 | dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy; | 1166 | dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy; |
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 0731802f876f..55b08e84ac8d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -40,11 +40,13 @@ typedef s32 dma_cookie_t; | |||
40 | * enum dma_status - DMA transaction status | 40 | * enum dma_status - DMA transaction status |
41 | * @DMA_SUCCESS: transaction completed successfully | 41 | * @DMA_SUCCESS: transaction completed successfully |
42 | * @DMA_IN_PROGRESS: transaction not yet processed | 42 | * @DMA_IN_PROGRESS: transaction not yet processed |
43 | * @DMA_PAUSED: transaction is paused | ||
43 | * @DMA_ERROR: transaction failed | 44 | * @DMA_ERROR: transaction failed |
44 | */ | 45 | */ |
45 | enum dma_status { | 46 | enum dma_status { |
46 | DMA_SUCCESS, | 47 | DMA_SUCCESS, |
47 | DMA_IN_PROGRESS, | 48 | DMA_IN_PROGRESS, |
49 | DMA_PAUSED, | ||
48 | DMA_ERROR, | 50 | DMA_ERROR, |
49 | }; | 51 | }; |
50 | 52 | ||
@@ -249,6 +251,21 @@ struct dma_async_tx_descriptor { | |||
249 | }; | 251 | }; |
250 | 252 | ||
251 | /** | 253 | /** |
254 | * struct dma_tx_state - filled in to report the status of | ||
255 | * a transfer. | ||
256 | * @last: last completed DMA cookie | ||
257 | * @used: last issued DMA cookie (i.e. the one in progress) | ||
258 | * @residue: the remaining number of bytes left to transmit | ||
259 | * on the selected transfer for states DMA_IN_PROGRESS and | ||
260 | * DMA_PAUSED if this is implemented in the driver, else 0 | ||
261 | */ | ||
262 | struct dma_tx_state { | ||
263 | dma_cookie_t last; | ||
264 | dma_cookie_t used; | ||
265 | u32 residue; | ||
266 | }; | ||
267 | |||
268 | /** | ||
252 | * struct dma_device - info on the entity supplying DMA services | 269 | * struct dma_device - info on the entity supplying DMA services |
253 | * @chancnt: how many DMA channels are supported | 270 | * @chancnt: how many DMA channels are supported |
254 | * @privatecnt: how many DMA channels are requested by dma_request_channel | 271 | * @privatecnt: how many DMA channels are requested by dma_request_channel |
@@ -276,7 +293,10 @@ struct dma_async_tx_descriptor { | |||
276 | * @device_prep_slave_sg: prepares a slave dma operation | 293 | * @device_prep_slave_sg: prepares a slave dma operation |
277 | * @device_control: manipulate all pending operations on a channel, returns | 294 | * @device_control: manipulate all pending operations on a channel, returns |
278 | * zero or error code | 295 | * zero or error code |
279 | * @device_is_tx_complete: poll for transaction completion | 296 | * @device_tx_status: poll for transaction completion, the optional |
297 | * txstate parameter can be supplied with a pointer to get a | ||
298 | * struct with auxilary transfer status information, otherwise the call | ||
299 | * will just return a simple status code | ||
280 | * @device_issue_pending: push pending transactions to hardware | 300 | * @device_issue_pending: push pending transactions to hardware |
281 | */ | 301 | */ |
282 | struct dma_device { | 302 | struct dma_device { |
@@ -329,9 +349,9 @@ struct dma_device { | |||
329 | unsigned long flags); | 349 | unsigned long flags); |
330 | int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); | 350 | int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); |
331 | 351 | ||
332 | enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, | 352 | enum dma_status (*device_tx_status)(struct dma_chan *chan, |
333 | dma_cookie_t cookie, dma_cookie_t *last, | 353 | dma_cookie_t cookie, |
334 | dma_cookie_t *used); | 354 | struct dma_tx_state *txstate); |
335 | void (*device_issue_pending)(struct dma_chan *chan); | 355 | void (*device_issue_pending)(struct dma_chan *chan); |
336 | }; | 356 | }; |
337 | 357 | ||
@@ -572,7 +592,15 @@ static inline void dma_async_issue_pending(struct dma_chan *chan) | |||
572 | static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, | 592 | static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, |
573 | dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) | 593 | dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) |
574 | { | 594 | { |
575 | return chan->device->device_is_tx_complete(chan, cookie, last, used); | 595 | struct dma_tx_state state; |
596 | enum dma_status status; | ||
597 | |||
598 | status = chan->device->device_tx_status(chan, cookie, &state); | ||
599 | if (last) | ||
600 | *last = state.last; | ||
601 | if (used) | ||
602 | *used = state.used; | ||
603 | return status; | ||
576 | } | 604 | } |
577 | 605 | ||
578 | #define dma_async_memcpy_complete(chan, cookie, last, used)\ | 606 | #define dma_async_memcpy_complete(chan, cookie, last, used)\ |