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