[PATCH 4/4] of: reserved_mem: Restructure code to call rmem init functions earlier

From: Oreoluwa Babatunde
Date: Mon Jul 08 2024 - 19:07:39 EST


This reapplies the fix from commit f2a524d9ef5b ("of: reserved_mem:
Restructure code to call reserved mem init functions earlier") which now
uses the fdt APIs instead of the unflatten_devicetree APIs.

Signed-off-by: Oreoluwa Babatunde <quic_obabatun@xxxxxxxxxxx>
---
drivers/of/fdt.c | 2 +-
drivers/of/of_private.h | 2 +-
drivers/of/of_reserved_mem.c | 79 ++++++++++++++++++++----------------
3 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e0f93886cc17..b5b1c9c8ed0a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1239,7 +1239,7 @@ void __init unflatten_device_tree(void)
unittest_unflatten_overlay_base();

/* initialize the reserved memory regions */
- fdt_init_reserved_mem();
+ fdt_scan_reserved_mem_reg_nodes();
}

/**
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 32b10d45b558..7ee11623612e 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -181,7 +181,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
#endif

int fdt_scan_reserved_mem(void);
-void fdt_init_reserved_mem(void);
+void fdt_scan_reserved_mem_reg_nodes(void);

bool of_fdt_device_is_available(const void *blob, unsigned long node);

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 113d593ea031..3fa06670f751 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -96,6 +96,7 @@ static void __init alloc_reserved_mem_array(void)
reserved_mem = new_array;
}

+static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem);
/*
* fdt_reserved_mem_save_node() - save fdt node for second pass initialization
*/
@@ -114,6 +115,7 @@ static void __init fdt_reserved_mem_save_node(unsigned long node, const char *un
rmem->base = base;
rmem->size = size;

+ fdt_init_reserved_mem_node(rmem);
reserved_mem_count++;
return;
}
@@ -200,6 +202,7 @@ static int __init __reserved_mem_check_root(unsigned long node)
return 0;
}

+static void __init __rmem_check_for_overlap(void);
/**
* fdt_scan_reserved_mem_reg_nodes() - Store info for the "reg" defined
* reserved memory regions.
@@ -210,7 +213,7 @@ static int __init __reserved_mem_check_root(unsigned long node)
* size are all stored in the reserved_mem array by calling the
* fdt_reserved_mem_save_node() function.
*/
-static void __init fdt_scan_reserved_mem_reg_nodes(void)
+void __init fdt_scan_reserved_mem_reg_nodes(void)
{
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
const void *fdt = initial_boot_params;
@@ -230,6 +233,13 @@ static void __init fdt_scan_reserved_mem_reg_nodes(void)
return;
}

+ /*
+ * Allocate the exact size needed for the reserved_mem array and
+ * copy all the contents from the previous array if allocation
+ * is successful.
+ */
+ alloc_reserved_mem_array();
+
fdt_for_each_subnode(child, fdt, node) {
const char *uname;

@@ -251,6 +261,9 @@ static void __init fdt_scan_reserved_mem_reg_nodes(void)
if (size)
fdt_reserved_mem_save_node(child, uname, base, size);
}
+
+ /* check for overlapping reserved regions */
+ __rmem_check_for_overlap();
}

static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname);
@@ -536,45 +549,39 @@ static void __init __rmem_check_for_overlap(void)
}

/**
- * fdt_init_reserved_mem() - allocate and init all saved reserved memory regions
+ * fdt_init_reserved_mem_node() - allocate and init an rmem memory region
+ * @rmem: reserved_mem object of the memory region to be initialized.
+ *
+ * This function is used to call the region specific initialization
+ * function on the rmem object passed as an argument. The rmem object
+ * will contain the base address, size, node name, and device_node of
+ * the reserved memory region to be initialized.
*/
-void __init fdt_init_reserved_mem(void)
+static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem)
{
- int i;
-
- alloc_reserved_mem_array();
-
- fdt_scan_reserved_mem_reg_nodes();
+ unsigned long node = rmem->fdt_node;
+ int err = 0;
+ bool nomap;

- /* check for overlapping reserved regions */
- __rmem_check_for_overlap();
+ nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;

- for (i = 0; i < reserved_mem_count; i++) {
- struct reserved_mem *rmem = &reserved_mem[i];
- unsigned long node = rmem->fdt_node;
- int err = 0;
- bool nomap;
-
- nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-
- err = __reserved_mem_init_node(rmem);
- if (err != 0 && err != -ENOENT) {
- pr_info("node %s compatible matching fail\n", rmem->name);
- if (nomap)
- memblock_clear_nomap(rmem->base, rmem->size);
- else
- memblock_phys_free(rmem->base, rmem->size);
- } else {
- phys_addr_t end = rmem->base + rmem->size - 1;
- bool reusable =
- (of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
-
- pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
- &rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
- nomap ? "nomap" : "map",
- reusable ? "reusable" : "non-reusable",
- rmem->name ? rmem->name : "unknown");
- }
+ err = __reserved_mem_init_node(rmem);
+ if (err != 0 && err != -ENOENT) {
+ pr_info("node %s compatible matching fail\n", rmem->name);
+ if (nomap)
+ memblock_clear_nomap(rmem->base, rmem->size);
+ else
+ memblock_phys_free(rmem->base, rmem->size);
+ } else {
+ phys_addr_t end = rmem->base + rmem->size - 1;
+ bool reusable =
+ (of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
+
+ pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
+ &rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
+ nomap ? "nomap" : "map",
+ reusable ? "reusable" : "non-reusable",
+ rmem->name ? rmem->name : "unknown");
}
}

--
2.34.1