summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2023-06-22 09:59:27 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-06-22 09:59:27 +0200
commit9be6eb40e5e55560d07a5056d978880ae879329d (patch)
tree98777637dd1e4d9be327cf70d4014793fe85e8fe /commands
parentf946c859fe5e25b7538742fbc8542921b095cffa (diff)
parentecd7854b9c661571137802bfc831c9fb07cbe820 (diff)
downloadbarebox-9be6eb40e5e55560d07a5056d978880ae879329d.tar.gz
barebox-9be6eb40e5e55560d07a5056d978880ae879329d.tar.xz
Merge branch 'for-next/of-compat'
Diffstat (limited to 'commands')
-rw-r--r--commands/Kconfig15
-rw-r--r--commands/Makefile1
-rw-r--r--commands/of_compatible.c121
-rw-r--r--commands/of_diff.c63
-rw-r--r--commands/of_dump.c35
-rw-r--r--commands/of_property.c16
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;
}