Analogous to the of_property command, add an -f option to the of_node command. This option defers the device tree modification until boot time and thus applies the modification as a fixup on the linux device tree. Signed-off-by: Florian Bäuerle <florian.baeuerle@xxxxxxxxxxxx> --- commands/of_node.c | 106 ++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 31 deletions(-) diff --git a/commands/of_node.c b/commands/of_node.c index 4962e5242..29cc371dd 100644 --- a/commands/of_node.c +++ b/commands/of_node.c @@ -32,16 +32,66 @@ #include <init.h> #include <libgen.h> +static int do_of_node_create_now(struct device_node *root, const char *path); +static int do_of_node_delete_now(struct device_node *root, const char *path); + +static int of_fixup_node_create(struct device_node *root, void *context) +{ + return do_of_node_create_now(root, (const char *)context); +} + +static int of_fixup_node_delete(struct device_node *root, void *context) +{ + return do_of_node_delete_now(root, (const char *)context); +} + +static int do_of_node_create_fixup(const char *path) +{ + char *data = xstrdup(path); + + return of_register_fixup(of_fixup_node_create, (void *)data); +} + +static int do_of_node_delete_fixup(const char *path) +{ + char *data = xstrdup(path); + + return of_register_fixup(of_fixup_node_delete, (void *)data); +} + +static int do_of_node_create_now(struct device_node *root, const char *path) +{ + struct device_node *node = of_create_node(root, path); + + if (!node) + return -EINVAL; + + return 0; +} + +static int do_of_node_delete_now(struct device_node *root, const char *path) +{ + struct device_node *node = of_find_node_by_path(path); + + if (!node) { + printf("Cannot find nodepath %s\n", path); + return -ENOENT; + } + + of_delete_node(node); + + return 0; +} + static int do_of_node(int argc, char *argv[]) { int opt; int delete = 0; int create = 0; + int fixup = 0; char *path = NULL; - struct device_node *node = NULL; - struct device_node *root; - while ((opt = getopt(argc, argv, "cd")) > 0) { + while ((opt = getopt(argc, argv, "cdf")) > 0) { switch (opt) { case 'c': create = 1; @@ -49,6 +99,9 @@ static int do_of_node(int argc, char *argv[]) case 'd': delete = 1; break; + case 'f': + fixup = 1; + break; default: return COMMAND_ERROR_USAGE; } @@ -57,53 +110,44 @@ static int do_of_node(int argc, char *argv[]) if (optind == argc) return COMMAND_ERROR_USAGE; - if (optind < argc) { + if (optind < argc) path = argv[optind]; - } - root = of_get_root_node(); - if (!root) { - printf("root node not set\n"); - return -ENOENT; - } - - if (create) { - if (!path) - return COMMAND_ERROR_USAGE; - - node = of_create_node(root, path); - if (!node) - return -EINVAL; - - return 0; - } - - if (delete) { - if (!path) - return COMMAND_ERROR_USAGE; + if (!path) + return COMMAND_ERROR_USAGE; - node = of_find_node_by_path(path); - if (!node) { - printf("Cannot find nodepath %s\n", path); + if (fixup) { + if (create) + return do_of_node_create_fixup(path); + if (delete) + return do_of_node_delete_fixup(path); + } else { + struct device_node *root = of_get_root_node(); + if (!root) { + printf("root node not set\n"); return -ENOENT; } - of_delete_node(node); + if (create) + return do_of_node_create_now(root, path); + if (delete) + return do_of_node_delete_now(root, path); } - return 0; + return COMMAND_ERROR_USAGE; } BAREBOX_CMD_HELP_START(of_node) BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_OPT ("-c", "create a new node") BAREBOX_CMD_HELP_OPT ("-d", "delete a node") +BAREBOX_CMD_HELP_OPT ("-f", "create/delete as a fixup (defer the action until booting)") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(of_node) .cmd = do_of_node, BAREBOX_CMD_DESC("create/delete nodes in the device tree") - BAREBOX_CMD_OPTS("[-cd] NODE NAME") + BAREBOX_CMD_OPTS("[-cd] [-f] NODE NAME") BAREBOX_CMD_GROUP(CMD_GRP_MISC) BAREBOX_CMD_COMPLETE(devicetree_complete) BAREBOX_CMD_HELP(cmd_of_node_help) _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox