]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
dm: core: fdtaddr: Avoid multiple calls to fdt_parent_offset()
authorJonas Karlman <jonas@kwiboo.se>
Sun, 4 Aug 2024 15:05:49 +0000 (15:05 +0000)
committerTom Rini <trini@konsulko.com>
Tue, 27 Aug 2024 20:32:49 +0000 (14:32 -0600)
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 <jonas@kwiboo.se>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/core/fdtaddr.c

index 9e59968df016b83ffc3d5f698f8df6a5fc2a5316..2aa58b006f1a93615c3fd56aaadb3274ddd0dd65 100644 (file)
 
 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