diff options
Diffstat (limited to 'scripts/dtc/checks.c')
-rw-r--r-- | scripts/dtc/checks.c | 105 |
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 | } |
279 | PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); | 279 | PROP_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 | |||
288 | static 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 | |||
314 | static 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 | } | ||
322 | static 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 | } | ||
334 | CHECK(duplicate_label, NULL, check_duplicate_label_node, | ||
335 | check_duplicate_label_prop, NULL, ERROR); | ||
336 | |||
281 | static void check_explicit_phandles(struct check *c, struct node *root, | 337 | static 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 | } |
314 | NODE_CHECK(explicit_phandles, NULL, ERROR); | 394 | PROP_CHECK(explicit_phandles, NULL, ERROR); |
315 | 395 | ||
316 | static void check_name_properties(struct check *c, struct node *root, | 396 | static 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 | ||