aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/checks.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/dtc/checks.c')
-rw-r--r--scripts/dtc/checks.c105
1 files changed, 94 insertions, 11 deletions
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 95485796f253..a662a0044798 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -278,32 +278,112 @@ static void check_property_name_chars(struct check *c, struct node *dt,
278} 278}
279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); 279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
280 280
281#define DESCLABEL_FMT "%s%s%s%s%s"
282#define DESCLABEL_ARGS(node,prop,mark) \
283 ((mark) ? "value of " : ""), \
284 ((prop) ? "'" : ""), \
285 ((prop) ? (prop)->name : ""), \
286 ((prop) ? "' in " : ""), (node)->fullpath
287
288static void check_duplicate_label(struct check *c, struct node *dt,
289 const char *label, struct node *node,
290 struct property *prop, struct marker *mark)
291{
292 struct node *othernode = NULL;
293 struct property *otherprop = NULL;
294 struct marker *othermark = NULL;
295
296 othernode = get_node_by_label(dt, label);
297
298 if (!othernode)
299 otherprop = get_property_by_label(dt, label, &othernode);
300 if (!othernode)
301 othermark = get_marker_label(dt, label, &othernode,
302 &otherprop);
303
304 if (!othernode)
305 return;
306
307 if ((othernode != node) || (otherprop != prop) || (othermark != mark))
308 FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
309 " and " DESCLABEL_FMT,
310 label, DESCLABEL_ARGS(node, prop, mark),
311 DESCLABEL_ARGS(othernode, otherprop, othermark));
312}
313
314static void check_duplicate_label_node(struct check *c, struct node *dt,
315 struct node *node)
316{
317 struct label *l;
318
319 for_each_label(node->labels, l)
320 check_duplicate_label(c, dt, l->label, node, NULL, NULL);
321}
322static void check_duplicate_label_prop(struct check *c, struct node *dt,
323 struct node *node, struct property *prop)
324{
325 struct marker *m = prop->val.markers;
326 struct label *l;
327
328 for_each_label(prop->labels, l)
329 check_duplicate_label(c, dt, l->label, node, prop, NULL);
330
331 for_each_marker_of_type(m, LABEL)
332 check_duplicate_label(c, dt, m->ref, node, prop, m);
333}
334CHECK(duplicate_label, NULL, check_duplicate_label_node,
335 check_duplicate_label_prop, NULL, ERROR);
336
281static void check_explicit_phandles(struct check *c, struct node *root, 337static void check_explicit_phandles(struct check *c, struct node *root,
282 struct node *node) 338 struct node *node, struct property *prop)
283{ 339{
284 struct property *prop; 340 struct marker *m;
285 struct node *other; 341 struct node *other;
286 cell_t phandle; 342 cell_t phandle;
287 343
288 prop = get_property(node, "linux,phandle"); 344 if (!streq(prop->name, "phandle")
289 if (! prop) 345 && !streq(prop->name, "linux,phandle"))
290 return; /* No phandle, that's fine */ 346 return;
291 347
292 if (prop->val.len != sizeof(cell_t)) { 348 if (prop->val.len != sizeof(cell_t)) {
293 FAIL(c, "%s has bad length (%d) linux,phandle property", 349 FAIL(c, "%s has bad length (%d) %s property",
294 node->fullpath, prop->val.len); 350 node->fullpath, prop->val.len, prop->name);
351 return;
352 }
353
354 m = prop->val.markers;
355 for_each_marker_of_type(m, REF_PHANDLE) {
356 assert(m->offset == 0);
357 if (node != get_node_by_ref(root, m->ref))
358 /* "Set this node's phandle equal to some
359 * other node's phandle". That's nonsensical
360 * by construction. */ {
361 FAIL(c, "%s in %s is a reference to another node",
362 prop->name, node->fullpath);
363 return;
364 }
365 /* But setting this node's phandle equal to its own
366 * phandle is allowed - that means allocate a unique
367 * phandle for this node, even if it's not otherwise
368 * referenced. The value will be filled in later, so
369 * no further checking for now. */
295 return; 370 return;
296 } 371 }
297 372
298 phandle = propval_cell(prop); 373 phandle = propval_cell(prop);
374
299 if ((phandle == 0) || (phandle == -1)) { 375 if ((phandle == 0) || (phandle == -1)) {
300 FAIL(c, "%s has invalid linux,phandle value 0x%x", 376 FAIL(c, "%s has bad value (0x%x) in %s property",
301 node->fullpath, phandle); 377 node->fullpath, phandle, prop->name);
302 return; 378 return;
303 } 379 }
304 380
381 if (node->phandle && (node->phandle != phandle))
382 FAIL(c, "%s has %s property which replaces existing phandle information",
383 node->fullpath, prop->name);
384
305 other = get_node_by_phandle(root, phandle); 385 other = get_node_by_phandle(root, phandle);
306 if (other) { 386 if (other && (other != node)) {
307 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", 387 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
308 node->fullpath, phandle, other->fullpath); 388 node->fullpath, phandle, other->fullpath);
309 return; 389 return;
@@ -311,7 +391,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
311 391
312 node->phandle = phandle; 392 node->phandle = phandle;
313} 393}
314NODE_CHECK(explicit_phandles, NULL, ERROR); 394PROP_CHECK(explicit_phandles, NULL, ERROR);
315 395
316static void check_name_properties(struct check *c, struct node *root, 396static void check_name_properties(struct check *c, struct node *root,
317 struct node *node) 397 struct node *node)
@@ -549,6 +629,9 @@ static struct check *check_table[] = {
549 &duplicate_node_names, &duplicate_property_names, 629 &duplicate_node_names, &duplicate_property_names,
550 &node_name_chars, &node_name_format, &property_name_chars, 630 &node_name_chars, &node_name_format, &property_name_chars,
551 &name_is_string, &name_properties, 631 &name_is_string, &name_properties,
632
633 &duplicate_label,
634
552 &explicit_phandles, 635 &explicit_phandles,
553 &phandle_references, &path_references, 636 &phandle_references, &path_references,
554 637