From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH] commands: implement of_compatible command
Date: Thu, 20 Apr 2023 22:09:28 +0200 [thread overview]
Message-ID: <20230420200928.2237187-1-a.fatoum@pengutronix.de> (raw)
Currently, the usual way within scripts to differentiate between machines
is to compare global.model or global.hostname. Both are suboptimal,
because they may change between releases or overridden by the user.
In C code, the machine compatible is used for this purpose. Add a new
of_compatible command that makes of_machine_is_compatible/
of_device_is_compatible available to scripts. Example use:
/env/init/fixups:
#!/bin/sh
if of_compatible -k radxa,rock3a ; then
of_property -df mmc0 sd-uhs-sdr104
fi
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
commands/Kconfig | 15 +++++
commands/Makefile | 1 +
commands/of_compatible.c | 139 +++++++++++++++++++++++++++++++++++++++
3 files changed, 155 insertions(+)
create mode 100644 commands/of_compatible.c
diff --git a/commands/Kconfig b/commands/Kconfig
index b9abd8565523..59e8d6fb382d 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2201,6 +2201,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 comptible (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 e5cc21f1970a..0ac84076f83d 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 000000000000..e4684f23b71d
--- /dev/null
+++ b/commands/of_compatible.c
@@ -0,0 +1,139 @@
+// 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 *dtbfile = NULL;
+ const char *compat, *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;
+
+ compat = argv[optind];
+
+ if (dtbfile) {
+ size_t size;
+ void *fdt;
+
+ fdt = read_file(dtbfile, &size);
+ if (!fdt) {
+ printf("unable to read %s: %s\n", dtbfile, strerror(errno));
+ return -errno;
+ }
+
+ root = of_unflatten_dtb(fdt, size);
+
+ free(fdt);
+
+ if (IS_ERR(root)) {
+ ret = PTR_ERR(root);
+ goto out;
+ }
+
+ 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;
+ }
+ }
+
+ if (fix) {
+ ret = of_fix_tree(root);
+ if (ret)
+ goto out;
+ }
+
+ node = of_find_node_by_path_or_alias(root, nodename);
+ if (!node) {
+ printf("Cannot find nodepath %s\n", nodename);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ 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() ?: "";
+ if (strcmp(compat_override, compat) == 0) {
+ ret = 0;
+ goto out;
+ }
+ }
+
+ ret = !of_device_is_compatible(node, compat);
+
+out:
+ if (of_free)
+ 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] [COMPAT]")
+ BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+ BAREBOX_CMD_COMPLETE(empty_complete)
+ BAREBOX_CMD_HELP(cmd_of_compatible_help)
+BAREBOX_CMD_END
--
2.39.2
next reply other threads:[~2023-04-20 20:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-20 20:09 Ahmad Fatoum [this message]
2023-05-02 11:17 ` Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230420200928.2237187-1-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox