Skip to content

Commit 54c180e

Browse files
committed
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>
1 parent 893ecc6 commit 54c180e

File tree

3 files changed

+127
-126
lines changed

3 files changed

+127
-126
lines changed

drivers/of/fdt.c

Lines changed: 1 addition & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <linux/mutex.h>
1818
#include <linux/of.h>
1919
#include <linux/of_fdt.h>
20-
#include <linux/of_reserved_mem.h>
2120
#include <linux/sizes.h>
2221
#include <linux/string.h>
2322
#include <linux/errno.h>
@@ -88,7 +87,7 @@ void __init of_fdt_limit_memory(int limit)
8887
}
8988
}
9089

91-
static bool of_fdt_device_is_available(const void *blob, unsigned long node)
90+
bool of_fdt_device_is_available(const void *blob, unsigned long node)
9291
{
9392
const char *status = fdt_getprop(blob, node, "status", NULL);
9493

@@ -484,126 +483,6 @@ void *initial_boot_params __ro_after_init;
484483

485484
static u32 of_fdt_crc32;
486485

487-
static int __init early_init_dt_reserve_memory(phys_addr_t base,
488-
phys_addr_t size, bool nomap)
489-
{
490-
if (nomap) {
491-
/*
492-
* If the memory is already reserved (by another region), we
493-
* should not allow it to be marked nomap, but don't worry
494-
* if the region isn't memory as it won't be mapped.
495-
*/
496-
if (memblock_overlaps_region(&memblock.memory, base, size) &&
497-
memblock_is_region_reserved(base, size))
498-
return -EBUSY;
499-
500-
return memblock_mark_nomap(base, size);
501-
}
502-
return memblock_reserve(base, size);
503-
}
504-
505-
/*
506-
* __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
507-
*/
508-
static int __init __reserved_mem_reserve_reg(unsigned long node,
509-
const char *uname)
510-
{
511-
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
512-
phys_addr_t base, size;
513-
int len;
514-
const __be32 *prop;
515-
int first = 1;
516-
bool nomap;
517-
518-
prop = of_get_flat_dt_prop(node, "reg", &len);
519-
if (!prop)
520-
return -ENOENT;
521-
522-
if (len && len % t_len != 0) {
523-
pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
524-
uname);
525-
return -EINVAL;
526-
}
527-
528-
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
529-
530-
while (len >= t_len) {
531-
base = dt_mem_next_cell(dt_root_addr_cells, &prop);
532-
size = dt_mem_next_cell(dt_root_size_cells, &prop);
533-
534-
if (size &&
535-
early_init_dt_reserve_memory(base, size, nomap) == 0)
536-
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
537-
uname, &base, (unsigned long)(size / SZ_1M));
538-
else
539-
pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
540-
uname, &base, (unsigned long)(size / SZ_1M));
541-
542-
len -= t_len;
543-
if (first) {
544-
fdt_reserved_mem_save_node(node, uname, base, size);
545-
first = 0;
546-
}
547-
}
548-
return 0;
549-
}
550-
551-
/*
552-
* __reserved_mem_check_root() - check if #size-cells, #address-cells provided
553-
* in /reserved-memory matches the values supported by the current implementation,
554-
* also check if ranges property has been provided
555-
*/
556-
static int __init __reserved_mem_check_root(unsigned long node)
557-
{
558-
const __be32 *prop;
559-
560-
prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
561-
if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
562-
return -EINVAL;
563-
564-
prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
565-
if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
566-
return -EINVAL;
567-
568-
prop = of_get_flat_dt_prop(node, "ranges", NULL);
569-
if (!prop)
570-
return -EINVAL;
571-
return 0;
572-
}
573-
574-
/*
575-
* fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
576-
*/
577-
static int __init fdt_scan_reserved_mem(void)
578-
{
579-
int node, child;
580-
const void *fdt = initial_boot_params;
581-
582-
node = fdt_path_offset(fdt, "/reserved-memory");
583-
if (node < 0)
584-
return -ENODEV;
585-
586-
if (__reserved_mem_check_root(node) != 0) {
587-
pr_err("Reserved memory: unsupported node format, ignoring\n");
588-
return -EINVAL;
589-
}
590-
591-
fdt_for_each_subnode(child, fdt, node) {
592-
const char *uname;
593-
int err;
594-
595-
if (!of_fdt_device_is_available(fdt, child))
596-
continue;
597-
598-
uname = fdt_get_name(fdt, child, NULL);
599-
600-
err = __reserved_mem_reserve_reg(child, uname);
601-
if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
602-
fdt_reserved_mem_save_node(child, uname, 0, 0);
603-
}
604-
return 0;
605-
}
606-
607486
/*
608487
* fdt_reserve_elfcorehdr() - reserves memory for elf core header
609488
*

drivers/of/of_private.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,9 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
175175
}
176176
#endif
177177

178+
int fdt_scan_reserved_mem(void);
178179
void fdt_init_reserved_mem(void);
179-
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
180-
phys_addr_t base, phys_addr_t size);
180+
181+
bool of_fdt_device_is_available(const void *blob, unsigned long node);
181182

182183
#endif /* _LINUX_OF_PRIVATE_H */

