summaryrefslogtreecommitdiffstats
path: root/common/oftree.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/oftree.c')
-rw-r--r--common/oftree.c97
1 files changed, 66 insertions, 31 deletions
diff --git a/common/oftree.c b/common/oftree.c
index 91b3fcc9fa..c12b3cfb16 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -124,14 +124,10 @@ void of_print_cmdline(struct device_node *root)
static int of_fixup_bootargs_bootsource(struct device_node *root,
struct device_node *chosen)
{
- char *alias_name = bootsource_get_alias_name();
struct device_node *bootsource;
int ret = 0;
- if (!alias_name)
- return 0;
-
- bootsource = of_find_node_by_alias(root, alias_name);
+ bootsource = bootsource_of_node_get(root);
/*
* If kernel DTB doesn't have the appropriate alias set up,
* give up and exit early. No error is reported.
@@ -140,7 +136,6 @@ static int of_fixup_bootargs_bootsource(struct device_node *root,
ret = of_set_property(chosen, "bootsource", bootsource->full_name,
strlen(bootsource->full_name) + 1, true);
- free(alias_name);
return ret;
}
@@ -205,7 +200,7 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
struct device_node *node;
int err;
int instance = reset_source_get_instance();
- struct device_d *dev;
+ struct device *dev;
const char *serialno;
const char *compat;
@@ -233,10 +228,10 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
dev = reset_source_get_device();
- if (dev && dev->device_node) {
+ if (dev && dev->of_node) {
phandle phandle;
- phandle = of_node_create_phandle(dev->device_node);
+ phandle = of_node_create_phandle(dev->of_node);
err = of_property_write_u32(node,
"reset-source-device", phandle);
@@ -271,6 +266,49 @@ static int of_register_bootargs_fixup(void)
}
late_initcall(of_register_bootargs_fixup);
+int of_fixup_reserved_memory(struct device_node *root, void *_res)
+{
+ struct resource *res = _res;
+ struct device_node *node, *child;
+ struct property *pp;
+ unsigned addr_n_cells = sizeof(void *) / sizeof(__be32),
+ size_n_cells = sizeof(void *) / sizeof(__be32);
+ unsigned rangelen = 0;
+ __be32 reg[4];
+ int ret;
+
+ node = of_get_child_by_name(root, "reserved-memory") ?: of_new_node(root, "reserved-memory");
+
+ ret = of_property_read_u32(node, "#address-cells", &addr_n_cells);
+ if (ret)
+ of_property_write_u32(node, "#address-cells", addr_n_cells);
+
+ ret = of_property_read_u32(node, "#size-cells", &size_n_cells);
+ if (ret)
+ of_property_write_u32(node, "#size-cells", size_n_cells);
+
+ pp = of_find_property(node, "ranges", &rangelen);
+ if (!pp) {
+ of_new_property(node, "ranges", NULL, 0);
+ } else if (rangelen) {
+ pr_warn("reserved-memory ranges not 1:1 mapped. Aborting fixup\n");
+ return -EINVAL;
+ }
+
+ child = of_get_child_by_name(node, res->name) ?: of_new_node(node, res->name);
+
+ if (res->flags & IORESOURCE_BUSY)
+ of_property_write_bool(child, "no-map", true);
+
+ of_write_number(reg, res->start, addr_n_cells);
+ of_write_number(reg + addr_n_cells, resource_size(res), size_n_cells);
+
+ of_set_property(child, "reg", reg,
+ (addr_n_cells + size_n_cells) * sizeof(*reg), true);
+
+ return 0;
+}
+
struct of_fixup_status_data {
const char *path;
bool status;
@@ -307,13 +345,12 @@ int of_register_set_status_fixup(const char *path, bool status)
return of_register_fixup(of_fixup_status, (void *)data);
}
-struct of_fixup {
- int (*fixup)(struct device_node *, void *);
- void *context;
- struct list_head list;
-};
+LIST_HEAD(of_fixup_list);
-static LIST_HEAD(of_fixup_list);
+static inline bool of_fixup_disabled(struct of_fixup *fixup)
+{
+ return fixup->disabled;
+}
int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context)
{
@@ -350,7 +387,7 @@ int of_unregister_fixup(int (*fixup)(struct device_node *, void *),
* Apply registered fixups for the given fdt. The fdt must have
* enough free space to apply the fixups.
*/
-int of_fix_tree(struct device_node *node)
+void of_fix_tree(struct device_node *node)
{
struct of_fixup *of_fixup;
int ret;
@@ -358,13 +395,14 @@ int of_fix_tree(struct device_node *node)
of_overlay_load_firmware_clear();
list_for_each_entry(of_fixup, &of_fixup_list, list) {
+ if (of_fixup_disabled(of_fixup))
+ continue;
+
ret = of_fixup->fixup(node, of_fixup->context);
if (ret)
pr_warn("Failed to fixup node in %pS: %s\n",
of_fixup->fixup, strerror(-ret));
}
-
- return 0;
}
/*
@@ -373,30 +411,27 @@ int of_fix_tree(struct device_node *node)
* It increases the size of the tree and applies the registered
* fixups.
*/
-struct fdt_header *of_get_fixed_tree(struct device_node *node)
+struct fdt_header *of_get_fixed_tree(const struct device_node *node)
{
- int ret;
struct fdt_header *fdt = NULL;
- struct device_node *freenp = NULL;
+ struct device_node *np;
if (!node) {
node = of_get_root_node();
if (!node)
return NULL;
-
- freenp = node = of_dup(node);
- if (!node)
- return NULL;
}
- ret = of_fix_tree(node);
- if (ret)
- goto out;
+ np = of_dup(node);
+
+ if (!np)
+ return NULL;
+
+ of_fix_tree(np);
- fdt = of_flatten_dtb(node);
+ fdt = of_flatten_dtb(np);
-out:
- of_delete_node(freenp);
+ of_delete_node(np);
return fdt;
}