aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/ipu
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-03-26 19:44:01 -0400
committerDan Williams <dan.j.williams@intel.com>2010-03-26 19:44:01 -0400
commitc3635c78e500a52c9fcd55de381a72928d9e054d (patch)
tree87403f402227cd8b5572550e70facf81c9eaa0d9 /drivers/dma/ipu
parent0f65169b1bf44220308e1ce1f6666ad03ddc27af (diff)
DMAENGINE: generic slave control v2
Convert the device_terminate_all() operation on the DMA engine to a generic device_control() operation which can now optionally support also pausing and resuming DMA on a certain channel. Implemented for the COH 901 318 DMAC as an example. [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>
Diffstat (limited to 'drivers/dma/ipu')
-rw-r--r--drivers/dma/ipu/ipu_idmac.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 2a446397c884..39e7fb2a90e3 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1472,13 +1472,17 @@ static void idmac_issue_pending(struct dma_chan *chan)
1472 */ 1472 */
1473} 1473}
1474 1474
1475static void __idmac_terminate_all(struct dma_chan *chan) 1475static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd)
1476{ 1476{
1477 struct idmac_channel *ichan = to_idmac_chan(chan); 1477 struct idmac_channel *ichan = to_idmac_chan(chan);
1478 struct idmac *idmac = to_idmac(chan->device); 1478 struct idmac *idmac = to_idmac(chan->device);
1479 unsigned long flags; 1479 unsigned long flags;
1480 int i; 1480 int i;
1481 1481
1482 /* Only supports DMA_TERMINATE_ALL */
1483 if (cmd != DMA_TERMINATE_ALL)
1484 return -ENXIO;
1485
1482 ipu_disable_channel(idmac, ichan, 1486 ipu_disable_channel(idmac, ichan,
1483 ichan->status >= IPU_CHANNEL_ENABLED); 1487 ichan->status >= IPU_CHANNEL_ENABLED);
1484 1488
@@ -1505,17 +1509,22 @@ static void __idmac_terminate_all(struct dma_chan *chan)
1505 tasklet_enable(&to_ipu(idmac)->tasklet); 1509 tasklet_enable(&to_ipu(idmac)->tasklet);
1506 1510
1507 ichan->status = IPU_CHANNEL_INITIALIZED; 1511 ichan->status = IPU_CHANNEL_INITIALIZED;
1512
1513 return 0;
1508} 1514}
1509 1515
1510static void idmac_terminate_all(struct dma_chan *chan) 1516static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd)
1511{ 1517{
1512 struct idmac_channel *ichan = to_idmac_chan(chan); 1518 struct idmac_channel *ichan = to_idmac_chan(chan);
1519 int ret;
1513 1520
1514 mutex_lock(&ichan->chan_mutex); 1521 mutex_lock(&ichan->chan_mutex);
1515 1522
1516 __idmac_terminate_all(chan); 1523 ret = __idmac_control(chan, cmd);
1517 1524
1518 mutex_unlock(&ichan->chan_mutex); 1525 mutex_unlock(&ichan->chan_mutex);
1526
1527 return ret;
1519} 1528}
1520 1529
1521#ifdef DEBUG 1530#ifdef DEBUG
@@ -1607,7 +1616,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
1607 1616
1608 mutex_lock(&ichan->chan_mutex); 1617 mutex_lock(&ichan->chan_mutex);
1609 1618
1610 __idmac_terminate_all(chan); 1619 __idmac_control(chan, DMA_TERMINATE_ALL);
1611 1620
1612 if (ichan->status > IPU_CHANNEL_FREE) { 1621 if (ichan->status > IPU_CHANNEL_FREE) {
1613#ifdef DEBUG 1622#ifdef DEBUG
@@ -1669,7 +1678,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
1669 1678
1670 /* Compulsory for DMA_SLAVE fields */ 1679 /* Compulsory for DMA_SLAVE fields */
1671 dma->device_prep_slave_sg = idmac_prep_slave_sg; 1680 dma->device_prep_slave_sg = idmac_prep_slave_sg;
1672 dma->device_terminate_all = idmac_terminate_all; 1681 dma->device_control = idmac_control;
1673 1682
1674 INIT_LIST_HEAD(&dma->channels); 1683 INIT_LIST_HEAD(&dma->channels);
1675 for (i = 0; i < IPU_CHANNELS_NUM; i++) { 1684 for (i = 0; i < IPU_CHANNELS_NUM; i++) {
@@ -1703,7 +1712,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
1703 for (i = 0; i < IPU_CHANNELS_NUM; i++) { 1712 for (i = 0; i < IPU_CHANNELS_NUM; i++) {
1704 struct idmac_channel *ichan = ipu->channel + i; 1713 struct idmac_channel *ichan = ipu->channel + i;
1705 1714
1706 idmac_terminate_all(&ichan->dma_chan); 1715 idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL);
1707 idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); 1716 idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
1708 } 1717 }
1709 1718