From d6330529a57288c4ef37e6c23986015738e87063 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 4 Aug 2024 15:05:49 +0000 Subject: [PATCH] dm: core: fdtaddr: Avoid multiple calls to fdt_parent_offset() Use of fdt_parent_offset() is very expensive as detailed by the function documentation: NOTE: This function is expensive, as it must scan the device tree structure from the start to nodeoffset, *twice*. Re-use the returned value from a single call instead of having to make multiple calls for same nodeoffset. Signed-off-by: Jonas Karlman Reviewed-by: Simon Glass --- drivers/core/fdtaddr.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index 9e59968df0..2aa58b006f 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -19,11 +19,10 @@ DECLARE_GLOBAL_DATA_PTR; -fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) +#if CONFIG_IS_ENABLED(OF_REAL) || CONFIG_IS_ENABLED(OF_CONTROL) +fdt_addr_t devfdt_get_addr_index_parent(const struct udevice *dev, int index, + int offset, int parent) { -#if CONFIG_IS_ENABLED(OF_REAL) - int offset = dev_of_offset(dev); - int parent = fdt_parent_offset(gd->fdt_blob, offset); fdt_addr_t addr; if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { @@ -89,6 +88,15 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) #endif return addr; +} +#endif + +fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) +{ +#if CONFIG_IS_ENABLED(OF_REAL) + int offset = dev_of_offset(dev); + int parent = fdt_parent_offset(gd->fdt_blob, offset); + return devfdt_get_addr_index_parent(dev, index, offset, parent); #else return FDT_ADDR_T_NONE; #endif @@ -113,14 +121,16 @@ fdt_addr_t devfdt_get_addr_size_index(const struct udevice *dev, int index, * next call to the exisiting dev_get_xxx function which handles * all config options. */ - fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev), - "reg", index, size, false); + int offset = dev_of_offset(dev); + int parent = fdt_parent_offset(gd->fdt_blob, offset); + fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent, offset, + "reg", index, size, false); /* * Get the base address via the existing function which handles * all Kconfig cases */ - return devfdt_get_addr_index(dev, index); + return devfdt_get_addr_index_parent(dev, index, offset, parent); #else return FDT_ADDR_T_NONE; #endif -- 2.39.5