From: Alice Guo <[email protected]> Add imx_wdog_alias_to_addr() to get watchdog register base address from device tree aliases. This function is used by mx7ulp, imx8ulp and imx9 SoCs to locate watchdog hardware.
The function supports: - Matching specific alias (e.g., "wdog0") or any "wdog*" if name is NULL. - Optional device tree status check via check_status parameter. Signed-off-by: Alice Guo <[email protected]> --- arch/arm/include/asm/mach-imx/sys_proto.h | 2 ++ arch/arm/mach-imx/Makefile | 4 +-- arch/arm/mach-imx/fdt.c | 51 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 46da7a1eff5..8b88b333b4f 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -10,6 +10,7 @@ #include <asm/io.h> #include <asm/mach-imx/regs-common.h> #include <asm/mach-imx/module_fuse.h> +#include <fdtdec.h> #include <linux/bitops.h> #include "../arch-imx/cpu.h" @@ -327,4 +328,5 @@ enum boot_device get_boot_device(void); int disable_cpu_nodes(void *blob, const char * const *nodes_path, u32 num_disabled_cores, u32 max_cores); int fixup_thermal_trips(void *blob, const char *name); +fdt_addr_t imx_wdog_alias_to_addr(char *name, bool check_status); #endif diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 0f6e737c0b9..b4f316d8c47 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -21,11 +21,9 @@ obj-$(CONFIG_IMX_HAB) += hab.o obj-y += cpu.o endif -ifeq ($(SOC),$(filter $(SOC),imx8m imx9)) -ifneq ($(CONFIG_XPL_BUILD),y) +ifeq ($(SOC),$(filter $(SOC),mx7ulp imx8m imx8ulp imx9)) obj-y += fdt.o endif -endif ifeq ($(SOC),$(filter $(SOC),mx5 mx6)) obj-y += cpu.o speed.o diff --git a/arch/arm/mach-imx/fdt.c b/arch/arm/mach-imx/fdt.c index f19ab9edce4..93016a11acc 100644 --- a/arch/arm/mach-imx/fdt.c +++ b/arch/arm/mach-imx/fdt.c @@ -6,8 +6,11 @@ #include <errno.h> #include <fdtdec.h> #include <malloc.h> +#include <asm/global_data.h> #include <asm/arch/sys_proto.h> +DECLARE_GLOBAL_DATA_PTR; + static void disable_thermal_cpu_nodes(void *blob, u32 num_disabled_cores, u32 max_cores) { static const char * const thermal_path[] = { @@ -127,3 +130,51 @@ int fixup_thermal_trips(void *blob, const char *name) return 0; } + +fdt_addr_t imx_wdog_alias_to_addr(char *name, bool check_status) +{ + const void *fdt = gd->fdt_blob; + int aliases_off, prop_off; + char *wdog_name_to_match; + fdt_addr_t addr; + + if (!fdt || fdt_check_header(fdt)) + return FDT_ADDR_T_NONE; + + aliases_off = fdt_path_offset(fdt, "/aliases"); + if (aliases_off < 0) + return FDT_ADDR_T_NONE; + + wdog_name_to_match = name ? name : "wdog"; + + fdt_for_each_property_offset(prop_off, fdt, aliases_off) { + const char *alias_name; + const char *path; + int len; + int node_off; + + path = fdt_getprop_by_offset(fdt, prop_off, &alias_name, &len); + if (!path || !alias_name) + continue; + + if (strncmp(alias_name, wdog_name_to_match, strlen(wdog_name_to_match)) != 0) + continue; + + node_off = fdt_path_offset(fdt, path); + if (node_off < 0) + continue; + + if (check_status) { + if (!fdtdec_get_is_enabled(fdt, node_off)) + continue; + } + + addr = fdtdec_get_addr_size_auto_noparent(fdt, node_off, "reg", 0, NULL, true); + if (addr == FDT_ADDR_T_NONE) + continue; + + return addr; + } + + return FDT_ADDR_T_NONE; +} -- 2.43.0

