[RFC 10/15] scripts/dtc: add count limit on nodes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Fabien Parent <fparent@xxxxxxxxxxxx>

Add the possibility to specify in a schema a count limit for the nodes matching
the schema:
    - count: if there is a match between a dts and a schema then there must
    be exactly X match between the dts and the schema at the end of the
    validation process.
    - max-count: if there is a match between a dts and a schema then there must
    be at most X match between the dts and the schema at the end of the
    validation process.
This can be used to check if a specific node appears the right amount of time
in the dts.

Add as well four test files for this feature.

/ {
    timer1 {
        compatible = "ti,omap-4430-timer";
        ...
    };

    timer2 {
        compatible = "ti,omap-4430-timer";
        ...
    };
};

If in the above dts there must be exactly two timer one can check this
constraints with the following schema:

/ {
    compatible = "ti,omap-4430-timer";
    count = <2>;
};

Note: If the dts doesn't specify any timer the dts will still be valid. To
ensure that the timer is really present 2 times one should might wants to
specify constraints on then children of a node, but this feature is not
yet available.

Signed-off-by: Fabien Parent <fparent@xxxxxxxxxxxx>
Signed-off-by: Benoit Cousson <bcousson@xxxxxxxxxxxx>
---
 scripts/dtc/schema-test.c                      | 10 ++++
 scripts/dtc/schema.c                           | 63 ++++++++++++++++++++++++--
 scripts/dtc/tests/schemas/nodes-count-1.schema |  5 ++
 scripts/dtc/tests/schemas/nodes-count-2.schema |  5 ++
 scripts/dtc/tests/schemas/nodes-count-3.schema |  5 ++
 scripts/dtc/tests/schemas/nodes-count-4.schema |  5 ++
 6 files changed, 89 insertions(+), 4 deletions(-)
 create mode 100644 scripts/dtc/tests/schemas/nodes-count-1.schema
 create mode 100644 scripts/dtc/tests/schemas/nodes-count-2.schema
 create mode 100644 scripts/dtc/tests/schemas/nodes-count-3.schema
 create mode 100644 scripts/dtc/tests/schemas/nodes-count-4.schema

diff --git a/scripts/dtc/schema-test.c b/scripts/dtc/schema-test.c
index a8a5664..128a265 100644
--- a/scripts/dtc/schema-test.c
+++ b/scripts/dtc/schema-test.c
@@ -65,6 +65,16 @@ static struct schema_test tests[] = {
 	 "tests/schemas/pattern-matching-1.schema", 1},
 	{"Pattern Matching #2", "tests/test1.dts",
 	 "tests/schemas/pattern-matching-2.schema", 0},
+
+	/* Nodes Count */
+	{"Nodes Count #1", "tests/test1.dts",
+	 "tests/schemas/nodes-count-1.schema", 1},
+	{"Nodes Count #2", "tests/test1.dts",
+	 "tests/schemas/nodes-count-2.schema", 1},
+	{"Nodes Count #3", "tests/test1.dts",
+	 "tests/schemas/nodes-count-3.schema", 0},
+	{"Nodes Count #4", "tests/test1.dts",
+	 "tests/schemas/nodes-count-4.schema", 0},
 };
 
 int main(void)
diff --git a/scripts/dtc/schema.c b/scripts/dtc/schema.c
index d96129f..b7cfb37 100644
--- a/scripts/dtc/schema.c
+++ b/scripts/dtc/schema.c
@@ -88,7 +88,10 @@ struct node_constraints {
 	struct boot_info *bi;
 	struct node *dt;
 
-	const char *compatible;
+	char *compatible;
+	uint32_t count_requested;
+	uint32_t count;
+	uint32_t max_count;
 };
 
 struct schema_db {
@@ -657,6 +660,23 @@ static int validate_properties(struct node *n,
 	return ret;
 }
 
+static void load_node_constraints(struct node_constraints *nc,
+				  struct node *n)
+{
+	struct property *p;
+
+	assert(n);
+	assert(nc);
+
+	nc->count = 0;
+
+	p = get_property(n, "count");
+	nc->count_requested = p ? prop_val_to_uint32(p, 0) : 0;
+
+	p = get_property(n, "max-count");
+	nc->max_count = p ? prop_val_to_uint32(p, 0) : ULONG_MAX;
+}
+
 static int validate_node(struct node *n,
 			 struct node_constraints *nc,
 			 struct node_list *path)
@@ -698,6 +718,7 @@ static struct node_constraints *get_node_constraints_of(struct schema_db *db,
 			n->bi = dt_from_source(n->filepath);
 			n->dt = n->bi->dt;
 		}
+		n->count++;
 		(*i)++;
 		return n;
 	}
