【问题描述】
  将之前可以在 Kernel 3.14 上正常运行的驱动代码移植到 Kernel 4.9 上,发现驱动在进行 probe 时失败,具体失败位置为函数 dma_alloc_coherent(),对应代码段如下:

amaudio_start_addr =
            (unsigned char *)dma_alloc_coherent(amaudio2_dev,
            SOFT_BUFFER_SIZE,
            &amaudio_phy_start_addr,
            GFP_KERNEL);

if (!amaudio_start_addr) {
    pr_info("amaudio2 out soft DMA buffer alloc failed, size %lu\n", SOFT_BUFFER_SIZE);
    ret = -ENOMEM;
    goto err4;
}

【原因及解决】
  造成这一问题的原因在于,基于 Kernel 4.9 的设备驱动在进行 DMA 操作前必须要先对相关的数据结构进行初始化,否则只能分配得到 NULL 指针。
  所以我们只需要在上方所示开辟 DMA 内存的代码前使用 of_dma_configure() 函数先对相关结构初始化一下就好了。如下:

/* dma data structure shall be initialised before being used in Kernel 4.9 */
of_dma_configure(amaudio2_dev, amaudio2_dev->of_node);

if (!amaudio2_dev->dma_mask)
    amaudio2_dev->dma_mask = &amaudio_pcm_dmamask;
if (!amaudio2_dev->coherent_dma_mask)
    amaudio2_dev->coherent_dma_mask = 0xffffffff;

amaudio_start_addr =
            (unsigned char *)dma_alloc_coherent(amaudio2_dev,
            SOFT_BUFFER_SIZE,
            &amaudio_phy_start_addr,
            GFP_KERNEL);

if (!amaudio_start_addr) {
    pr_info("amaudio2 out soft DMA buffer alloc failed, size %lu\n", SOFT_BUFFER_SIZE);
    ret = -ENOMEM;
    goto err4;
}

  重新编译 boot.img 烧入设备进行验证,发现驱动可以正常 probe 了。

更多推荐

Kernel 4.9 上 dma_alloc_coherent() 函数开辟 DMA 连续内存空间失败 解决办法