[PATCH v3 7/7] of: reserved_mem: rework fdt_init_reserved_mem_node()

From: Marek Szyprowski

Date: Wed Mar 25 2026 - 05:05:24 EST


Move the content of fdt_reserved_mem_save_node() to
fdt_init_reserved_mem_node() function. Initialization is no longer
performed in two steps as it was initially, so
fdt_reserved_mem_save_node() name is a bit misleading and that function
now performs full initialization of the reserved memory region.

This also fixes the problem of keeping pointers to the regions, which
failed to initialize, what might cause issues when such region is
assigned to the device.

Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
---
drivers/of/of_reserved_mem.c | 62 ++++++++++++++++--------------------
1 file changed, 28 insertions(+), 34 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 037e3d74dde1..8d5777cb5d1b 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -102,36 +102,13 @@ static void __init alloc_reserved_mem_array(void)
reserved_mem = new_array;
}

-static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem,
- unsigned long node);
+static void fdt_init_reserved_mem_node(unsigned long node, const char *uname,
+ phys_addr_t base, phys_addr_t size);
static int fdt_validate_reserved_mem_node(unsigned long node,
phys_addr_t *align);
static int fdt_fixup_reserved_mem_node(unsigned long node,
phys_addr_t base, phys_addr_t size);

-/*
- * fdt_reserved_mem_save_node() - save fdt node for second pass initialization
- */
-static void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
- phys_addr_t base, phys_addr_t size)
-{
- struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
-
- if (reserved_mem_count == total_reserved_mem_cnt) {
- pr_err("not enough space for all defined regions.\n");
- return;
- }
-
- rmem->name = uname;
- rmem->base = base;
- rmem->size = size;
-
- /* Call the region specific initialization function */
- fdt_init_reserved_mem_node(rmem, node);
-
- reserved_mem_count++;
-}
-
static int __init early_init_dt_reserve_memory(phys_addr_t base,
phys_addr_t size, bool nomap)
{
@@ -316,7 +293,7 @@ void __init fdt_scan_reserved_mem_late(void)

if (size) {
uname = fdt_get_name(fdt, child, NULL);
- fdt_reserved_mem_save_node(child, uname, base, size);
+ fdt_init_reserved_mem_node(child, uname, base, size);
}
}

@@ -515,9 +492,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
}

fdt_fixup_reserved_mem_node(node, base, size);
+ fdt_init_reserved_mem_node(node, uname, base, size);

- /* Save region in the reserved_mem array */
- fdt_reserved_mem_save_node(node, uname, base, size);
return 0;
}

@@ -619,30 +595,46 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem,
return ret;
}

-
/**
* fdt_init_reserved_mem_node() - Initialize a reserved memory region
- * @rmem: reserved_mem struct of the memory region to be initialized.
* @node: fdt node of the initialized region
+ * @uname: name of the reserved memory node
+ * @base: base address of the reserved memory region
+ * @size: size of the reserved memory region
*
- * This function is used to call the region specific initialization
- * function for a reserved memory region.
+ * This function calls the region-specific initialization function for a
+ * reserved memory region and saves all region-specific data to the
+ * reserved_mem array to allow of_reserved_mem_lookup() to find it.
*/
-static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem,
- unsigned long node)
+static void __init fdt_init_reserved_mem_node(unsigned long node, const char *uname,
+ phys_addr_t base, phys_addr_t size)
{
int err = 0;
bool nomap;

+ struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
+
+ if (reserved_mem_count == total_reserved_mem_cnt) {
+ pr_err("not enough space for all defined regions.\n");
+ return;
+ }
+
+ rmem->name = uname;
+ rmem->base = base;
+ rmem->size = size;
+
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;

err = __reserved_mem_init_node(rmem, node);
if (err != 0 && err != -ENODEV) {
pr_info("node %s compatible matching fail\n", rmem->name);
+ rmem->name = NULL;
+
if (nomap)
memblock_clear_nomap(rmem->base, rmem->size);
else
memblock_phys_free(rmem->base, rmem->size);
+ return;
} else {
phys_addr_t end = rmem->base + rmem->size - 1;
bool reusable =
@@ -654,6 +646,8 @@ static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem,
reusable ? "reusable" : "non-reusable",
rmem->name ? rmem->name : "unknown");
}
+
+ reserved_mem_count++;
}

struct rmem_assigned_device {
--
2.34.1