Use Example
The following code block provides a DMA use case.
/* Request a callback function for transmission complete */
static void dma_complete_func(void *arg)
{
struct completion *done = (struct completion *)arg;
complete(done);
}
struct dma_chan *chan;
dma_cap_mask_t mask;
dma_cookie_t cookie;
struct dma_slave_config config;
struct dma_tx_state state;
struct dma_async_tx_descriptor *tx = NULL;
void *src_buf;
dma_addr_t src_dma;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_CYCLIC, mask);
/* Request an available channel */
chan = dma_request_channel(dt->mask, NULL, NULL);
if (!chan){
return -EINVAL;
}
src_buf = kmalloc(1024*4, GFP_KERNEL);
if (!src_buf) {
dma_release_channel(chan);
return -EINVAL;
}
/* Use DMA to visit the mapping address */
src_dma = dma_map_single(NULL, src_buf, 1024*4, DMA_TO_DEVICE);
config.direction = DMA_MEM_TO_DEV;
config.src_addr = src_dma;
config.dst_addr = 0x01c;
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
config.src_maxburst = 1;
config.dst_maxburst = 1;
dmaengine_slave_config(chan, &config);
tx = dmaengine_pre_dma_cyclic(chan, scr_dma, 1024*4, 1024, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
/* Set the callback function for transmission complete */
tx->callback = dma_complete_func;
/* submit and start the transmission */
cookie = dmaengine_submit(tx);
dma_async_issue_pending(chan);
