@@ -558,55 +558,6 @@ static int __init __reserved_mem_check_root(unsigned long node)
return 0;
}
-/*
- * Save the reserved_mem reg nodes in the reserved_mem array
- */
-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;
- phys_addr_t base, size;
- const __be32 *prop;
- int node, child;
- int len;
-
- node = fdt_path_offset(fdt, "/reserved-memory");
- if (node < 0) {
- pr_err("Reserved memory: Did not find reserved-memory node\n");
- return;
- }
-
- if (__reserved_mem_check_root(node) != 0) {
- pr_err("Reserved memory: unsupported node format, ignoring\n");
- return;
- }
-
- fdt_for_each_subnode(child, fdt, node) {
- const char *uname;
-
- prop = of_get_flat_dt_prop(child, "reg", &len);
- if (!prop)
- continue;
-
- if (!of_fdt_device_is_available(fdt, child))
- continue;
-
- uname = fdt_get_name(fdt, child, NULL);
- if (len && len % t_len != 0) {
- pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
- uname);
- continue;
- }
-
- base = dt_mem_next_cell(dt_root_addr_cells, &prop);
- size = dt_mem_next_cell(dt_root_size_cells, &prop);
-
- if (size)
- fdt_reserved_mem_save_node(child, uname, base, size);
- }
-}
-
/*
* fdt_scan_reserved_mem() - scan a single FDT node for reserved memory.
*/
@@ -177,7 +177,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
#endif
void update_reserved_mem_max_cnt(int max_count);
-void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
- phys_addr_t base, phys_addr_t size);
+void fdt_reserved_mem_save_node(struct device_node *node, const char *uname,
+ phys_addr_t base, phys_addr_t size);
#endif /* _LINUX_OF_PRIVATE_H */
@@ -96,11 +96,58 @@ static int alloc_reserved_mem_array(void)
return -1;
}
+/*
+ * Save the reserved_mem reg nodes in the reserved_mem array
+ */
+static void __init dt_scan_reserved_mem_reg_nodes(void)
+{
+ int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
+ struct device_node *node, *child;
+ phys_addr_t base, size;
+ const __be32 *prop;
+ int len;
+
+ node = of_find_node_by_path("/reserved-memory");
+ if (node < 0) {
+ pr_err("Reserved memory: Did not find reserved-memory node\n");
+ return;
+ }
+
+ for_each_child_of_node(node, child) {
+ const char *uname;
+ struct reserved_mem *rmem;
+
+ if (!of_device_is_available(child))
+ continue;
+
+ prop = of_get_property(child, "reg", &len);
+ if (!prop) {
+ rmem = of_reserved_mem_lookup(child);
+ if (rmem)
+ rmem->dev_node = child;
+ continue;
+ }
+
+ uname = of_node_full_name(child);
+ if (len && len % t_len != 0) {
+ pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
+ uname);
+ continue;
+ }
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+ size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+ if (size)
+ fdt_reserved_mem_save_node(child, uname, base, size);
+ }
+}
+
/*
* fdt_reserved_mem_save_node() - save fdt node for second pass initialization
*/
-void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
- phys_addr_t base, phys_addr_t size)
+void __init fdt_reserved_mem_save_node(struct device_node *node, const char *uname,
+ phys_addr_t base, phys_addr_t size)
{
struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
@@ -109,7 +156,7 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
return;
}
- rmem->fdt_node = node;
+ rmem->dev_node = node;
rmem->name = uname;
rmem->base = base;
rmem->size = size;
@@ -252,7 +299,7 @@ int __init __reserved_mem_alloc_size(unsigned long node, const char *uname)
uname, (unsigned long)(size / SZ_1M));
return -ENOMEM;
}
- fdt_reserved_mem_save_node(node, uname, base, size);
+ fdt_reserved_mem_save_node(NULL, uname, base, size);
return 0;
}
@@ -272,7 +319,7 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
reservedmem_of_init_fn initfn = i->data;
const char *compat = i->compatible;
- if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
+ if (!of_device_is_compatible(rmem->dev_node, compat))
continue;
ret = initfn(rmem);
@@ -305,11 +352,6 @@ static int __init __rmem_cmp(const void *a, const void *b)
if (ra->size > rb->size)
return 1;
- if (ra->fdt_node < rb->fdt_node)
- return -1;
- if (ra->fdt_node > rb->fdt_node)
- return 1;
-
return 0;
}
@@ -351,23 +393,23 @@ void __init fdt_init_reserved_mem(void)
if (ret)
pr_err("Failed to allocate memory for reserved_mem array with err: %d", ret);
- fdt_scan_reserved_mem_reg_nodes();
+ dt_scan_reserved_mem_reg_nodes();
/* check for overlapping reserved regions */
__rmem_check_for_overlap();
for (i = 0; i < reserved_mem_count; i++) {
struct reserved_mem *rmem = &reserved_mem[i];
- unsigned long node = rmem->fdt_node;
+ struct device_node *node = rmem->dev_node;
int len;
const __be32 *prop;
int err = 0;
bool nomap;
- nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
- prop = of_get_flat_dt_prop(node, "phandle", &len);
+ nomap = of_get_property(node, "no-map", NULL) != NULL;
+ prop = of_get_property(node, "phandle", &len);
if (!prop)
- prop = of_get_flat_dt_prop(node, "linux,phandle", &len);
+ prop = of_get_property(node, "linux,phandle", &len);
if (prop)
rmem->phandle = of_read_number(prop, len/4);
@@ -383,7 +425,7 @@ void __init fdt_init_reserved_mem(void)
} else {
phys_addr_t end = rmem->base + rmem->size - 1;
bool reusable =
- (of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
+ (of_get_property(node, "reusable", NULL)) != NULL;
pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
&rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
@@ -73,7 +73,6 @@ extern int early_init_dt_scan_root(void);
extern bool early_init_dt_scan(void *params);
extern bool early_init_dt_verify(void *params);
extern void early_init_dt_scan_nodes(void);
-extern void fdt_scan_reserved_mem_reg_nodes(void);
extern const char *of_flat_dt_get_machine_name(void);
extern const void *of_flat_dt_match_machine(const void *default_match,
@@ -10,7 +10,7 @@ struct reserved_mem_ops;
struct reserved_mem {
const char *name;
- unsigned long fdt_node;
+ struct device_node *dev_node;
unsigned long phandle;
const struct reserved_mem_ops *ops;
phys_addr_t base;
@@ -362,9 +362,9 @@ static const struct reserved_mem_ops rmem_dma_ops = {
static int __init rmem_dma_setup(struct reserved_mem *rmem)
{
- unsigned long node = rmem->fdt_node;
+ struct device_node *node = rmem->dev_node;
- if (of_get_flat_dt_prop(node, "reusable", NULL))
+ if (of_get_property(node, "reusable", NULL))
return -EINVAL;
#ifdef CONFIG_ARM
@@ -462,8 +462,8 @@ static const struct reserved_mem_ops rmem_cma_ops = {
static int __init rmem_cma_setup(struct reserved_mem *rmem)
{
- unsigned long node = rmem->fdt_node;
- bool default_cma = of_get_flat_dt_prop(node, "linux,cma-default", NULL);
+ struct device_node *node = rmem->dev_node;
+ bool default_cma = of_get_property(node, "linux,cma-default", NULL);
struct cma *cma;
int err;
@@ -473,8 +473,8 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
return -EBUSY;
}
- if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
- of_get_flat_dt_prop(node, "no-map", NULL))
+ if (!of_get_property(node, "reusable", NULL) ||
+ of_get_property(node, "no-map", NULL))
return -EINVAL;
if (!IS_ALIGNED(rmem->base | rmem->size, CMA_MIN_ALIGNMENT_BYTES)) {
@@ -1732,12 +1732,12 @@ static const struct reserved_mem_ops rmem_swiotlb_ops = {
static int __init rmem_swiotlb_setup(struct reserved_mem *rmem)
{
- unsigned long node = rmem->fdt_node;
+ struct device_node *node = rmem->dev_node;
- if (of_get_flat_dt_prop(node, "reusable", NULL) ||
- of_get_flat_dt_prop(node, "linux,cma-default", NULL) ||
- of_get_flat_dt_prop(node, "linux,dma-default", NULL) ||
- of_get_flat_dt_prop(node, "no-map", NULL))
+ if (of_get_property(node, "reusable", NULL) ||
+ of_get_property(node, "linux,cma-default", NULL) ||
+ of_get_property(node, "linux,dma-default", NULL) ||
+ of_get_property(node, "no-map", NULL))
return -EINVAL;
rmem->ops = &rmem_swiotlb_ops;
The unflattened devicetree APIs are available to be used not long after the processing is done for the reserved memory regions on some architectures, and is available even before that on other architectures. Therefore, use the unflattened devicetree APIs to process and store information for the reserved memory regions. Using the unflattened devicetree APIs is more efficient than using the flattened devicetree APIs. Signed-off-by: Oreoluwa Babatunde <quic_obabatun@quicinc.com> --- drivers/of/fdt.c | 49 ---------------------- drivers/of/of_private.h | 4 +- drivers/of/of_reserved_mem.c | 74 ++++++++++++++++++++++++++------- include/linux/of_fdt.h | 1 - include/linux/of_reserved_mem.h | 2 +- kernel/dma/coherent.c | 4 +- kernel/dma/contiguous.c | 8 ++-- kernel/dma/swiotlb.c | 10 ++--- 8 files changed, 72 insertions(+), 80 deletions(-)