@@ -705,6 +726,33 @@ static struct node_constraints *get_node_constraints_of(struct schema_db *db,
 	return NULL;
 }
 
+static int check_nodes_count(struct schema_db *db)
+{
+	int i;
+	int ret = 1;
+	struct node_constraints *n;
+
+	for (i = 0; i < db->size; i++) {
+		n = &db->buffer[i];
+
+		if (n->count_requested) {
+			DT_ERROR_IF(n->count != n->count_requested, NULL, NULL,
+				    "There is %u instance of %s instead "
+				    "of %u.\n",
+				    n->count,
+				    n->compatible,
+				    n->count_requested);
+		} else {
+			DT_ERROR_IF(n->count > n->max_count, NULL, NULL,
+				    "There is too much instance of %s.\n",
+				    n->compatible);
+		}
+	}
+
+end:
+	return ret;
+}
+
 static int for_each_compatible_validate(struct schema_db *db,
 					struct property *p,
 					struct node *node,
@@ -771,11 +819,15 @@ static int validate_nodes(struct schema_db *db,
 
 int validate_dt(struct schema_db *db, struct boot_info *bi)
 {
+	int ret = 1;
+
 	assert(bi);
 	assert(bi->dt);
 	assert(db);
 
-	return validate_nodes(db, bi->dt, NULL);
+	ret &= validate_nodes(db, bi->dt, NULL);
+	ret &= check_nodes_count(db);
+	return ret;
 }
 
 void exit_on_schema_validation_failure(int exit)
@@ -836,7 +888,7 @@ add_compatible_to_schema_db(struct schema_db *db,
 
 	nc = add_new_entry_to_schema_db(db);
 
-	nc->compatible = compatible;
+	nc->compatible = xstrdup(compatible);
 	nc->re_compat = compile_pattern(compatible);
 	if (!nc->re_compat)
 		die("Invalid regex for compatible in %s\n", file);
@@ -851,6 +903,7 @@ static void add_to_schema_db_from_property(struct schema_db *db,
 					   struct node *root)
 {
 	int offset = 0;
+	struct node_constraints *nc;
 
 	assert(db);
 	assert(file);
@@ -858,7 +911,8 @@ static void add_to_schema_db_from_property(struct schema_db *db,
 	assert(p->val.type == STRING);
 
 	while (offset >= 0 && offset < p->val.len) {
-		add_compatible_to_schema_db(db, p->val.val + offset, file);
+		nc = add_compatible_to_schema_db(db, p->val.val + offset, file);
+		load_node_constraints(nc, root);
 		offset = get_next_string_offset(p, offset);
 	}
 }
@@ -973,6 +1027,7 @@ static void free_node_constraints(struct node_constraints *nc)
 	pcre_free(nc->re_compat);
 	free_dt(nc->bi);
 	free(nc->filepath);
+	free(nc->compatible);
 }
 
 void free_schema_db(struct schema_db *db)
diff --git a/scripts/dtc/tests/schemas/nodes-count-1.schema b/scripts/dtc/tests/schemas/nodes-count-1.schema
new file mode 100644
index 0000000..2dc574f
--- /dev/null
+++ b/scripts/dtc/tests/schemas/nodes-count-1.schema
@@ -0,0 +1,5 @@
+/dts-v1/;
+/ {
+	compatible = "compat[1-2]";
+	count = <2>;
+};
diff --git a/scripts/dtc/tests/schemas/nodes-count-2.schema b/scripts/dtc/tests/schemas/nodes-count-2.schema
new file mode 100644
index 0000000..ca8bb4b
--- /dev/null
+++ b/scripts/dtc/tests/schemas/nodes-count-2.schema
@@ -0,0 +1,5 @@
+/dts-v1/;
+/ {
+	compatible = "compat[1-2]";
+	max-count = <5>;
+};
diff --git a/scripts/dtc/tests/schemas/nodes-count-3.schema b/scripts/dtc/tests/schemas/nodes-count-3.schema
new file mode 100644
index 0000000..bcbded0
--- /dev/null
+++ b/scripts/dtc/tests/schemas/nodes-count-3.schema
@@ -0,0 +1,5 @@
+/dts-v1/;
+/ {
+	compatible = "compat[1-2]";
+	count = <3>;
+};
diff --git a/scripts/dtc/tests/schemas/nodes-count-4.schema b/scripts/dtc/tests/schemas/nodes-count-4.schema
new file mode 100644
index 0000000..04408f9
--- /dev/null
+++ b/scripts/dtc/tests/schemas/nodes-count-4.schema
@@ -0,0 +1,5 @@
+/dts-v1/;
+/ {
+	compatible = "compat[1-2]";
+	max-count = <1>;
+};
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux