aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r--drivers/dma/amba-pl08x.c46
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
90static struct amba_driver pl08x_amba_driver; 92static 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
951static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt( 950static 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(
1326static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( 1313static 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);