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 <jonas@kwiboo.se>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Jonas Karlman 2024-08-04 15:05:49 +00:00 committed by Tom Rini
parent 6becf9ba1a
commit d6330529a5

View file

@ -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