aboutsummaryrefslogtreecommitdiff
path: root/dtc-parser.y
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2020-10-25 12:39:59 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2022-01-25 17:10:47 +1100
commitec7986e682cf9a5078bdbad341feb807a56b21e0 (patch)
treec8fbf13a9b2d6d8570b46dcf2e2052a96102ced2 /dtc-parser.y
parent651410e54cb9a478f2fbb16cb493a5e7808ad8fe (diff)
downloaddtc-ec7986e682cf9a5078bdbad341feb807a56b21e0.zip
dtc-ec7986e682cf9a5078bdbad341feb807a56b21e0.tar.gz
dtc-ec7986e682cf9a5078bdbad341feb807a56b21e0.tar.bz2
dtc: introduce label relative path references
Reference via label allows extending nodes with compile-time checking of whether the node being extended exists. This is useful to catch renamed/removed nodes after an update of the device trees to be extended. In absence of labels in the original device trees, new style path references can be used: /* upstream device tree */ / { leds: some-non-standard-led-controller-name { led-0 { default-state = "off"; }; }; }; /* downstream device tree */ &{/some-non-standard-led-controller-name/led-0} { default-state = "on"; }; This is a common theme within the barebox bootloader[0], which extends the upstream (Linux) device trees in that manner. The downside is that, especially for deep nodes, these references can get quite long and tend to break often due to upstream rework (e.g. rename to adhere to bindings). Often there is a label a level or two higher that could be used. This patch allows combining both a label and a new style path reference to get a compile-time-checked reference, which allows rewriting the previous downstream device tree snippet to: &{leds/led-0} { default-state = "on"; }; This won't be broken when /some-non-standard-led-controller-name is renamed or moved while keeping the label. And if led-0 is renamed, we will get the expected compile-time error. Overlay support is skipped for now as they require special support: The label and relative path parts need to be resolved at overlay apply-time, not at compile-time. [0]: https://www.barebox.org/doc/latest/devicetree/index.html Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Diffstat (limited to 'dtc-parser.y')
-rw-r--r--dtc-parser.y13
1 files changed, 13 insertions, 0 deletions
diff --git a/dtc-parser.y b/dtc-parser.y
index a0316a3..46457d4 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -23,6 +23,12 @@ extern void yyerror(char const *s);
extern struct dt_info *parser_output;
extern bool treesource_error;
+
+static bool is_ref_relative(const char *ref)
+{
+ return ref[0] != '/' && strchr(&ref[1], '/');
+}
+
%}
%union {
@@ -169,6 +175,8 @@ devicetree:
*/
if (!($<flags>-1 & DTSF_PLUGIN))
ERROR(&@2, "Label or path %s not found", $1);
+ else if (is_ref_relative($1))
+ ERROR(&@2, "Label-relative reference %s not supported in plugin", $1);
$$ = add_orphan_node(
name_node(build_node(NULL, NULL, NULL),
""),
@@ -178,6 +186,9 @@ devicetree:
{
struct node *target = get_node_by_ref($1, $3);
+ if (($<flags>-1 & DTSF_PLUGIN) && is_ref_relative($3))
+ ERROR(&@2, "Label-relative reference %s not supported in plugin", $3);
+
if (target) {
add_label(&target->labels, $2);
merge_nodes(target, $4);
@@ -193,6 +204,8 @@ devicetree:
* so $-1 is what we want (plugindecl)
*/
if ($<flags>-1 & DTSF_PLUGIN) {
+ if (is_ref_relative($2))
+ ERROR(&@2, "Label-relative reference %s not supported in plugin", $2);
add_orphan_node($1, $3, $2);
} else {
struct node *target = get_node_by_ref($1, $2);