summaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2024-03-11 12:13:03 -0600
committerRob Herring <robh@kernel.org>2024-03-12 09:23:26 -0600
commit54c180e73ffa3e17a8289fa531279eeb2034b69f (patch)
tree0744e910c1b1d810724f5d96a8c6e3fe67da829f /drivers/of/fdt.c
parent893ecc6d2d61381bc56991178cb3de697a948b78 (diff)
downloadlinux-stable-54c180e73ffa3e17a8289fa531279eeb2034b69f.tar.gz
linux-stable-54c180e73ffa3e17a8289fa531279eeb2034b69f.tar.bz2
linux-stable-54c180e73ffa3e17a8289fa531279eeb2034b69f.zip
of: Move all FDT reserved-memory handling into of_reserved_mem.c
The split of /reserved-memory handling between fdt.c and of_reserved_mem.c makes for reading and restructuring the code difficult. As of_reserved_mem.c is only built for CONFIG_OF_EARLY_FLATTREE already, move all the code to one spot. Acked-by: Saravana Kannan <saravanak@google.com> Reviewed-by: Oreoluwa Babatunde <quic_obabatun@quicinc.com> Link: https://lore.kernel.org/r/20240311181303.1516514-2-robh@kernel.org Signed-off-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c123
1 files changed, 1 insertions, 122 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5a385285149..a8a04f27915b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -17,7 +17,6 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
-#include <linux/of_reserved_mem.h>
#include <linux/sizes.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -88,7 +87,7 @@ void __init of_fdt_limit_memory(int limit)
}
}
-static bool of_fdt_device_is_available(const void *blob, unsigned long node)
+bool of_fdt_device_is_available(const void *blob, unsigned long node)
{
const char *status = fdt_getprop(blob, node, "status", NULL);
@@ -484,126 +483,6 @@ void *initial_boot_params __ro_after_init;
static u32 of_fdt_crc32;
-static int __init early_init_dt_reserve_memory(phys_addr_t base,
- phys_addr_t size, bool nomap)
-{
- if (nomap) {
- /*
- * If the memory is already reserved (by another region), we
- * should not allow it to be marked nomap, but don't worry
- * if the region isn't memory as it won't be mapped.
- */
- if (memblock_overlaps_region(&memblock.memory, base, size) &&
- memblock_is_region_reserved(base, size))
- return -EBUSY;
-
- return memblock_mark_nomap(base, size);
- }
- return memblock_reserve(base, size);
-}
-
-/*
- * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
- */
-static int __init __reserved_mem_reserve_reg(unsigned long node,
- const char *uname)
-{
- int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
- phys_addr_t base, size;
- int len;
- const __be32 *prop;
- int first = 1;
- bool nomap;
-
- prop = of_get_flat_dt_prop(node, "reg", &len);
- if (!prop)
- return -ENOENT;
-
- if (len && len % t_len != 0) {
- pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
- uname);
- return -EINVAL;
- }
-
- nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-
- while (len >= t_len) {
- base = dt_mem_next_cell(dt_root_addr_cells, &prop);
- size = dt_mem_next_cell(dt_root_size_cells, &prop);
-
- if (size &&
- early_init_dt_reserve_memory(base, size, nomap) == 0)
- pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
- uname, &base, (unsigned long)(size / SZ_1M));
- else
- pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
- uname, &base, (unsigned long)(size / SZ_1M));
-
- len -= t_len;
- if (first) {
- fdt_reserved_mem_save_node(node, uname, base, size);
- first = 0;
- }
- }
- return 0;
-}
-
-/*
- * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
- * in /reserved-memory matches the values supported by the current implementation,
- * also check if ranges property has been provided
- */
-static int __init __reserved_mem_check_root(unsigned long node)
-{
- const __be32 *prop;
-
- prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
- if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
- return -EINVAL;
-
- prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
- if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
- return -EINVAL;
-
- prop = of_get_flat_dt_prop(node, "ranges", NULL);
- if (!prop)
- return -EINVAL;
- return 0;
-}
-
-/*
- * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
- */
-static int __init fdt_scan_reserved_mem(void)
-{
- int node, child;
- const void *fdt = initial_boot_params;
-
- node = fdt_path_offset(fdt, "/reserved-memory");
- if (node < 0)
- return -ENODEV;
-
- if (__reserved_mem_check_root(node) != 0) {
- pr_err("Reserved memory: unsupported node format, ignoring\n");
- return -EINVAL;
- }
-
- fdt_for_each_subnode(child, fdt, node) {
- const char *uname;
- int err;
-
- if (!of_fdt_device_is_available(fdt, child))
- continue;
-
- uname = fdt_get_name(fdt, child, NULL);
-
- err = __reserved_mem_reserve_reg(child, uname);
- if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
- fdt_reserved_mem_save_node(child, uname, 0, 0);
- }
- return 0;
-}
-
/*
* fdt_reserve_elfcorehdr() - reserves memory for elf core header
*