summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Gala <kumar.gala@linaro.org>2018-12-13 13:30:14 -0600
committerDavid Gibson <david@gibson.dropbear.id.au>2018-12-15 18:47:55 +1100
commit7cbc550f903b23f2291c7ca5d347ae0236ce27b6 (patch)
tree458f9eff940e601e74017b95d92d192f6a1f69b4
parentf267e674d1452d381bb2f180695801454d3549ad (diff)
downloaddevice-tree-compiler-7cbc550f903b23f2291c7ca5d347ae0236ce27b6.tar.gz
checks: Add unit address check if node is enabled
There are various SoCs that have 2 different peripheral blocks at the same register offset. However, we might have one block marked as status = "disabled" and the other status = "ok". In such cases we shouldn't warn about duplicate unit-address. Here's a cut down example that we would warning about before: /dts-v1/; / { #address-cells = <0x01>; #size-cells = <0x01>; soc { #address-cells = <0x01>; #size-cells = <0x01>; compatible = "simple-bus"; ranges; i2c0: i2c@40003000 { compatible = "nordic,nrf-i2c"; reg = <0x40003000 0x1000>; status = "ok"; }; spi0: spi@40003000 { compatible = "nordic,nrf-spi"; reg = <0x40003000 0x1000>; status = "disabled"; }; }; }; We introduce 'unique_unit_address_if_enabled' check that is disabled by default. Signed-off-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--checks.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/checks.c b/checks.c
index 4834e44..c0ed45e 100644
--- a/checks.c
+++ b/checks.c
@@ -1212,8 +1212,24 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
}
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
-static void check_unique_unit_address(struct check *c, struct dt_info *dti,
- struct node *node)
+static bool node_is_disabled(struct node *node)
+{
+ struct property *prop;
+
+ prop = get_property(node, "status");
+ if (prop) {
+ char *str = prop->val.val;
+ if (streq("disabled", str))
+ return true;
+ }
+
+ return false;
+}
+
+static void check_unique_unit_address_common(struct check *c,
+ struct dt_info *dti,
+ struct node *node,
+ bool disable_check)
{
struct node *childa;
@@ -1230,18 +1246,38 @@ static void check_unique_unit_address(struct check *c, struct dt_info *dti,
if (!strlen(addr_a))
continue;
+ if (disable_check && node_is_disabled(childa))
+ continue;
+
for_each_child(node, childb) {
const char *addr_b = get_unitname(childb);
if (childa == childb)
break;
+ if (disable_check && node_is_disabled(childb))
+ continue;
+
if (streq(addr_a, addr_b))
FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
}
}
}
+
+static void check_unique_unit_address(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ check_unique_unit_address_common(c, dti, node, false);
+}
WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
+static void check_unique_unit_address_if_enabled(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ check_unique_unit_address_common(c, dti, node, true);
+}
+CHECK_ENTRY(unique_unit_address_if_enabled, check_unique_unit_address_if_enabled,
+ NULL, false, false, &avoid_default_addr_size);
+
static void check_obsolete_chosen_interrupt_controller(struct check *c,
struct dt_info *dti,
struct node *node)
@@ -1769,6 +1805,7 @@ static struct check *check_table[] = {
&avoid_default_addr_size,
&avoid_unnecessary_addr_size,
&unique_unit_address,
+ &unique_unit_address_if_enabled,
&obsolete_chosen_interrupt_controller,
&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,