diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-18 19:49:20 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-18 19:49:20 +0300 |
commit | ce1d3fde87d1a21f1ec1147dde32b2825dd3a276 (patch) | |
tree | 6ffab43e47e3a22a76bf9bf4efeecdf1b90dcb6f /drivers/dma/mmp_pdma.c | |
parent | 928fce2f6d8152d897790c1a5bbeef5642f69e0e (diff) | |
parent | 88987d2c7534a0269f567fb101e6d71a08f0f01d (diff) | |
download | linux-ce1d3fde87d1a21f1ec1147dde32b2825dd3a276.tar.xz |
Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul:
"This update brings:
- the big cleanup up by Maxime for device control and slave
capabilities. This makes the API much cleaner.
- new IMG MDC driver by Andrew
- new Renesas R-Car Gen2 DMA Controller driver by Laurent along with
bunch of fixes on rcar drivers
- odd fixes and updates spread over driver"
* 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma: (130 commits)
dmaengine: pl330: add DMA_PAUSE feature
dmaengine: pl330: improve pl330_tx_status() function
dmaengine: rcar-dmac: Disable channel 0 when using IOMMU
dmaengine: rcar-dmac: Work around descriptor mode IOMMU errata
dmaengine: rcar-dmac: Allocate hardware descriptors with DMAC device
dmaengine: rcar-dmac: Fix oops due to unintialized list in error ISR
dmaengine: rcar-dmac: Fix spinlock issues in interrupt
dmaenegine: edma: fix sparse warnings
dmaengine: rcar-dmac: Fix uninitialized variable usage
dmaengine: shdmac: extend PM methods
dmaengine: shdmac: use SET_RUNTIME_PM_OPS()
dmaengine: pl330: fix bug that cause start the same descs in cyclic
dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers
dmaengine: at_xdmac: simplify channel configuration stuff
dmaengine: at_xdmac: introduce save_cc field
dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel
ioat: fail self-test if wait_for_completion times out
dmaengine: dw: define DW_DMA_MAX_NR_MASTERS
dmaengine: dw: amend description of dma_dev field
dmatest: move src_off, dst_off, len inside loop
...
Diffstat (limited to 'drivers/dma/mmp_pdma.c')
-rw-r--r-- | drivers/dma/mmp_pdma.c | 109 |
1 files changed, 56 insertions, 53 deletions
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index 8b8952f35e6c..8926f271904e 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -683,68 +683,70 @@ fail: return NULL; } -static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd, - unsigned long arg) +static int mmp_pdma_config(struct dma_chan *dchan, + struct dma_slave_config *cfg) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); - struct dma_slave_config *cfg = (void *)arg; - unsigned long flags; u32 maxburst = 0, addr = 0; enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED; if (!dchan) return -EINVAL; - switch (cmd) { - case DMA_TERMINATE_ALL: - disable_chan(chan->phy); - mmp_pdma_free_phy(chan); - spin_lock_irqsave(&chan->desc_lock, flags); - mmp_pdma_free_desc_list(chan, &chan->chain_pending); - mmp_pdma_free_desc_list(chan, &chan->chain_running); - spin_unlock_irqrestore(&chan->desc_lock, flags); - chan->idle = true; - break; - case DMA_SLAVE_CONFIG: - if (cfg->direction == DMA_DEV_TO_MEM) { - chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; - maxburst = cfg->src_maxburst; - width = cfg->src_addr_width; - addr = cfg->src_addr; - } else if (cfg->direction == DMA_MEM_TO_DEV) { - chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; - maxburst = cfg->dst_maxburst; - width = cfg->dst_addr_width; - addr = cfg->dst_addr; - } - - if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) - chan->dcmd |= DCMD_WIDTH1; - else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) - chan->dcmd |= DCMD_WIDTH2; - else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES) - chan->dcmd |= DCMD_WIDTH4; - - if (maxburst == 8) - chan->dcmd |= DCMD_BURST8; - else if (maxburst == 16) - chan->dcmd |= DCMD_BURST16; - else if (maxburst == 32) - chan->dcmd |= DCMD_BURST32; - - chan->dir = cfg->direction; - chan->dev_addr = addr; - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (cfg->slave_id) - chan->drcmr = cfg->slave_id; - break; - default: - return -ENOSYS; + if (cfg->direction == DMA_DEV_TO_MEM) { + chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; + maxburst = cfg->src_maxburst; + width = cfg->src_addr_width; + addr = cfg->src_addr; + } else if (cfg->direction == DMA_MEM_TO_DEV) { + chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; + maxburst = cfg->dst_maxburst; + width = cfg->dst_addr_width; + addr = cfg->dst_addr; } + if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) + chan->dcmd |= DCMD_WIDTH1; + else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) + chan->dcmd |= DCMD_WIDTH2; + else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES) + chan->dcmd |= DCMD_WIDTH4; + + if (maxburst == 8) + chan->dcmd |= DCMD_BURST8; + else if (maxburst == 16) + chan->dcmd |= DCMD_BURST16; + else if (maxburst == 32) + chan->dcmd |= DCMD_BURST32; + + chan->dir = cfg->direction; + chan->dev_addr = addr; + /* FIXME: drivers should be ported over to use the filter + * function. Once that's done, the following two lines can + * be removed. + */ + if (cfg->slave_id) + chan->drcmr = cfg->slave_id; + + return 0; +} + +static int mmp_pdma_terminate_all(struct dma_chan *dchan) +{ + struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); + unsigned long flags; + + if (!dchan) + return -EINVAL; + + disable_chan(chan->phy); + mmp_pdma_free_phy(chan); + spin_lock_irqsave(&chan->desc_lock, flags); + mmp_pdma_free_desc_list(chan, &chan->chain_pending); + mmp_pdma_free_desc_list(chan, &chan->chain_running); + spin_unlock_irqrestore(&chan->desc_lock, flags); + chan->idle = true; + return 0; } @@ -1061,7 +1063,8 @@ static int mmp_pdma_probe(struct platform_device *op) pdev->device.device_prep_slave_sg = mmp_pdma_prep_slave_sg; pdev->device.device_prep_dma_cyclic = mmp_pdma_prep_dma_cyclic; pdev->device.device_issue_pending = mmp_pdma_issue_pending; - pdev->device.device_control = mmp_pdma_control; + pdev->device.device_config = mmp_pdma_config; + pdev->device.device_terminate_all = mmp_pdma_terminate_all; pdev->device.copy_align = PDMA_ALIGNMENT; if (pdev->dev->coherent_dma_mask) |