如何使用设备树将两个设备的资源映射到一个 Linux 内核驱动程序中?

How to map resources of two devices in one Linux kernel driver using device tree?

我正在使用 CPU 的内部寄存器 (持久)RAM 中的专用位置为看门狗编写 Linux 内核驱动程序在看门狗触发复位的情况下存储调试信息。

在旧世界中,我的电路板文件中有两个类型为 IORESOURCE_MEM 的资源:内部寄存器(内部寄存器的基地址加上偏移量)和 RAM 中的位置(绝对内存地址)。

我可以使用适当的索引通过 platform_get_resource() 访问这些,然后我可以重新映射。

在具有设备树的新世界中,我的看门狗节点位于内部 CPU 寄存器域中,我可以毫无问题地访问它们。

但是如何在 RAM 中添加内存位置? RAM 的基地址与 CPU 内部寄存器不同,所以我不能向“reg”条目添加另一个范围(如 reg = <0x20300 0x408>, <0x3BFFE000 0x1000>;)。我是否需要像这样添加一个新的“设备”?

PRAM {
    #address-cells = <1>;
    #size-cells = <1>;       
    PRAM0: Watchdog_Crash_Debug_Context {            
        reg = <0x3BFFE000 0x1000>;
    };
};

但是我如何在看门狗设备驱动程序中引用它呢?或者在看门狗设备树条目中?

Linux 版本为 4.1.18.

同时我自己找到了解决方案。秘诀就是魔法函数 of_parse_phandle().

设备树设置:

soc {
    ...
    internal-regs {
        ...
        watchdog_global {
            ...
            PRAM_address = <&PRAM0>;
        };
    };
};


PRAM {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0 0 0x3b000000 0x5000000>;

    PRAM0: Watchdog_Crash_Debug_Context {            
        reg = <0xFFE000 0x1000>;
    };
};

代码中的用法(真的很简单!):

struct device_node *PRAM_node = of_parse_phandle(pdev->dev.of_node, "PRAM_address", 0);
debug_info = of_iomap(PRAM_node, 0);
of_node_put(PRAM_node);

其中pdev->dev.of_node指的是设备树节点watchdog_globaldebug_info是指向自定义结构体的指针。