Browse Source

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>
main
Kumar Gala 6 years ago committed by David Gibson
parent
commit
7cbc550f90
  1. 41
      checks.c

41
checks.c

@ -1212,8 +1212,24 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d @@ -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, @@ -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[] = { @@ -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,


Loading…
Cancel
Save