重新提交DMA引擎交易

时间:2019-03-06 04:02:27

标签: c linux linux-device-driver dma

我正在为嵌入式SoC编写定制的高速Linux SPI驱动程序。要将数据发送到SPI外设(DMA_MEM_TO_DEV),我是Linux DMA引擎API。

https://www.kernel.org/doc/Documentation/dmaengine/client.txt

根据文档,设置和执行DMA事务的步骤为:

  1. 分配DMA从通道:dma_request_channel
  2. 设置从站和控制器特定的参数:dmaengine_slave_config
  3. 获取交易记录描述符:dmaengine_prep_slave_single
  4. 提交交易:dmaengine_submit
  5. 发出待处理的请求并等待回调通知:dma_async_issue_pending

我可以处理单个DMA事务。但是我需要基于一些硬件流控制(GPIO)从相同大小(dma_addr_t buf)的相同内存位置(size_t len)发送多个DMA事务。

对于初学者,我尝试为每个DMA事务重做步骤1-5。因此,每次流控制GPIO IRQ触发时,我都会重新分配DMA从设备通道,重新设置从设备和控制器特定的参数,...

这似乎也可行,但是我不确定这是否是最有效的方法。

我想知道是否可以再次重新提交交易(dmaengine_submit)并再次发布(dma_async_issue_pending)?这样会更有效吗?

在内核文档的任何地方,我似乎都找不到有关如何重新提交完全相同的DMA请求的任何信息。

2 个答案:

答案 0 :(得分:1)

您至少需要重新初始化内存源地址,目标地址和长度寄存器,因为它们将在DMA事务过程中发生变化。我认为每次重做所有内容都一样快-设置起来不是很多,因此花费的时间很小。

答案 1 :(得分:1)

步骤1和2无需重复。可以对多个事务重复步骤3至5。例如,请参见补丁here dspi_dma_xfer 函数可以多次调用 dspi_next_xfer_dma_submit ,并重做步骤3至5。由于您希望 dma_addr_t buf 相同,据我所知,这就是您想要的。