20.9 dma engine驱动
dma engine是一套通用的DMA(直接存储器存取)驱动框架,该框架为使用DMA通道的设备驱动提供了一套统一的API,而且也定义了用具体的DMA控制器实现这一套API的方法。
对于使用DMA引擎的设备驱动而言,发起DMA传输的过程变得整洁了,如在sound子系统的sound/core/pcm_dmaengine.c中,会使用dmaengine进行周期性的DMA传输,相关的代码如清单20.27所
示。
代码清单20.27 dma engine API的使用
static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
struct dma_chan *chan = prtd->dma_chan;
struct dma_async_tx_descriptor *desc;
enum dma_transfer_direction direction;
unsigned long flags = DMA_CTRL_ACK;
direction = snd_pcm_substream_to_dma_direction(substream);
if (!substream->runtime->no_period_wakeup)
flags |= DMA_PREP_INTERRUPT;
prtd->pos = 0;
desc = dmaengine_prep_dma_cyclic(chan,
substream->runtime->dma_addr,
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream), direction, flags);//初始化一个具体的周期性的DMA传输描述符
if (!desc)
return -ENOMEM;
desc->callback = dmaengine_pcm_dma_complete;
desc->callback_param = substream;
prtd->cookie = dmaengine_submit(desc);
return 0;
}
int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(su