drivers/of/of_reserved_mem.c

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define pr_fmt(fmt) "OF: reserved mem: " fmt
1313

1414
#include <linux/err.h>
15+
#include <linux/libfdt.h>
1516
#include <linux/of.h>
1617
#include <linux/of_fdt.h>
1718
#include <linux/of_platform.h>
@@ -58,8 +59,8 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
5859
/*
5960
* fdt_reserved_mem_save_node() - save fdt node for second pass initialization
6061
*/
61-
void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
62-
phys_addr_t base, phys_addr_t size)
62+
static void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
63+
phys_addr_t base, phys_addr_t size)
6364
{
6465
struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
6566

@@ -77,6 +78,126 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
7778
return;
7879
}
7980

81+
static int __init early_init_dt_reserve_memory(phys_addr_t base,
82+
phys_addr_t size, bool nomap)
83+
{
84+
if (nomap) {
85+
/*
86+
* If the memory is already reserved (by another region), we
87+
* should not allow it to be marked nomap, but don't worry
88+
* if the region isn't memory as it won't be mapped.
89+
*/
90+
if (memblock_overlaps_region(&memblock.memory, base, size) &&
91+
memblock_is_region_reserved(base, size))
92+
return -EBUSY;
93+
94+
return memblock_mark_nomap(base, size);
95+
}
96+
return memblock_reserve(base, size);
97+
}
98+
99+
/*
100+
* __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
101+
*/
102+
static int __init __reserved_mem_reserve_reg(unsigned long node,
103+
const char *uname)
104+
{
105+
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
106+
phys_addr_t base, size;
107+
int len;
108+
const __be32 *prop;
109+
int first = 1;
110+
bool nomap;
111+
112+
prop = of_get_flat_dt_prop(node, "reg", &len);
113+
if (!prop)
114+
return -ENOENT;
115+
116+
if (len && len % t_len != 0) {
117+
pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
118+
uname);
119+
return -EINVAL;
120+
}
121+
122+
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
123+
124+
while (len >= t_len) {
125+
base = dt_mem_next_cell(dt_root_addr_cells, &prop);
126+
size = dt_mem_next_cell(dt_root_size_cells, &prop);
127+
128+
if (size &&
129+
early_init_dt_reserve_memory(base, size, nomap) == 0)
130+
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
131+
uname, &base, (unsigned long)(size / SZ_1M));
132+
else
133+
pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
134+
uname, &base, (unsigned long)(size / SZ_1M));
135+
136+
len -= t_len;
137+
if (first) {
138+
fdt_reserved_mem_save_node(node, uname, base, size);
139+
first = 0;
140+
}
141+
}
142+
return 0;
143+
}
144+
145+
/*
146+
* __reserved_mem_check_root() - check if #size-cells, #address-cells provided
147+
* in /reserved-memory matches the values supported by the current implementation,
148+
* also check if ranges property has been provided
149+
*/
150+
static int __init __reserved_mem_check_root(unsigned long node)
151+
{
152+
const __be32 *prop;
153+
154+
prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
155+
if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
156+
return -EINVAL;
157+
158+
prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
159+
if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
160+
return -EINVAL;
161+
162+
prop = of_get_flat_dt_prop(node, "ranges", NULL);
163+
if (!prop)
164+
return -EINVAL;
165+
return 0;
166+
}
167+
168+
/*
169+
* fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
170+
*/
171+
int __init fdt_scan_reserved_mem(void)
172+
{
173+
int node, child;
174+
const void *fdt = initial_boot_params;
175+
176+
node = fdt_path_offset(fdt, "/reserved-memory");
177+
if (node < 0)
178+
return -ENODEV;
179+
180+
if (__reserved_mem_check_root(node) != 0) {
181+
pr_err("Reserved memory: unsupported node format, ignoring\n");
182+
return -EINVAL;
183+
}
184+
185+
fdt_for_each_subnode(child, fdt, node) {
186+
const char *uname;
187+
int err;
188+
189+
if (!of_fdt_device_is_available(fdt, child))
190+
continue;
191+
192+
uname = fdt_get_name(fdt, child, NULL);
193+
194+
err = __reserved_mem_reserve_reg(child, uname);
195+
if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
196+
fdt_reserved_mem_save_node(child, uname, 0, 0);
197+
}
198+
return 0;
199+
}
200+
80201
/*
81202
* __reserved_mem_alloc_in_range() - allocate reserved memory described with
82203
* 'alloc-ranges'. Choose bottom-up/top-down depending on nearby existing

0 commit comments

Comments
 (0)