aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/pl330.c
diff options
context:
space:
mode:
authorBoojin Kim <boojin.kim@samsung.com>2011-09-01 20:44:31 -0400
committerVinod Koul <vinod.koul@intel.com>2011-09-14 01:40:01 -0400
commit1d0c1d606d787e833ee3bd9e1cda640e75c4681a (patch)
tree024e06dd09b6b3bb4fdb2a5cf5af1868ba9caba0 /drivers/dma/pl330.c
parent1b9bb715e7c4c189c4215a11a09e2ccb16598d86 (diff)
DMA: PL330: Support DMA_SLAVE_CONFIG command
Signed-off-by: Boojin Kim <boojin.kim@samsung.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Cc: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r--drivers/dma/pl330.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index d5829c734fad..e7f9d1d3d81a 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -73,6 +73,7 @@ struct dma_pl330_chan {
73 73
74 /* For D-to-M and M-to-D channels */ 74 /* For D-to-M and M-to-D channels */
75 int burst_sz; /* the peripheral fifo width */ 75 int burst_sz; /* the peripheral fifo width */
76 int burst_len; /* the number of burst */
76 dma_addr_t fifo_addr; 77 dma_addr_t fifo_addr;
77}; 78};
78 79
@@ -263,23 +264,47 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned
263 struct dma_pl330_chan *pch = to_pchan(chan); 264 struct dma_pl330_chan *pch = to_pchan(chan);
264 struct dma_pl330_desc *desc; 265 struct dma_pl330_desc *desc;
265 unsigned long flags; 266 unsigned long flags;
267 struct dma_pl330_dmac *pdmac = pch->dmac;
268 struct dma_slave_config *slave_config;
266 269
267 /* Only supports DMA_TERMINATE_ALL */ 270 switch (cmd) {
268 if (cmd != DMA_TERMINATE_ALL) 271 case DMA_TERMINATE_ALL:
269 return -ENXIO; 272 spin_lock_irqsave(&pch->lock, flags);
270 273
271 spin_lock_irqsave(&pch->lock, flags); 274 /* FLUSH the PL330 Channel thread */
275 pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
272 276
273 /* FLUSH the PL330 Channel thread */ 277 /* Mark all desc done */
274 pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH); 278 list_for_each_entry(desc, &pch->work_list, node)
275 279 desc->status = DONE;
276 /* Mark all desc done */
277 list_for_each_entry(desc, &pch->work_list, node)
278 desc->status = DONE;
279 280
280 spin_unlock_irqrestore(&pch->lock, flags); 281 spin_unlock_irqrestore(&pch->lock, flags);
281 282
282 pl330_tasklet((unsigned long) pch); 283 pl330_tasklet((unsigned long) pch);
284 break;
285 case DMA_SLAVE_CONFIG:
286 slave_config = (struct dma_slave_config *)arg;
287
288 if (slave_config->direction == DMA_TO_DEVICE) {
289 if (slave_config->dst_addr)
290 pch->fifo_addr = slave_config->dst_addr;
291 if (slave_config->dst_addr_width)
292 pch->burst_sz = __ffs(slave_config->dst_addr_width);
293 if (slave_config->dst_maxburst)
294 pch->burst_len = slave_config->dst_maxburst;
295 } else if (slave_config->direction == DMA_FROM_DEVICE) {
296 if (slave_config->src_addr)
297 pch->fifo_addr = slave_config->src_addr;
298 if (slave_config->src_addr_width)
299 pch->burst_sz = __ffs(slave_config->src_addr_width);
300 if (slave_config->src_maxburst)
301 pch->burst_len = slave_config->src_maxburst;
302 }
303 break;
304 default:
305 dev_err(pch->dmac->pif.dev, "Not supported command.\n");
306 return -ENXIO;
307 }
283 308
284 return 0; 309 return 0;
285} 310}