English
Language : 

UM0851 Datasheet, PDF (169/245 Pages) STMicroelectronics – SPEAr is a family of highly customizable ARM-based embedded
UM0851
Accelerator engine device drivers
struct dma_async_tx_descriptor * device_prep_slave_sg( struct dma_chan *chan, struct
scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned
long flags);
/* It can't be called directly, call it using chan pointer */
tx = chan->device->device_prep_slave_sg(chan, sgl, sg_len, direction, flags);
Check the Start transfer section below for for details on starting the actual transfer.
Start transfer
Up until this point, DMA transfer has been prepared, using the previously described
routines, but actual transfer has not yet started (except the framework function call for
memcpy). Assigning a callback and submitting the dma_async_tx_descriptor for actual
transfer can be done as follows:
/*
tx: is struct dma_async_tx_descriptor * returned from transfer prepration functions.
A non negative value of cookie indicates success in starting transfer. On error
cookie is negative. */
static void dma_callback(void *param)
{
/* callback function to be called and transfer completion */
}
tx->callback = dma_callback;
tx->callback_param = param;
cookie = tx->tx_submit(tx);
Transfer completion notification
If callback is not assigned before submitting transfer, then completion of DMA transfer can
be checked by using the following function.
/*
chan: DMA channel
cookie: transaction identifier to check status of
last: returns last completed cookie of channel, can be passed as NULL
used: returns last issued cookie of channel, can be passed as NULL
If transfer is completed then DMA_SUCCESS or DMA_ERROR is returned else
DMA_IN_PROGRESS is returned. */
static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used);
If callback is assigned then callback is called with the parameter given by the user.
On completion of transfer you must update the amount of bytes transferred to the framework
using the following code.
cpu = get_cpu();
per_cpu_ptr(chan->local, cpu)->bytes_transferred += size;
per_cpu_ptr(chan->local, cpu)->memcpy_count++;
put_cpu();
In addition, you should decrement the usage count of channel per CPU using the following
call:
static inline void dma_chan_put(struct dma_chan *chan);
This lets the framework know the amount of data copied by the DMA driver and how many
channels each CPU is using.
Doc ID 16604 Rev 2
169/245