From: Herve Codina <herve.codina@bootlin.com>
To: David Gibson <david@gibson.dropbear.id.au>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk@kernel.org>,
Conor Dooley <conor+dt@kernel.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
David Lechner <dlechner@baylibre.com>,
Ayush Singh <ayush@beagleboard.org>,
Geert Uytterhoeven <geert@linux-m68k.org>,
devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org,
Hui Pu <hui.pu@gehealthcare.com>,
Ian Ray <ian.ray@gehealthcare.com>,
Luca Ceresoli <luca.ceresoli@bootlin.com>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Herve Codina <herve.codina@bootlin.com>
Subject: [RFC PATCH v2 13/74] Add support for /addon/ keyword
Date: Wed, 26 Aug 2026 11:48:42 +0200 [thread overview]
Message-ID: <20260826094950.1088288-14-herve.codina@bootlin.com> (raw)
In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com>
The dts /addon/ keyword allows to mark a dts as an addon dts.
This is similar to /plugin/ used for overlay dts but specific to addon
dts.
It is also worth noting that a dts tagged with /addon/ will lead to a
dtb with the dt_flags set to FDT_FLAG_ADDON (0x1).
This allows to identify without any ambiguity an addon dts and an addon
dtb.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
checks.c | 36 +++++++++++++++++++++++-------------
dtc-lexer.l | 5 +++++
dtc-parser.y | 5 +++++
dtc.h | 1 +
fdtdump.c | 4 ++++
flattree.c | 15 ++++++++++++---
libfdt/fdt.h | 1 +
treesource.c | 6 ++++++
8 files changed, 57 insertions(+), 16 deletions(-)
diff --git a/checks.c b/checks.c
index a6037ed0..cb3b4b16 100644
--- a/checks.c
+++ b/checks.c
@@ -624,7 +624,7 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
refnode = get_node_by_ref(dt, m->ref);
if (! refnode) {
- if (!(dti->dtsflags & DTSF_PLUGIN))
+ if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)))
FAIL(c, dti, node, "Reference to non-existent node or "
"label \"%s\"\n", m->ref);
else /* mark the entry as unresolved */
@@ -726,8 +726,8 @@ static void check_alias_paths(struct check *c, struct dt_info *dti,
continue;
}
- /* This check does not work for overlays with external paths */
- if (!(dti->dtsflags & DTSF_PLUGIN) &&
+ /* This check does not work for overlays nor addons with external paths */
+ if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) &&
(!prop->val.val || !get_node_by_path(dti->dt, prop->val.val))) {
FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)",
prop->val.val);
@@ -1425,8 +1425,8 @@ static void check_property_phandle_args(struct check *c,
* entries when each index position has a specific definition.
*/
if (!phandle_is_valid(phandle)) {
- /* Give up if this is an overlay with external references */
- if (dti->dtsflags & DTSF_PLUGIN)
+ /* Give up if this is an overlay or addon with external references */
+ if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))
break;
cellsize = 0;
@@ -1659,8 +1659,8 @@ static void check_interrupt_map(struct check *c,
phandle = propval_cell_n(irq_map_prop, cell);
if (!phandle_is_valid(phandle)) {
- /* Give up if this is an overlay with external references */
- if (!(dti->dtsflags & DTSF_PLUGIN))
+ /* Give up if this is an overlay or an addon with external references */
+ if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)))
FAIL_PROP(c, dti, node, irq_map_prop,
"Cell %zu is not a phandle(%d)",
cell, phandle);
@@ -1728,9 +1728,9 @@ static void check_interrupts_property(struct check *c,
if (prop) {
phandle = propval_cell(prop);
if (!phandle_is_valid(phandle)) {
- /* Give up if this is an overlay with
+ /* Give up if this is an overlay with or an addon
* external references */
- if (dti->dtsflags & DTSF_PLUGIN)
+ if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))
return;
FAIL_PROP(c, dti, parent, prop, "Invalid phandle");
continue;
@@ -1846,8 +1846,8 @@ static void check_graph_port(struct check *c, struct dt_info *dti,
check_graph_reg(c, dti, node);
- /* skip checks below for overlays */
- if (dti->dtsflags & DTSF_PLUGIN)
+ /* skip checks below for overlays or addons */
+ if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))
return;
if (!strprefixeq(node->name, node->basenamelen, "port"))
@@ -1888,8 +1888,8 @@ static void check_graph_endpoint(struct check *c, struct dt_info *dti,
check_graph_reg(c, dti, node);
- /* skip checks below for overlays */
- if (dti->dtsflags & DTSF_PLUGIN)
+ /* skip checks below for overlays or addons */
+ if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))
return;
if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
@@ -2062,6 +2062,16 @@ void process_checks(bool force, struct dt_info *dti)
unsigned int i;
int error = 0;
+ if ((dti->dtsflags & (DTSF_ADDON | DTSF_PLUGIN)) == (DTSF_ADDON | DTSF_PLUGIN)) {
+ /*
+ * Addons and overlays are mutually exclusive. The same input
+ * cannot be both.
+ */
+ fprintf(stderr,
+ "ERROR: Input tree cannot be both an addon and an overlay\n");
+ exit(2);
+ }
+
for (i = 0; i < ARRAY_SIZE(check_table); i++) {
struct check *c = check_table[i];
diff --git a/dtc-lexer.l b/dtc-lexer.l
index 1b129b11..7e9b6796 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -108,6 +108,11 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
return DT_PLUGIN;
}
+<*>"/addon/" {
+ DPRINT("Keyword: /addon/\n");
+ return DT_ADDON;
+ }
+
<*>"/memreserve/" {
DPRINT("Keyword: /memreserve/\n");
BEGIN_DEFAULT();
diff --git a/dtc-parser.y b/dtc-parser.y
index e47f80d4..2e152b0e 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -53,6 +53,7 @@ static bool is_ref_relative(const char *ref)
%token DT_V1
%token DT_PLUGIN
+%token DT_ADDON
%token DT_MEMRESERVE
%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
%token DT_BITS
@@ -120,6 +121,10 @@ header:
{
$$ = DTSF_V1 | DTSF_PLUGIN;
}
+ | DT_V1 ';' DT_ADDON ';'
+ {
+ $$ = DTSF_V1 | DTSF_ADDON;
+ }
;
headers:
diff --git a/dtc.h b/dtc.h
index 64eaffde..40aab572 100644
--- a/dtc.h
+++ b/dtc.h
@@ -336,6 +336,7 @@ struct dt_info {
/* DTS version flags definitions */
#define DTSF_V1 0x0001 /* /dts-v1/ */
#define DTSF_PLUGIN 0x0002 /* /plugin/ */
+#define DTSF_ADDON 0x0004 /* /addon/ */
struct dt_info *build_dt_info(unsigned int dtsflags,
struct reserve_info *reservelist,
diff --git a/fdtdump.c b/fdtdump.c
index 2acf3210..370db848 100644
--- a/fdtdump.c
+++ b/fdtdump.c
@@ -120,6 +120,10 @@ static void dump_blob(void *blob, bool debug, int dump_unknown)
printf("// last_comp_version_w:\t%"PRIu32"\n",
fdt32_to_cpu(bph->last_comp_version_w));
}
+ if (version >= 18) {
+ if (fdt32_to_cpu(bph->dt_flags) & FDT_FLAG_ADDON)
+ printf("/addon/;\n");
+ }
printf("\n");
for (i = 0; ; i++) {
diff --git a/flattree.c b/flattree.c
index abc50873..004119c4 100644
--- a/flattree.c
+++ b/flattree.c
@@ -420,6 +420,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
struct data dtbuf = empty_data;
struct data strbuf = empty_data;
struct fdt_header fdt;
+ uint32_t dt_flags = 0;
int padlen = 0;
for (i = 0; i < ARRAY_SIZE(version_table); i++) {
@@ -429,6 +430,8 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
if (!vi)
die("Unknown device tree blob version %d\n", version);
+ dt_flags |= dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0;
+
flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi);
bin_emit_cell(&dtbuf, FDT_END);
@@ -436,7 +439,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
/* Make header */
make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
- dti->boot_cpuid_phys, 0);
+ dti->boot_cpuid_phys, dt_flags);
/*
* If the user asked for more space than is used, adjust the totalsize.
@@ -519,6 +522,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
struct data strbuf = empty_data;
struct reserve_info *re;
const char *symprefix = "dt";
+ uint32_t dt_flags = 0;
for (i = 0; i < ARRAY_SIZE(version_table); i++) {
if (version_table[i].version == version)
@@ -527,6 +531,8 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
if (!vi)
die("Unknown device tree blob version %d\n", version);
+ dt_flags |= dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0;
+
fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
emit_label(f, symprefix, "blob_start");
@@ -569,7 +575,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
if (vi->flags & FTF_DTFLAGS) {
fprintf(f, "\t/* dt_flags */\n");
- asm_emit_cell(f, 0);
+ asm_emit_cell(f, dt_flags);
}
if (vi->flags & FTF_LCVERSW) {
@@ -1113,8 +1119,11 @@ struct dt_info *dt_from_blob(const char *fname)
if (version >= 18)
flags |= FTF_DTFLAGS | FTF_LCVERSW;
- if (version >= 20)
+ if (version >= 20) {
flags |= FTF_PROPDATA_PHANDLE;
+ dtsflags |= fdt32_to_cpu(fdt->dt_flags) & FDT_FLAG_ADDON ?
+ DTSF_ADDON : 0;
+ }
inbuf_init(&memresvbuf,
blob + off_mem_rsvmap, blob + totalsize);
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index c151aa2b..255e9447 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -52,6 +52,7 @@ struct fdt_property {
#endif /* !__ASSEMBLER__ */
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_FLAG_ADDON 0x1
#define FDT_TAGSIZE sizeof(fdt32_t)
#define FDT_CELLSIZE sizeof(fdt32_t)
diff --git a/treesource.c b/treesource.c
index 0e33e3e1..9f6cf92d 100644
--- a/treesource.c
+++ b/treesource.c
@@ -420,8 +420,14 @@ void dt_to_source(FILE *f, struct dt_info *dti)
struct reserve_info *re;
fprintf(f, "/dts-v1/;\n");
+ /*
+ * DTSF_PLUGIN and DTSF_ADDON are mutually exclusive. This has been
+ * already checked.
+ */
if (dti->dtsflags & DTSF_PLUGIN)
fprintf(f, "/plugin/;\n");
+ if (dti->dtsflags & DTSF_ADDON)
+ fprintf(f, "/addon/;\n");
fprintf(f, "\n");
for (re = dti->reservelist; re; re = re->next) {
--
2.55.0
next prev parent reply other threads:[~2026-08-26 9:51 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 9:48 [RFC PATCH v2 00/74] Add support for dtb metadata and addon device-trees Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 01/74] dtc-parser.y: Avoid an empty proplist Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 02/74] Introduce v20 dtb version Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 03/74] fdtdump: Introduce get_structured_tag_data() Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 04/74] libfdt: Introduce fdt_get_structured_tag_data() Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 05/74] libfdt: Prepare for metadata tag support Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 06/74] dtc: Move fill_fullpaths() into build_dt_info() Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 07/74] Add support for FDT_PROPDATA_PHANDLE dtb tag Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 08/74] livetree: Improve get_node_by_phandle() Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 09/74] dtc: Complete REF_PHANDLE markers with ref strings and is_local flags Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 10/74] tests: Add basic metadata tests Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 11/74] Add support for FDT_PROPDATA_PHANDLE_REF dtb tag Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 12/74] tests: metadata: Add external phandle reference tests Herve Codina
2026-08-26 9:48 ` Herve Codina [this message]
2026-08-26 9:48 ` [RFC PATCH v2 14/74] tests: Add a test related to addon dt_flags header value Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 15/74] tests: metadata: Add a basic addon test Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 16/74] dtc: Introduce export symbols Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 17/74] dtc: Add support for /export/ dts keyword parsing Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 18/74] checks: Handle export symbols in fixup_phandle_references() Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 19/74] dtc: Add export symbols (/export/ keyword) in generated dts file Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 20/74] dtc: Extend complete_references() to handle export symbols Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 21/74] Add support for FDT_EXPORT_SYM dtb tag Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 22/74] tests: metadata: Add export symbols with local references tests Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 23/74] dtc: Add support for export symbols sorting Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 24/74] tests: metadata: Add a test " Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 25/74] Add support for FDT_EXPORT_SYM_REF dtb tag Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 26/74] tests: metadata: Add export symbols with external references tests Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 27/74] dtc: Introduce import symbols Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 28/74] dtc-parser: Introduce last_header_flags Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 29/74] dtc: Add support for /import/ dts keyword parsing Herve Codina
2026-08-26 9:48 ` [RFC PATCH v2 30/74] dtc: Add import symbols (/import/ keyword) in generated dts file Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 31/74] Add support for FDT_IMPORT_SYM dtb tag Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 32/74] tests: metadata: Add import symbols tests Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 33/74] dtc: Add support for import symbols sorting Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 34/74] tests: metadata: Improve sort test to check " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 35/74] checks: Get 'chosen' node using get_subnode() Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 36/74] dtc: Change get_node_by_path() signature to take dt_info Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 37/74] dtc: Change get_node_by_label() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 38/74] dtc: Change get_node_by_phandle() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 39/74] dtc: Change get_node_by_ref() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 40/74] dtc: Change get_node_phandle() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 41/74] dtc: Change get_property_by_label() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 42/74] dtc: Change get_marker_label() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 43/74] dtc: Change fill_fullpaths() " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 44/74] dtc: Introduce orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 45/74] dtc: Handle orphan nodes in get_xxx_by_yyy() Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 46/74] dtc: Avoid NULL fullpath for nodes in orphan trees Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 47/74] dtc: Handle orphan nodes in complete_references() Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 48/74] checks: Perform checks for orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 49/74] dtc: Rename add_orphan_node() to plugin_add_orphan_node() Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 50/74] dtc: Add basic support for addon orphan nodes in dts Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 51/74] Add support for FDT_BEGIN_NODE_REF dtb tag Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 52/74] tests: metadata: Add basic test for addon orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 53/74] dtc: Add support for missing root node in addon device-tree Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 54/74] tests: metadata: Add a test for addon without root node Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 55/74] dtc: Allow parser_get_node_by_ref() to return an orphan node for merging purpose Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 56/74] tests: metadata: Add a test related to orphan node merging Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 57/74] dtc: Add support for orphan nodes sorting Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 58/74] tests: metadata: Improve sort test to check " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 59/74] dtc: Add support for references by path involving orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 60/74] tests: metadata: Add a test " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 61/74] dtc: Add support for namespace labels references Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 62/74] tests: metadata: Add a test " Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 63/74] libfdt: Add support for applying an addon on a base device-tree blob Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 64/74] Add fdtaddon tool to apply an addon Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 65/74] tests: Add a first basic test for fdtaddon Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 66/74] tests: fdtaddon: Add a basic test for addons using an orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 67/74] tests: fdtaddon: Add a basic test for addons with unresolved phandle references Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 68/74] tests: fdtaddon: Add a basic test for addons with references by path to orphan nodes Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 69/74] tests: fdtaddon: Add a test for addons with properties identical to existing ones Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 70/74] tests: fdtaddon: Add a test for addons using namespace label references Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 71/74] tests: fdtaddon: Add a test for using 'stacked' addons Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 72/74] tests: fdtaddon: Add a test using more realistic dts and dtsa Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 73/74] libfdt/fdt_addon.c: Add support for an external resolver Herve Codina
2026-08-26 9:49 ` [RFC PATCH v2 74/74] fdtaddon: Add a simple " Herve Codina
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=20260826094950.1088288-14-herve.codina@bootlin.com \
--to=herve.codina@bootlin.com \
--cc=ayush@beagleboard.org \
--cc=conor+dt@kernel.org \
--cc=david@gibson.dropbear.id.au \
--cc=devicetree-compiler@vger.kernel.org \
--cc=devicetree-spec@vger.kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=geert@linux-m68k.org \
--cc=hui.pu@gehealthcare.com \
--cc=ian.ray@gehealthcare.com \
--cc=krzk@kernel.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luca.ceresoli@bootlin.com \
--cc=robh@kernel.org \
--cc=thomas.petazzoni@bootlin.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.