diff options
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r-- | drivers/dma/pl330.c | 134 |
1 files changed, 55 insertions, 79 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index bdf40b530032..027f1d7ea4fc 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2086,78 +2086,63 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) return 1; } -static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg) +static int pl330_config(struct dma_chan *chan, + struct dma_slave_config *slave_config) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + + if (slave_config->direction == DMA_MEM_TO_DEV) { + if (slave_config->dst_addr) + pch->fifo_addr = slave_config->dst_addr; + if (slave_config->dst_addr_width) + pch->burst_sz = __ffs(slave_config->dst_addr_width); + if (slave_config->dst_maxburst) + pch->burst_len = slave_config->dst_maxburst; + } else if (slave_config->direction == DMA_DEV_TO_MEM) { + if (slave_config->src_addr) + pch->fifo_addr = slave_config->src_addr; + if (slave_config->src_addr_width) + pch->burst_sz = __ffs(slave_config->src_addr_width); + if (slave_config->src_maxburst) + pch->burst_len = slave_config->src_maxburst; + } + + return 0; +} + +static int pl330_terminate_all(struct dma_chan *chan) { struct dma_pl330_chan *pch = to_pchan(chan); struct dma_pl330_desc *desc; unsigned long flags; struct pl330_dmac *pl330 = pch->dmac; - struct dma_slave_config *slave_config; LIST_HEAD(list); - switch (cmd) { - case DMA_TERMINATE_ALL: - pm_runtime_get_sync(pl330->ddma.dev); - spin_lock_irqsave(&pch->lock, flags); - - spin_lock(&pl330->lock); - _stop(pch->thread); - spin_unlock(&pl330->lock); - - pch->thread->req[0].desc = NULL; - pch->thread->req[1].desc = NULL; - pch->thread->req_running = -1; - - /* Mark all desc done */ - list_for_each_entry(desc, &pch->submitted_list, node) { - desc->status = FREE; - dma_cookie_complete(&desc->txd); - } - - list_for_each_entry(desc, &pch->work_list , node) { - desc->status = FREE; - dma_cookie_complete(&desc->txd); - } - - list_for_each_entry(desc, &pch->completed_list , node) { - desc->status = FREE; - dma_cookie_complete(&desc->txd); - } - - if (!list_empty(&pch->work_list)) - pm_runtime_put(pl330->ddma.dev); + spin_lock_irqsave(&pch->lock, flags); + spin_lock(&pl330->lock); + _stop(pch->thread); + spin_unlock(&pl330->lock); + + pch->thread->req[0].desc = NULL; + pch->thread->req[1].desc = NULL; + pch->thread->req_running = -1; + + /* Mark all desc done */ + list_for_each_entry(desc, &pch->submitted_list, node) { + desc->status = FREE; + dma_cookie_complete(&desc->txd); + } - list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool); - list_splice_tail_init(&pch->work_list, &pl330->desc_pool); - list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); - spin_unlock_irqrestore(&pch->lock, flags); - pm_runtime_mark_last_busy(pl330->ddma.dev); - pm_runtime_put_autosuspend(pl330->ddma.dev); - break; - case DMA_SLAVE_CONFIG: - slave_config = (struct dma_slave_config *)arg; - - if (slave_config->direction == DMA_MEM_TO_DEV) { - if (slave_config->dst_addr) - pch->fifo_addr = slave_config->dst_addr; - if (slave_config->dst_addr_width) - pch->burst_sz = __ffs(slave_config->dst_addr_width); - if (slave_config->dst_maxburst) - pch->burst_len = slave_config->dst_maxburst; - } else if (slave_config->direction == DMA_DEV_TO_MEM) { - if (slave_config->src_addr) - pch->fifo_addr = slave_config->src_addr; - if (slave_config->src_addr_width) - pch->burst_sz = __ffs(slave_config->src_addr_width); - if (slave_config->src_maxburst) - pch->burst_len = slave_config->src_maxburst; - } - break; - default: - dev_err(pch->dmac->ddma.dev, "Not supported command.\n"); - return -ENXIO; + list_for_each_entry(desc, &pch->work_list , node) { + desc->status = FREE; + dma_cookie_complete(&desc->txd); } + list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool); + list_splice_tail_init(&pch->work_list, &pl330->desc_pool); + list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); + spin_unlock_irqrestore(&pch->lock, flags); + return 0; } @@ -2623,19 +2608,6 @@ static irqreturn_t pl330_irq_handler(int irq, void *data) BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) -static int pl330_dma_device_slave_caps(struct dma_chan *dchan, - struct dma_slave_caps *caps) -{ - caps->src_addr_widths = PL330_DMA_BUSWIDTHS; - caps->dstn_addr_widths = PL330_DMA_BUSWIDTHS; - caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); - caps->cmd_pause = false; - caps->cmd_terminate = true; - caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; - - return 0; -} - /* * Runtime PM callbacks are provided by amba/bus.c driver. * @@ -2793,9 +2765,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic; pd->device_tx_status = pl330_tx_status; pd->device_prep_slave_sg = pl330_prep_slave_sg; - pd->device_control = pl330_control; + pd->device_config = pl330_config; + pd->device_terminate_all = pl330_terminate_all; pd->device_issue_pending = pl330_issue_pending; - pd->device_slave_caps = pl330_dma_device_slave_caps; + pd->src_addr_widths = PL330_DMA_BUSWIDTHS; + pd->dst_addr_widths = PL330_DMA_BUSWIDTHS; + pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + pd->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; ret = dma_async_device_register(pd); if (ret) { @@ -2847,7 +2823,7 @@ probe_err3: /* Flush the channel */ if (pch->thread) { - pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); + pl330_terminate_all(&pch->chan); pl330_free_chan_resources(&pch->chan); } } @@ -2878,7 +2854,7 @@ static int pl330_remove(struct amba_device *adev) /* Flush the channel */ if (pch->thread) { - pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); + pl330_terminate_all(&pch->chan); pl330_free_chan_resources(&pch->chan); } } |