From: Fabien Parent <[email protected]>
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 <[email protected]>
Signed-off-by: Benoit Cousson <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html