diff options
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 8a281584458b..c301a8ec31aa 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
@@ -85,6 +85,8 @@ | |||
85 | #include <linux/slab.h> | 85 | #include <linux/slab.h> |
86 | #include <asm/hardware/pl080.h> | 86 | #include <asm/hardware/pl080.h> |
87 | 87 | ||
88 | #include "dmaengine.h" | ||
89 | |||
88 | #define DRIVER_NAME "pl08xdmac" | 90 | #define DRIVER_NAME "pl08xdmac" |
89 | 91 | ||
90 | static struct amba_driver pl08x_amba_driver; | 92 | static struct amba_driver pl08x_amba_driver; |
@@ -649,7 +651,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, | |||
649 | } | 651 | } |
650 | 652 | ||
651 | if ((bd.srcbus.addr % bd.srcbus.buswidth) || | 653 | if ((bd.srcbus.addr % bd.srcbus.buswidth) || |
652 | (bd.srcbus.addr % bd.srcbus.buswidth)) { | 654 | (bd.dstbus.addr % bd.dstbus.buswidth)) { |
653 | dev_err(&pl08x->adev->dev, | 655 | dev_err(&pl08x->adev->dev, |
654 | "%s src & dst address must be aligned to src" | 656 | "%s src & dst address must be aligned to src" |
655 | " & dst width if peripheral is flow controller", | 657 | " & dst width if peripheral is flow controller", |
@@ -919,13 +921,10 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx) | |||
919 | struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan); | 921 | struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan); |
920 | struct pl08x_txd *txd = to_pl08x_txd(tx); | 922 | struct pl08x_txd *txd = to_pl08x_txd(tx); |
921 | unsigned long flags; | 923 | unsigned long flags; |
924 | dma_cookie_t cookie; | ||
922 | 925 | ||
923 | spin_lock_irqsave(&plchan->lock, flags); | 926 | spin_lock_irqsave(&plchan->lock, flags); |
924 | 927 | cookie = dma_cookie_assign(tx); | |
925 | plchan->chan.cookie += 1; | ||
926 | if (plchan->chan.cookie < 0) | ||
927 | plchan->chan.cookie = 1; | ||
928 | tx->cookie = plchan->chan.cookie; | ||
929 | 928 | ||
930 | /* Put this onto the pending list */ | 929 | /* Put this onto the pending list */ |
931 | list_add_tail(&txd->node, &plchan->pend_list); | 930 | list_add_tail(&txd->node, &plchan->pend_list); |
@@ -945,7 +944,7 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx) | |||
945 | 944 | ||
946 | spin_unlock_irqrestore(&plchan->lock, flags); | 945 | spin_unlock_irqrestore(&plchan->lock, flags); |
947 | 946 | ||
948 | return tx->cookie; | 947 | return cookie; |
949 | } | 948 | } |
950 | 949 | ||
951 | static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt( | 950 | static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt( |
@@ -965,31 +964,17 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan, | |||
965 | dma_cookie_t cookie, struct dma_tx_state *txstate) | 964 | dma_cookie_t cookie, struct dma_tx_state *txstate) |
966 | { | 965 | { |
967 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); | 966 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); |
968 | dma_cookie_t last_used; | ||
969 | dma_cookie_t last_complete; | ||
970 | enum dma_status ret; | 967 | enum dma_status ret; |
971 | u32 bytesleft = 0; | ||
972 | 968 | ||
973 | last_used = plchan->chan.cookie; | 969 | ret = dma_cookie_status(chan, cookie, txstate); |
974 | last_complete = plchan->lc; | 970 | if (ret == DMA_SUCCESS) |
975 | |||
976 | ret = dma_async_is_complete(cookie, last_complete, last_used); | ||
977 | if (ret == DMA_SUCCESS) { | ||
978 | dma_set_tx_state(txstate, last_complete, last_used, 0); | ||
979 | return ret; | 971 | return ret; |
980 | } | ||
981 | 972 | ||
982 | /* | 973 | /* |
983 | * This cookie not complete yet | 974 | * This cookie not complete yet |
975 | * Get number of bytes left in the active transactions and queue | ||
984 | */ | 976 | */ |
985 | last_used = plchan->chan.cookie; | 977 | dma_set_residue(txstate, pl08x_getbytes_chan(plchan)); |
986 | last_complete = plchan->lc; | ||
987 | |||
988 | /* Get number of bytes left in the active transactions and queue */ | ||
989 | bytesleft = pl08x_getbytes_chan(plchan); | ||
990 | |||
991 | dma_set_tx_state(txstate, last_complete, last_used, | ||
992 | bytesleft); | ||
993 | 978 | ||
994 | if (plchan->state == PL08X_CHAN_PAUSED) | 979 | if (plchan->state == PL08X_CHAN_PAUSED) |
995 | return DMA_PAUSED; | 980 | return DMA_PAUSED; |
@@ -1139,6 +1124,8 @@ static int dma_set_runtime_config(struct dma_chan *chan, | |||
1139 | cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT; | 1124 | cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT; |
1140 | cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT; | 1125 | cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT; |
1141 | 1126 | ||
1127 | plchan->device_fc = config->device_fc; | ||
1128 | |||
1142 | if (plchan->runtime_direction == DMA_DEV_TO_MEM) { | 1129 | if (plchan->runtime_direction == DMA_DEV_TO_MEM) { |
1143 | plchan->src_addr = config->src_addr; | 1130 | plchan->src_addr = config->src_addr; |
1144 | plchan->src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR | | 1131 | plchan->src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR | |
@@ -1326,7 +1313,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( | |||
1326 | static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( | 1313 | static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( |
1327 | struct dma_chan *chan, struct scatterlist *sgl, | 1314 | struct dma_chan *chan, struct scatterlist *sgl, |
1328 | unsigned int sg_len, enum dma_transfer_direction direction, | 1315 | unsigned int sg_len, enum dma_transfer_direction direction, |
1329 | unsigned long flags) | 1316 | unsigned long flags, void *context) |
1330 | { | 1317 | { |
1331 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); | 1318 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); |
1332 | struct pl08x_driver_data *pl08x = plchan->host; | 1319 | struct pl08x_driver_data *pl08x = plchan->host; |
@@ -1370,7 +1357,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( | |||
1370 | return NULL; | 1357 | return NULL; |
1371 | } | 1358 | } |
1372 | 1359 | ||
1373 | if (plchan->cd->device_fc) | 1360 | if (plchan->device_fc) |
1374 | tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER : | 1361 | tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER : |
1375 | PL080_FLOW_PER2MEM_PER; | 1362 | PL080_FLOW_PER2MEM_PER; |
1376 | else | 1363 | else |
@@ -1541,7 +1528,7 @@ static void pl08x_tasklet(unsigned long data) | |||
1541 | 1528 | ||
1542 | if (txd) { | 1529 | if (txd) { |
1543 | /* Update last completed */ | 1530 | /* Update last completed */ |
1544 | plchan->lc = txd->tx.cookie; | 1531 | dma_cookie_complete(&txd->tx); |
1545 | } | 1532 | } |
1546 | 1533 | ||
1547 | /* If a new descriptor is queued, set it up plchan->at is NULL here */ | 1534 | /* If a new descriptor is queued, set it up plchan->at is NULL here */ |
@@ -1722,8 +1709,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, | |||
1722 | chan->name); | 1709 | chan->name); |
1723 | 1710 | ||
1724 | chan->chan.device = dmadev; | 1711 | chan->chan.device = dmadev; |
1725 | chan->chan.cookie = 0; | 1712 | dma_cookie_init(&chan->chan); |
1726 | chan->lc = 0; | ||
1727 | 1713 | ||
1728 | spin_lock_init(&chan->lock); | 1714 | spin_lock_init(&chan->lock); |
1729 | INIT_LIST_HEAD(&chan->pend_list); | 1715 | INIT_LIST_HEAD(&chan->pend_list); |