diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2014-11-17 08:42:15 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-12-22 01:58:58 -0500 |
commit | d80f381f321ab739e8a702ecc882560a5838b1fb (patch) | |
tree | b380f91bfb1af6f0fd285b6bacde64f2390a6d38 /drivers/dma/fsl-edma.c | |
parent | 2258b67543eaed7b55afe62c84324a2bc7bd4c33 (diff) |
dmaengine: fsl-edma: Split device_control
Split the device_control callback of the Freescale EDMA driver to make use
of the newly introduced callbacks, that will eventually be used to retrieve
slave capabilities.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/fsl-edma.c')
-rw-r--r-- | drivers/dma/fsl-edma.c | 106 |
1 files changed, 58 insertions, 48 deletions
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index ce6e960b78a7..d96a4aff2f4e 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c | |||
@@ -289,62 +289,69 @@ static void fsl_edma_free_desc(struct virt_dma_desc *vdesc) | |||
289 | kfree(fsl_desc); | 289 | kfree(fsl_desc); |
290 | } | 290 | } |
291 | 291 | ||
292 | static int fsl_edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 292 | static int fsl_edma_terminate_all(struct dma_chan *chan) |
293 | unsigned long arg) | ||
294 | { | 293 | { |
295 | struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); | 294 | struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); |
296 | struct dma_slave_config *cfg = (void *)arg; | ||
297 | unsigned long flags; | 295 | unsigned long flags; |
298 | LIST_HEAD(head); | 296 | LIST_HEAD(head); |
299 | 297 | ||
300 | switch (cmd) { | 298 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); |
301 | case DMA_TERMINATE_ALL: | 299 | fsl_edma_disable_request(fsl_chan); |
302 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); | 300 | fsl_chan->edesc = NULL; |
301 | vchan_get_all_descriptors(&fsl_chan->vchan, &head); | ||
302 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); | ||
303 | vchan_dma_desc_free_list(&fsl_chan->vchan, &head); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int fsl_edma_pause(struct dma_chan *chan) | ||
308 | { | ||
309 | struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); | ||
310 | unsigned long flags; | ||
311 | |||
312 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); | ||
313 | if (fsl_chan->edesc) { | ||
303 | fsl_edma_disable_request(fsl_chan); | 314 | fsl_edma_disable_request(fsl_chan); |
304 | fsl_chan->edesc = NULL; | 315 | fsl_chan->status = DMA_PAUSED; |
305 | vchan_get_all_descriptors(&fsl_chan->vchan, &head); | 316 | } |
306 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); | 317 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); |
307 | vchan_dma_desc_free_list(&fsl_chan->vchan, &head); | 318 | return 0; |
308 | return 0; | 319 | } |
309 | |||
310 | case DMA_SLAVE_CONFIG: | ||
311 | fsl_chan->fsc.dir = cfg->direction; | ||
312 | if (cfg->direction == DMA_DEV_TO_MEM) { | ||
313 | fsl_chan->fsc.dev_addr = cfg->src_addr; | ||
314 | fsl_chan->fsc.addr_width = cfg->src_addr_width; | ||
315 | fsl_chan->fsc.burst = cfg->src_maxburst; | ||
316 | fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width); | ||
317 | } else if (cfg->direction == DMA_MEM_TO_DEV) { | ||
318 | fsl_chan->fsc.dev_addr = cfg->dst_addr; | ||
319 | fsl_chan->fsc.addr_width = cfg->dst_addr_width; | ||
320 | fsl_chan->fsc.burst = cfg->dst_maxburst; | ||
321 | fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width); | ||
322 | } else { | ||
323 | return -EINVAL; | ||
324 | } | ||
325 | return 0; | ||
326 | 320 | ||
327 | case DMA_PAUSE: | 321 | static int fsl_edma_resume(struct dma_chan *chan) |
328 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); | 322 | { |
329 | if (fsl_chan->edesc) { | 323 | struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); |
330 | fsl_edma_disable_request(fsl_chan); | 324 | unsigned long flags; |
331 | fsl_chan->status = DMA_PAUSED; | ||
332 | } | ||
333 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); | ||
334 | return 0; | ||
335 | |||
336 | case DMA_RESUME: | ||
337 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); | ||
338 | if (fsl_chan->edesc) { | ||
339 | fsl_edma_enable_request(fsl_chan); | ||
340 | fsl_chan->status = DMA_IN_PROGRESS; | ||
341 | } | ||
342 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); | ||
343 | return 0; | ||
344 | 325 | ||
345 | default: | 326 | spin_lock_irqsave(&fsl_chan->vchan.lock, flags); |
346 | return -ENXIO; | 327 | if (fsl_chan->edesc) { |
328 | fsl_edma_enable_request(fsl_chan); | ||
329 | fsl_chan->status = DMA_IN_PROGRESS; | ||
347 | } | 330 | } |
331 | spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int fsl_edma_slave_config(struct dma_chan *chan, | ||
336 | struct dma_slave_config *cfg) | ||
337 | { | ||
338 | struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); | ||
339 | |||
340 | fsl_chan->fsc.dir = cfg->direction; | ||
341 | if (cfg->direction == DMA_DEV_TO_MEM) { | ||
342 | fsl_chan->fsc.dev_addr = cfg->src_addr; | ||
343 | fsl_chan->fsc.addr_width = cfg->src_addr_width; | ||
344 | fsl_chan->fsc.burst = cfg->src_maxburst; | ||
345 | fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width); | ||
346 | } else if (cfg->direction == DMA_MEM_TO_DEV) { | ||
347 | fsl_chan->fsc.dev_addr = cfg->dst_addr; | ||
348 | fsl_chan->fsc.addr_width = cfg->dst_addr_width; | ||
349 | fsl_chan->fsc.burst = cfg->dst_maxburst; | ||
350 | fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width); | ||
351 | } else { | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | return 0; | ||
348 | } | 355 | } |
349 | 356 | ||
350 | static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan, | 357 | static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan, |
@@ -917,7 +924,10 @@ static int fsl_edma_probe(struct platform_device *pdev) | |||
917 | fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status; | 924 | fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status; |
918 | fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg; | 925 | fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg; |
919 | fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic; | 926 | fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic; |
920 | fsl_edma->dma_dev.device_control = fsl_edma_control; | 927 | fsl_edma->dma_dev.device_config = fsl_edma_slave_config; |
928 | fsl_edma->dma_dev.device_pause = fsl_edma_pause; | ||
929 | fsl_edma->dma_dev.device_resume = fsl_edma_resume; | ||
930 | fsl_edma->dma_dev.device_terminate_all = fsl_edma_terminate_all; | ||
921 | fsl_edma->dma_dev.device_issue_pending = fsl_edma_issue_pending; | 931 | fsl_edma->dma_dev.device_issue_pending = fsl_edma_issue_pending; |
922 | fsl_edma->dma_dev.device_slave_caps = fsl_dma_device_slave_caps; | 932 | fsl_edma->dma_dev.device_slave_caps = fsl_dma_device_slave_caps; |
923 | 933 | ||