如何使用设备树将两个设备的资源映射到一个 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_global
,debug_info
是指向自定义结构体的指针。
我正在使用 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_global
,debug_info
是指向自定义结构体的指针。