diff options
Diffstat (limited to 'common/oftree.c')
-rw-r--r-- | common/oftree.c | 97 |
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; } |