Reputation: 21
I am writing a Linux kernel driver for a watchdog using the CPU’s internal registers and a dedicated location in (persistent) RAM for storing debug information in case of a watchdog-triggered reset.
In the old world, I had two resources of type IORESOURCE_MEM
in my board file: the internal registers (base address of internal regs plus offset) and the location in RAM (absolute memory address).
I could access these via platform_get_resource()
with the appropriate index, and then I could remap.
In the new world featuring a device tree, my node for the watchdog is located in the domain of internal CPU registers and I can access them without problems.
But how do I add my memory location in RAM? The base address of RAM is different from the CPU-internal registers, so I can’t just add another range to the “reg” entry (like reg = <0x20300 0x408>, <0x3BFFE000 0x1000>;
). Do I need to add a new “device” like this, maybe?
PRAM {
#address-cells = <1>;
#size-cells = <1>;
PRAM0: Watchdog_Crash_Debug_Context {
reg = <0x3BFFE000 0x1000>;
};
};
But how do I reference it in the watchdog device driver? Or in the watchdog device tree entry?
Linux version is 4.1.18.
Upvotes: 1
Views: 1965
Reputation: 21
In the meantime I have found the solution myself. The secret was the magic function of_parse_phandle()
.
Device Tree setup:
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>;
};
};
Usage in code (really simple!):
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);
where pdev->dev.of_node
refers to device tree node watchdog_global
and debug_info
is a pointer to a self-defined struct.
Upvotes: 1