diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2023-06-22 09:59:27 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2023-06-22 09:59:27 +0200 |
commit | 9be6eb40e5e55560d07a5056d978880ae879329d (patch) | |
tree | 98777637dd1e4d9be327cf70d4014793fe85e8fe /commands | |
parent | f946c859fe5e25b7538742fbc8542921b095cffa (diff) | |
parent | ecd7854b9c661571137802bfc831c9fb07cbe820 (diff) | |
download | barebox-9be6eb40e5e55560d07a5056d978880ae879329d.tar.gz barebox-9be6eb40e5e55560d07a5056d978880ae879329d.tar.xz |
Merge branch 'for-next/of-compat'
Diffstat (limited to 'commands')
-rw-r--r-- | commands/Kconfig | 15 | ||||
-rw-r--r-- | commands/Makefile | 1 | ||||
-rw-r--r-- | commands/of_compatible.c | 121 | ||||
-rw-r--r-- | commands/of_diff.c | 63 | ||||
-rw-r--r-- | commands/of_dump.c | 35 | ||||
-rw-r--r-- | commands/of_property.c | 16 |
6 files changed, 179 insertions, 72 deletions
diff --git a/commands/Kconfig b/commands/Kconfig index 4d3ff631a8..824e01690e 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -2190,6 +2190,21 @@ config CMD_LSMOD help List loaded barebox modules. +config CMD_OF_COMPATIBLE + tristate + select OFTREE + prompt "of_compatible" + help + Check DT node's compatible + + Usage: [-fFnk] [COMPAT] + + Options: + -f dtb work on dtb instead of internal devicetree + -F apply fixups on devicetree before compare + -n node node path or alias to compare its compatible (default is /) + -k compare $global.of.kernel.add_machine_compatible as well + config CMD_OF_DIFF tristate select OFTREE diff --git a/commands/Makefile b/commands/Makefile index 98625a0373..0c3980d463 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_CMD_USB) += usb.o obj-$(CONFIG_CMD_TIME) += time.o obj-$(CONFIG_CMD_UPTIME) += uptime.o obj-$(CONFIG_CMD_OFTREE) += oftree.o +obj-$(CONFIG_CMD_OF_COMPATIBLE) += of_compatible.o obj-$(CONFIG_CMD_OF_DIFF) += of_diff.o obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o obj-$(CONFIG_CMD_OF_NODE) += of_node.o diff --git a/commands/of_compatible.c b/commands/of_compatible.c new file mode 100644 index 0000000000..d8704d50bb --- /dev/null +++ b/commands/of_compatible.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: © 2023 Ahmad Fatoum <a.fatoum@pengutronix.de> + +#include <common.h> +#include <libfile.h> +#include <fdt.h> +#include <of.h> +#include <command.h> +#include <complete.h> +#include <errno.h> +#include <getopt.h> + +static int do_of_compatible(int argc, char *argv[]) +{ + int opt; + int ret = 0; + bool fix = false, kernel_compat = false; + struct device_node *root = NULL, *node, *of_free = NULL; + char **compats, **compat, *dtbfile = NULL; + const char *nodename = "/"; + + while ((opt = getopt(argc, argv, "f:n:Fk")) > 0) { + switch (opt) { + case 'f': + dtbfile = optarg; + break; + case 'n': + nodename = optarg; + break; + case 'F': + fix = true; + break; + case 'k': + kernel_compat = true; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (argc - optind < 1) + return COMMAND_ERROR_USAGE; + + compats = &argv[optind]; + + if (dtbfile) { + root = of_read_file(dtbfile); + if (IS_ERR(root)) + return PTR_ERR(root); + + of_free = root; + } else { + root = of_get_root_node(); + + /* copy internal device tree to apply fixups onto it */ + if (fix) + root = of_free = of_dup(root); + } + + if (fix) + of_fix_tree(root); + + node = of_find_node_by_path_or_alias(root, nodename); + if (!node) { + printf("Cannot find nodepath %s\n", nodename); + ret = -ENOENT; + goto out; + } + + ret = COMMAND_ERROR; + + if (kernel_compat) { + const char *compat_override; + + if (node->parent) { + printf("-k only valid for root node\n"); + ret = COMMAND_ERROR_USAGE; + goto out; + } + + compat_override = barebox_get_of_machine_compatible() ?: ""; + for (compat = compats; *compat; compat++) { + if (strcmp(*compat, compat_override) == 0) { + ret = COMMAND_SUCCESS; + goto out; + } + } + } + + for (compat = compats; *compat; compat++) { + int score; + + score = of_device_is_compatible(node, *compat); + if (score > 0) { + ret = COMMAND_SUCCESS; + break; + } + } + +out: + of_delete_node(of_free); + + return ret; +} + +BAREBOX_CMD_HELP_START(of_compatible) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-f dtb", "work on dtb instead of internal devicetree") +BAREBOX_CMD_HELP_OPT ("-F", "apply fixups on devicetree before compare") +BAREBOX_CMD_HELP_OPT ("-n node", "node path or alias to compare its compatible (default is /)") +BAREBOX_CMD_HELP_OPT ("-k", "compare $global.of.kernel.add_machine_compatible as well") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(of_compatible) + .cmd = do_of_compatible, + BAREBOX_CMD_DESC("Check DT node's compatible") + BAREBOX_CMD_OPTS("[-fFnk] [COMPATS..]") + BAREBOX_CMD_GROUP(CMD_GRP_MISC) + BAREBOX_CMD_COMPLETE(empty_complete) + BAREBOX_CMD_HELP(cmd_of_compatible_help) +BAREBOX_CMD_END diff --git a/commands/of_diff.c b/commands/of_diff.c index 19a4a26d20..8b19c093dd 100644 --- a/commands/of_diff.c +++ b/commands/of_diff.c @@ -18,59 +18,56 @@ static struct device_node *get_tree(const char *filename, struct device_node *ro struct device_node *node; if (!strcmp(filename, "-")) { - node = of_get_root_node(); - if (!node) - return ERR_PTR(-ENOENT); - - return of_dup(node); + node = of_dup(root) ?: ERR_PTR(-ENOENT); + } else if (!strcmp(filename, "+")) { + return NULL; + } else { + node = of_read_file(filename); } - if (!strcmp(filename, "+")) { - node = of_get_root_node(); - if (!node) - return ERR_PTR(-ENOENT); + if (IS_ERR(node)) + printf("Cannot read %s: %pe\n", filename, node); - node = of_dup(root); + return node; +} - of_fix_tree(node); +static struct device_node *get_tree_fixed(const struct device_node *root) +{ + struct device_node *node; - return node; - } + node = of_dup(root); + if (!IS_ERR(node)) + of_fix_tree(node); - return of_read_file(filename); + return node; } static int do_of_diff(int argc, char *argv[]) { - int ret = 0; + int ret = COMMAND_ERROR; struct device_node *a, *b, *root; - if (argc < 3) + if (argc != 3) return COMMAND_ERROR_USAGE; root = of_get_root_node(); a = get_tree(argv[1], root); b = get_tree(argv[2], root); - if (IS_ERR(a)) { - printf("Cannot read %s: %pe\n", argv[1], a); - ret = COMMAND_ERROR; - a = NULL; - goto out; - } + if (!a && !b) + return COMMAND_ERROR_USAGE; - if (IS_ERR(b)) { - printf("Cannot read %s: %pe\n", argv[2], b); - ret = COMMAND_ERROR; - b = NULL; - goto out; - } + if (!a) + a = get_tree_fixed(b); + if (!b) + b = get_tree_fixed(a); + + if (!IS_ERR(a) && !IS_ERR(b)) + ret = of_diff(a, b, 0) ? COMMAND_ERROR : COMMAND_SUCCESS; - ret = of_diff(a, b, 0) ? COMMAND_ERROR : COMMAND_SUCCESS; -out: - if (a && a != root) + if (!IS_ERR(a) && a != root) of_delete_node(a); - if (b && b != root) + if (!IS_ERR(b) && b != root) of_delete_node(b); return ret; @@ -80,7 +77,7 @@ BAREBOX_CMD_HELP_START(of_diff) BAREBOX_CMD_HELP_TEXT("This command prints a diff between two given device trees.") BAREBOX_CMD_HELP_TEXT("The device trees are given as dtb files or:") BAREBOX_CMD_HELP_TEXT("'-' to compare against the barebox live tree, or") -BAREBOX_CMD_HELP_TEXT("'+' to compare against the fixed barebox live tree") +BAREBOX_CMD_HELP_TEXT("'+' to compare against the other device tree after fixups") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(of_diff) diff --git a/commands/of_dump.c b/commands/of_dump.c index 86755ff1e4..c77dc27c99 100644 --- a/commands/of_dump.c +++ b/commands/of_dump.c @@ -72,38 +72,20 @@ static int do_of_dump(int argc, char *argv[]) if (dtbfile) { root = of_read_file(dtbfile); - if (IS_ERR(root)) { - printf("Cannot open %s: %pe\n", dtbfile, root); - ret = PTR_ERR(root); - goto out; - } + if (IS_ERR(root)) + return PTR_ERR(root); of_free = root; } else { root = of_get_root_node(); - if (fix) { - /* create a copy of internal devicetree */ - void *fdt; - fdt = of_flatten_dtb(root); - root = of_unflatten_dtb(fdt, fdt_totalsize(fdt)); - - free(fdt); - - if (IS_ERR(root)) { - ret = PTR_ERR(root); - goto out; - } - - of_free = root; - } + /* copy internal device tree to apply fixups onto it */ + if (fix) + root = of_free = of_dup(root); } - if (fix) { - ret = of_fix_tree(root); - if (ret) - goto out; - } + if (fix) + of_fix_tree(root); node = of_find_node_by_path_or_alias(root, nodename); if (!node) { @@ -120,8 +102,7 @@ static int do_of_dump(int argc, char *argv[]) of_print_nodes(node, 0, maxpropsize); out: - if (of_free) - of_delete_node(of_free); + of_delete_node(of_free); return ret; } diff --git a/commands/of_property.c b/commands/of_property.c index 063e97775c..0c914c55c6 100644 --- a/commands/of_property.c +++ b/commands/of_property.c @@ -305,7 +305,6 @@ static int do_of_property(int argc, char *argv[]) char *path, *propname; char *dtbfile = NULL; int ret = 0; - size_t size; struct fdt_header *fdt = NULL; struct device_node *root = NULL; @@ -340,15 +339,9 @@ static int do_of_property(int argc, char *argv[]) return COMMAND_ERROR_USAGE; if (dtbfile) { - fdt = read_file(dtbfile, &size); - if (!fdt) { - printf("unable to read %s: %m\n", dtbfile); - return -errno; - } - - root = of_unflatten_dtb(fdt, size); - - free(fdt); + root = of_read_file(dtbfile); + if (IS_ERR(root)) + return PTR_ERR(root); } if (set) { @@ -401,8 +394,7 @@ static int do_of_property(int argc, char *argv[]) out: - if (root) - of_delete_node(root); + of_delete_node(root); return ret; } |