"Das U-Boot" Source Tree
at master 1701 lines 46 kB view raw
1/* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 * USA 19 */ 20 21#include "dtc.h" 22 23#ifdef TRACE_CHECKS 24#define TRACE(c, ...) \ 25 do { \ 26 fprintf(stderr, "=== %s: ", (c)->name); \ 27 fprintf(stderr, __VA_ARGS__); \ 28 fprintf(stderr, "\n"); \ 29 } while (0) 30#else 31#define TRACE(c, fmt, ...) do { } while (0) 32#endif 33 34enum checkstatus { 35 UNCHECKED = 0, 36 PREREQ, 37 PASSED, 38 FAILED, 39}; 40 41struct check; 42 43typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); 44 45struct check { 46 const char *name; 47 check_fn fn; 48 void *data; 49 bool warn, error; 50 enum checkstatus status; 51 bool inprogress; 52 int num_prereqs; 53 struct check **prereq; 54}; 55 56#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \ 57 static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \ 58 static struct check nm_ = { \ 59 .name = #nm_, \ 60 .fn = (fn_), \ 61 .data = (d_), \ 62 .warn = (w_), \ 63 .error = (e_), \ 64 .status = UNCHECKED, \ 65 .num_prereqs = ARRAY_SIZE(nm_##_prereqs), \ 66 .prereq = nm_##_prereqs, \ 67 }; 68#define WARNING(nm_, fn_, d_, ...) \ 69 CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__) 70#define ERROR(nm_, fn_, d_, ...) \ 71 CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__) 72#define CHECK(nm_, fn_, d_, ...) \ 73 CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__) 74 75static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, 76 struct node *node, 77 struct property *prop, 78 const char *fmt, ...) 79{ 80 va_list ap; 81 va_start(ap, fmt); 82 83 if ((c->warn && (quiet < 1)) 84 || (c->error && (quiet < 2))) { 85 fprintf(stderr, "%s: %s (%s): ", 86 strcmp(dti->outname, "-") ? dti->outname : "<stdout>", 87 (c->error) ? "ERROR" : "Warning", c->name); 88 if (node) { 89 fprintf(stderr, "%s", node->fullpath); 90 if (prop) 91 fprintf(stderr, ":%s", prop->name); 92 fputs(": ", stderr); 93 } 94 vfprintf(stderr, fmt, ap); 95 fprintf(stderr, "\n"); 96 } 97 va_end(ap); 98} 99 100#define FAIL(c, dti, node, ...) \ 101 do { \ 102 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 103 (c)->status = FAILED; \ 104 check_msg((c), dti, node, NULL, __VA_ARGS__); \ 105 } while (0) 106 107#define FAIL_PROP(c, dti, node, prop, ...) \ 108 do { \ 109 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 110 (c)->status = FAILED; \ 111 check_msg((c), dti, node, prop, __VA_ARGS__); \ 112 } while (0) 113 114static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) 115{ 116 struct node *child; 117 118 TRACE(c, "%s", node->fullpath); 119 if (c->fn) 120 c->fn(c, dti, node); 121 122 for_each_child(node, child) 123 check_nodes_props(c, dti, child); 124} 125 126static bool run_check(struct check *c, struct dt_info *dti) 127{ 128 struct node *dt = dti->dt; 129 bool error = false; 130 int i; 131 132 assert(!c->inprogress); 133 134 if (c->status != UNCHECKED) 135 goto out; 136 137 c->inprogress = true; 138 139 for (i = 0; i < c->num_prereqs; i++) { 140 struct check *prq = c->prereq[i]; 141 error = error || run_check(prq, dti); 142 if (prq->status != PASSED) { 143 c->status = PREREQ; 144 check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", 145 c->prereq[i]->name); 146 } 147 } 148 149 if (c->status != UNCHECKED) 150 goto out; 151 152 check_nodes_props(c, dti, dt); 153 154 if (c->status == UNCHECKED) 155 c->status = PASSED; 156 157 TRACE(c, "\tCompleted, status %d", c->status); 158 159out: 160 c->inprogress = false; 161 if ((c->status != PASSED) && (c->error)) 162 error = true; 163 return error; 164} 165 166/* 167 * Utility check functions 168 */ 169 170/* A check which always fails, for testing purposes only */ 171static inline void check_always_fail(struct check *c, struct dt_info *dti, 172 struct node *node) 173{ 174 FAIL(c, dti, node, "always_fail check"); 175} 176CHECK(always_fail, check_always_fail, NULL); 177 178static void check_is_string(struct check *c, struct dt_info *dti, 179 struct node *node) 180{ 181 struct property *prop; 182 char *propname = c->data; 183 184 prop = get_property(node, propname); 185 if (!prop) 186 return; /* Not present, assumed ok */ 187 188 if (!data_is_one_string(prop->val)) 189 FAIL_PROP(c, dti, node, prop, "property is not a string"); 190} 191#define WARNING_IF_NOT_STRING(nm, propname) \ 192 WARNING(nm, check_is_string, (propname)) 193#define ERROR_IF_NOT_STRING(nm, propname) \ 194 ERROR(nm, check_is_string, (propname)) 195 196static void check_is_string_list(struct check *c, struct dt_info *dti, 197 struct node *node) 198{ 199 int rem, l; 200 struct property *prop; 201 char *propname = c->data; 202 char *str; 203 204 prop = get_property(node, propname); 205 if (!prop) 206 return; /* Not present, assumed ok */ 207 208 str = prop->val.val; 209 rem = prop->val.len; 210 while (rem > 0) { 211 l = strnlen(str, rem); 212 if (l == rem) { 213 FAIL_PROP(c, dti, node, prop, "property is not a string list"); 214 break; 215 } 216 rem -= l + 1; 217 str += l + 1; 218 } 219} 220#define WARNING_IF_NOT_STRING_LIST(nm, propname) \ 221 WARNING(nm, check_is_string_list, (propname)) 222#define ERROR_IF_NOT_STRING_LIST(nm, propname) \ 223 ERROR(nm, check_is_string_list, (propname)) 224 225static void check_is_cell(struct check *c, struct dt_info *dti, 226 struct node *node) 227{ 228 struct property *prop; 229 char *propname = c->data; 230 231 prop = get_property(node, propname); 232 if (!prop) 233 return; /* Not present, assumed ok */ 234 235 if (prop->val.len != sizeof(cell_t)) 236 FAIL_PROP(c, dti, node, prop, "property is not a single cell"); 237} 238#define WARNING_IF_NOT_CELL(nm, propname) \ 239 WARNING(nm, check_is_cell, (propname)) 240#define ERROR_IF_NOT_CELL(nm, propname) \ 241 ERROR(nm, check_is_cell, (propname)) 242 243/* 244 * Structural check functions 245 */ 246 247static void check_duplicate_node_names(struct check *c, struct dt_info *dti, 248 struct node *node) 249{ 250 struct node *child, *child2; 251 252 for_each_child(node, child) 253 for (child2 = child->next_sibling; 254 child2; 255 child2 = child2->next_sibling) 256 if (streq(child->name, child2->name)) 257 FAIL(c, dti, child2, "Duplicate node name"); 258} 259ERROR(duplicate_node_names, check_duplicate_node_names, NULL); 260 261static void check_duplicate_property_names(struct check *c, struct dt_info *dti, 262 struct node *node) 263{ 264 struct property *prop, *prop2; 265 266 for_each_property(node, prop) { 267 for (prop2 = prop->next; prop2; prop2 = prop2->next) { 268 if (prop2->deleted) 269 continue; 270 if (streq(prop->name, prop2->name)) 271 FAIL_PROP(c, dti, node, prop, "Duplicate property name"); 272 } 273 } 274} 275ERROR(duplicate_property_names, check_duplicate_property_names, NULL); 276 277#define LOWERCASE "abcdefghijklmnopqrstuvwxyz" 278#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 279#define DIGITS "0123456789" 280#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" 281#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" 282 283static void check_node_name_chars(struct check *c, struct dt_info *dti, 284 struct node *node) 285{ 286 int n = strspn(node->name, c->data); 287 288 if (n < strlen(node->name)) 289 FAIL(c, dti, node, "Bad character '%c' in node name", 290 node->name[n]); 291} 292ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); 293 294static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, 295 struct node *node) 296{ 297 int n = strspn(node->name, c->data); 298 299 if (n < node->basenamelen) 300 FAIL(c, dti, node, "Character '%c' not recommended in node name", 301 node->name[n]); 302} 303CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); 304 305static void check_node_name_format(struct check *c, struct dt_info *dti, 306 struct node *node) 307{ 308 if (strchr(get_unitname(node), '@')) 309 FAIL(c, dti, node, "multiple '@' characters in node name"); 310} 311ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); 312 313static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, 314 struct node *node) 315{ 316 const char *unitname = get_unitname(node); 317 struct property *prop = get_property(node, "reg"); 318 319 if (get_subnode(node, "__overlay__")) { 320 /* HACK: Overlay fragments are a special case */ 321 return; 322 } 323 324 if (!prop) { 325 prop = get_property(node, "ranges"); 326 if (prop && !prop->val.len) 327 prop = NULL; 328 } 329 330 if (prop) { 331 if (!unitname[0]) 332 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); 333 } else { 334 if (unitname[0]) 335 FAIL(c, dti, node, "node has a unit name, but no reg property"); 336 } 337} 338WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); 339 340static void check_property_name_chars(struct check *c, struct dt_info *dti, 341 struct node *node) 342{ 343 struct property *prop; 344 345 for_each_property(node, prop) { 346 int n = strspn(prop->name, c->data); 347 348 if (n < strlen(prop->name)) 349 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", 350 prop->name[n]); 351 } 352} 353ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); 354 355static void check_property_name_chars_strict(struct check *c, 356 struct dt_info *dti, 357 struct node *node) 358{ 359 struct property *prop; 360 361 for_each_property(node, prop) { 362 const char *name = prop->name; 363 int n = strspn(name, c->data); 364 365 if (n == strlen(prop->name)) 366 continue; 367 368 /* Certain names are whitelisted */ 369 if (streq(name, "device_type")) 370 continue; 371 372 /* 373 * # is only allowed at the beginning of property names not counting 374 * the vendor prefix. 375 */ 376 if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { 377 name += n + 1; 378 n = strspn(name, c->data); 379 } 380 if (n < strlen(name)) 381 FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", 382 name[n]); 383 } 384} 385CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); 386 387#define DESCLABEL_FMT "%s%s%s%s%s" 388#define DESCLABEL_ARGS(node,prop,mark) \ 389 ((mark) ? "value of " : ""), \ 390 ((prop) ? "'" : ""), \ 391 ((prop) ? (prop)->name : ""), \ 392 ((prop) ? "' in " : ""), (node)->fullpath 393 394static void check_duplicate_label(struct check *c, struct dt_info *dti, 395 const char *label, struct node *node, 396 struct property *prop, struct marker *mark) 397{ 398 struct node *dt = dti->dt; 399 struct node *othernode = NULL; 400 struct property *otherprop = NULL; 401 struct marker *othermark = NULL; 402 403 othernode = get_node_by_label(dt, label); 404 405 if (!othernode) 406 otherprop = get_property_by_label(dt, label, &othernode); 407 if (!othernode) 408 othermark = get_marker_label(dt, label, &othernode, 409 &otherprop); 410 411 if (!othernode) 412 return; 413 414 if ((othernode != node) || (otherprop != prop) || (othermark != mark)) 415 FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT 416 " and " DESCLABEL_FMT, 417 label, DESCLABEL_ARGS(node, prop, mark), 418 DESCLABEL_ARGS(othernode, otherprop, othermark)); 419} 420 421static void check_duplicate_label_node(struct check *c, struct dt_info *dti, 422 struct node *node) 423{ 424 struct label *l; 425 struct property *prop; 426 427 for_each_label(node->labels, l) 428 check_duplicate_label(c, dti, l->label, node, NULL, NULL); 429 430 for_each_property(node, prop) { 431 struct marker *m = prop->val.markers; 432 433 for_each_label(prop->labels, l) 434 check_duplicate_label(c, dti, l->label, node, prop, NULL); 435 436 for_each_marker_of_type(m, LABEL) 437 check_duplicate_label(c, dti, m->ref, node, prop, m); 438 } 439} 440ERROR(duplicate_label, check_duplicate_label_node, NULL); 441 442static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, 443 struct node *node, const char *propname) 444{ 445 struct node *root = dti->dt; 446 struct property *prop; 447 struct marker *m; 448 cell_t phandle; 449 450 prop = get_property(node, propname); 451 if (!prop) 452 return 0; 453 454 if (prop->val.len != sizeof(cell_t)) { 455 FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", 456 prop->val.len, prop->name); 457 return 0; 458 } 459 460 m = prop->val.markers; 461 for_each_marker_of_type(m, REF_PHANDLE) { 462 assert(m->offset == 0); 463 if (node != get_node_by_ref(root, m->ref)) 464 /* "Set this node's phandle equal to some 465 * other node's phandle". That's nonsensical 466 * by construction. */ { 467 FAIL(c, dti, node, "%s is a reference to another node", 468 prop->name); 469 } 470 /* But setting this node's phandle equal to its own 471 * phandle is allowed - that means allocate a unique 472 * phandle for this node, even if it's not otherwise 473 * referenced. The value will be filled in later, so 474 * we treat it as having no phandle data for now. */ 475 return 0; 476 } 477 478 phandle = propval_cell(prop); 479 480 if ((phandle == 0) || (phandle == -1)) { 481 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", 482 phandle, prop->name); 483 return 0; 484 } 485 486 return phandle; 487} 488 489static void check_explicit_phandles(struct check *c, struct dt_info *dti, 490 struct node *node) 491{ 492 struct node *root = dti->dt; 493 struct node *other; 494 cell_t phandle, linux_phandle; 495 496 /* Nothing should have assigned phandles yet */ 497 assert(!node->phandle); 498 499 phandle = check_phandle_prop(c, dti, node, "phandle"); 500 501 linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); 502 503 if (!phandle && !linux_phandle) 504 /* No valid phandles; nothing further to check */ 505 return; 506 507 if (linux_phandle && phandle && (phandle != linux_phandle)) 508 FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" 509 " properties"); 510 511 if (linux_phandle && !phandle) 512 phandle = linux_phandle; 513 514 other = get_node_by_phandle(root, phandle); 515 if (other && (other != node)) { 516 FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", 517 phandle, other->fullpath); 518 return; 519 } 520 521 node->phandle = phandle; 522} 523ERROR(explicit_phandles, check_explicit_phandles, NULL); 524 525static void check_name_properties(struct check *c, struct dt_info *dti, 526 struct node *node) 527{ 528 struct property **pp, *prop = NULL; 529 530 for (pp = &node->proplist; *pp; pp = &((*pp)->next)) 531 if (streq((*pp)->name, "name")) { 532 prop = *pp; 533 break; 534 } 535 536 if (!prop) 537 return; /* No name property, that's fine */ 538 539 if ((prop->val.len != node->basenamelen+1) 540 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { 541 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" 542 " of base node name)", prop->val.val); 543 } else { 544 /* The name property is correct, and therefore redundant. 545 * Delete it */ 546 *pp = prop->next; 547 free(prop->name); 548 data_free(prop->val); 549 free(prop); 550 } 551} 552ERROR_IF_NOT_STRING(name_is_string, "name"); 553ERROR(name_properties, check_name_properties, NULL, &name_is_string); 554 555/* 556 * Reference fixup functions 557 */ 558 559static void fixup_phandle_references(struct check *c, struct dt_info *dti, 560 struct node *node) 561{ 562 struct node *dt = dti->dt; 563 struct property *prop; 564 565 for_each_property(node, prop) { 566 struct marker *m = prop->val.markers; 567 struct node *refnode; 568 cell_t phandle; 569 570 for_each_marker_of_type(m, REF_PHANDLE) { 571 assert(m->offset + sizeof(cell_t) <= prop->val.len); 572 573 refnode = get_node_by_ref(dt, m->ref); 574 if (! refnode) { 575 if (!(dti->dtsflags & DTSF_PLUGIN)) 576 FAIL(c, dti, node, "Reference to non-existent node or " 577 "label \"%s\"\n", m->ref); 578 else /* mark the entry as unresolved */ 579 *((fdt32_t *)(prop->val.val + m->offset)) = 580 cpu_to_fdt32(0xffffffff); 581 continue; 582 } 583 584 phandle = get_node_phandle(dt, refnode); 585 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 586 587 reference_node(refnode); 588 } 589 } 590} 591ERROR(phandle_references, fixup_phandle_references, NULL, 592 &duplicate_node_names, &explicit_phandles); 593 594static void fixup_path_references(struct check *c, struct dt_info *dti, 595 struct node *node) 596{ 597 struct node *dt = dti->dt; 598 struct property *prop; 599 600 for_each_property(node, prop) { 601 struct marker *m = prop->val.markers; 602 struct node *refnode; 603 char *path; 604 605 for_each_marker_of_type(m, REF_PATH) { 606 assert(m->offset <= prop->val.len); 607 608 refnode = get_node_by_ref(dt, m->ref); 609 if (!refnode) { 610 FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", 611 m->ref); 612 continue; 613 } 614 615 path = refnode->fullpath; 616 prop->val = data_insert_at_marker(prop->val, m, path, 617 strlen(path) + 1); 618 619 reference_node(refnode); 620 } 621 } 622} 623ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); 624 625static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti, 626 struct node *node) 627{ 628 if (node->omit_if_unused && !node->is_referenced) 629 delete_node(node); 630} 631ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references); 632 633/* 634 * Semantic checks 635 */ 636WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); 637WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); 638WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); 639 640WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); 641WARNING_IF_NOT_STRING(model_is_string, "model"); 642WARNING_IF_NOT_STRING(status_is_string, "status"); 643WARNING_IF_NOT_STRING(label_is_string, "label"); 644 645WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); 646 647static void check_names_is_string_list(struct check *c, struct dt_info *dti, 648 struct node *node) 649{ 650 struct property *prop; 651 652 for_each_property(node, prop) { 653 const char *s = strrchr(prop->name, '-'); 654 if (!s || !streq(s, "-names")) 655 continue; 656 657 c->data = prop->name; 658 check_is_string_list(c, dti, node); 659 } 660} 661WARNING(names_is_string_list, check_names_is_string_list, NULL); 662 663static void check_alias_paths(struct check *c, struct dt_info *dti, 664 struct node *node) 665{ 666 struct property *prop; 667 668 if (!streq(node->name, "aliases")) 669 return; 670 671 for_each_property(node, prop) { 672 if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { 673 FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", 674 prop->val.val); 675 continue; 676 } 677 if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) 678 FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); 679 } 680} 681WARNING(alias_paths, check_alias_paths, NULL); 682 683static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, 684 struct node *node) 685{ 686 struct property *prop; 687 688 node->addr_cells = -1; 689 node->size_cells = -1; 690 691 prop = get_property(node, "#address-cells"); 692 if (prop) 693 node->addr_cells = propval_cell(prop); 694 695 prop = get_property(node, "#size-cells"); 696 if (prop) 697 node->size_cells = propval_cell(prop); 698} 699WARNING(addr_size_cells, fixup_addr_size_cells, NULL, 700 &address_cells_is_cell, &size_cells_is_cell); 701 702#define node_addr_cells(n) \ 703 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) 704#define node_size_cells(n) \ 705 (((n)->size_cells == -1) ? 1 : (n)->size_cells) 706 707static void check_reg_format(struct check *c, struct dt_info *dti, 708 struct node *node) 709{ 710 struct property *prop; 711 int addr_cells, size_cells, entrylen; 712 713 prop = get_property(node, "reg"); 714 if (!prop) 715 return; /* No "reg", that's fine */ 716 717 if (!node->parent) { 718 FAIL(c, dti, node, "Root node has a \"reg\" property"); 719 return; 720 } 721 722 if (prop->val.len == 0) 723 FAIL_PROP(c, dti, node, prop, "property is empty"); 724 725 addr_cells = node_addr_cells(node->parent); 726 size_cells = node_size_cells(node->parent); 727 entrylen = (addr_cells + size_cells) * sizeof(cell_t); 728 729 if (!entrylen || (prop->val.len % entrylen) != 0) 730 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " 731 "(#address-cells == %d, #size-cells == %d)", 732 prop->val.len, addr_cells, size_cells); 733} 734WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); 735 736static void check_ranges_format(struct check *c, struct dt_info *dti, 737 struct node *node) 738{ 739 struct property *prop; 740 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; 741 742 prop = get_property(node, "ranges"); 743 if (!prop) 744 return; 745 746 if (!node->parent) { 747 FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); 748 return; 749 } 750 751 p_addr_cells = node_addr_cells(node->parent); 752 p_size_cells = node_size_cells(node->parent); 753 c_addr_cells = node_addr_cells(node); 754 c_size_cells = node_size_cells(node); 755 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); 756 757 if (prop->val.len == 0) { 758 if (p_addr_cells != c_addr_cells) 759 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 760 "#address-cells (%d) differs from %s (%d)", 761 c_addr_cells, node->parent->fullpath, 762 p_addr_cells); 763 if (p_size_cells != c_size_cells) 764 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 765 "#size-cells (%d) differs from %s (%d)", 766 c_size_cells, node->parent->fullpath, 767 p_size_cells); 768 } else if ((prop->val.len % entrylen) != 0) { 769 FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " 770 "(parent #address-cells == %d, child #address-cells == %d, " 771 "#size-cells == %d)", prop->val.len, 772 p_addr_cells, c_addr_cells, c_size_cells); 773 } 774} 775WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); 776 777static const struct bus_type pci_bus = { 778 .name = "PCI", 779}; 780 781static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) 782{ 783 struct property *prop; 784 cell_t *cells; 785 786 prop = get_property(node, "device_type"); 787 if (!prop || !streq(prop->val.val, "pci")) 788 return; 789 790 node->bus = &pci_bus; 791 792 if (!strprefixeq(node->name, node->basenamelen, "pci") && 793 !strprefixeq(node->name, node->basenamelen, "pcie")) 794 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); 795 796 prop = get_property(node, "ranges"); 797 if (!prop) 798 FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); 799 800 if (node_addr_cells(node) != 3) 801 FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); 802 if (node_size_cells(node) != 2) 803 FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); 804 805 prop = get_property(node, "bus-range"); 806 if (!prop) { 807 FAIL(c, dti, node, "missing bus-range for PCI bridge"); 808 return; 809 } 810 if (prop->val.len != (sizeof(cell_t) * 2)) { 811 FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); 812 return; 813 } 814 cells = (cell_t *)prop->val.val; 815 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) 816 FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); 817 if (fdt32_to_cpu(cells[1]) > 0xff) 818 FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); 819} 820WARNING(pci_bridge, check_pci_bridge, NULL, 821 &device_type_is_string, &addr_size_cells); 822 823static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) 824{ 825 struct property *prop; 826 unsigned int bus_num, min_bus, max_bus; 827 cell_t *cells; 828 829 if (!node->parent || (node->parent->bus != &pci_bus)) 830 return; 831 832 prop = get_property(node, "reg"); 833 if (!prop) 834 return; 835 836 cells = (cell_t *)prop->val.val; 837 bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; 838 839 prop = get_property(node->parent, "bus-range"); 840 if (!prop) { 841 min_bus = max_bus = 0; 842 } else { 843 cells = (cell_t *)prop->val.val; 844 min_bus = fdt32_to_cpu(cells[0]); 845 max_bus = fdt32_to_cpu(cells[0]); 846 } 847 if ((bus_num < min_bus) || (bus_num > max_bus)) 848 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", 849 bus_num, min_bus, max_bus); 850} 851WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge); 852 853static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) 854{ 855 struct property *prop; 856 const char *unitname = get_unitname(node); 857 char unit_addr[5]; 858 unsigned int dev, func, reg; 859 cell_t *cells; 860 861 if (!node->parent || (node->parent->bus != &pci_bus)) 862 return; 863 864 prop = get_property(node, "reg"); 865 if (!prop) { 866 FAIL(c, dti, node, "missing PCI reg property"); 867 return; 868 } 869 870 cells = (cell_t *)prop->val.val; 871 if (cells[1] || cells[2]) 872 FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); 873 874 reg = fdt32_to_cpu(cells[0]); 875 dev = (reg & 0xf800) >> 11; 876 func = (reg & 0x700) >> 8; 877 878 if (reg & 0xff000000) 879 FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); 880 if (reg & 0x000000ff) 881 FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); 882 883 if (func == 0) { 884 snprintf(unit_addr, sizeof(unit_addr), "%x", dev); 885 if (streq(unitname, unit_addr)) 886 return; 887 } 888 889 snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); 890 if (streq(unitname, unit_addr)) 891 return; 892 893 FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", 894 unit_addr); 895} 896WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge); 897 898static const struct bus_type simple_bus = { 899 .name = "simple-bus", 900}; 901 902static bool node_is_compatible(struct node *node, const char *compat) 903{ 904 struct property *prop; 905 const char *str, *end; 906 907 prop = get_property(node, "compatible"); 908 if (!prop) 909 return false; 910 911 for (str = prop->val.val, end = str + prop->val.len; str < end; 912 str += strnlen(str, end - str) + 1) { 913 if (strprefixeq(str, end - str, compat)) 914 return true; 915 } 916 return false; 917} 918 919static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 920{ 921 if (node_is_compatible(node, "simple-bus")) 922 node->bus = &simple_bus; 923} 924WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); 925 926static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 927{ 928 struct property *prop; 929 const char *unitname = get_unitname(node); 930 char unit_addr[17]; 931 unsigned int size; 932 uint64_t reg = 0; 933 cell_t *cells = NULL; 934 935 if (!node->parent || (node->parent->bus != &simple_bus)) 936 return; 937 938 prop = get_property(node, "reg"); 939 if (prop) 940 cells = (cell_t *)prop->val.val; 941 else { 942 prop = get_property(node, "ranges"); 943 if (prop && prop->val.len) 944 /* skip of child address */ 945 cells = ((cell_t *)prop->val.val) + node_addr_cells(node); 946 } 947 948 if (!cells) { 949 if (node->parent->parent && !(node->bus == &simple_bus)) 950 FAIL(c, dti, node, "missing or empty reg/ranges property"); 951 return; 952 } 953 954 size = node_addr_cells(node->parent); 955 while (size--) 956 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 957 958 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); 959 if (!streq(unitname, unit_addr)) 960 FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", 961 unit_addr); 962} 963WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge); 964 965static void check_unit_address_format(struct check *c, struct dt_info *dti, 966 struct node *node) 967{ 968 const char *unitname = get_unitname(node); 969 970 if (node->parent && node->parent->bus) 971 return; 972 973 if (!unitname[0]) 974 return; 975 976 if (!strncmp(unitname, "0x", 2)) { 977 FAIL(c, dti, node, "unit name should not have leading \"0x\""); 978 /* skip over 0x for next test */ 979 unitname += 2; 980 } 981 if (unitname[0] == '0' && isxdigit(unitname[1])) 982 FAIL(c, dti, node, "unit name should not have leading 0s"); 983} 984WARNING(unit_address_format, check_unit_address_format, NULL, 985 &node_name_format, &pci_bridge, &simple_bus_bridge); 986 987/* 988 * Style checks 989 */ 990static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, 991 struct node *node) 992{ 993 struct property *reg, *ranges; 994 995 if (!node->parent) 996 return; /* Ignore root node */ 997 998 reg = get_property(node, "reg"); 999 ranges = get_property(node, "ranges"); 1000 1001 if (!reg && !ranges) 1002 return; 1003 1004 if (node->parent->addr_cells == -1) 1005 FAIL(c, dti, node, "Relying on default #address-cells value"); 1006 1007 if (node->parent->size_cells == -1) 1008 FAIL(c, dti, node, "Relying on default #size-cells value"); 1009} 1010WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, 1011 &addr_size_cells); 1012 1013static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, 1014 struct node *node) 1015{ 1016 struct property *prop; 1017 struct node *child; 1018 bool has_reg = false; 1019 1020 if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) 1021 return; 1022 1023 if (get_property(node, "ranges") || !node->children) 1024 return; 1025 1026 for_each_child(node, child) { 1027 prop = get_property(child, "reg"); 1028 if (prop) 1029 has_reg = true; 1030 } 1031 1032 if (!has_reg) 1033 FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); 1034} 1035WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); 1036 1037static void check_unique_unit_address(struct check *c, struct dt_info *dti, 1038 struct node *node) 1039{ 1040 struct node *childa; 1041 1042 if (node->addr_cells < 0 || node->size_cells < 0) 1043 return; 1044 1045 if (!node->children) 1046 return; 1047 1048 for_each_child(node, childa) { 1049 struct node *childb; 1050 const char *addr_a = get_unitname(childa); 1051 1052 if (!strlen(addr_a)) 1053 continue; 1054 1055 for_each_child(node, childb) { 1056 const char *addr_b = get_unitname(childb); 1057 if (childa == childb) 1058 break; 1059 1060 if (streq(addr_a, addr_b)) 1061 FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath); 1062 } 1063 } 1064} 1065WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size); 1066 1067static void check_obsolete_chosen_interrupt_controller(struct check *c, 1068 struct dt_info *dti, 1069 struct node *node) 1070{ 1071 struct node *dt = dti->dt; 1072 struct node *chosen; 1073 struct property *prop; 1074 1075 if (node != dt) 1076 return; 1077 1078 chosen = get_node_by_path(dt, "/chosen"); 1079 if (!chosen) 1080 return; 1081 1082 prop = get_property(chosen, "interrupt-controller"); 1083 if (prop) 1084 FAIL_PROP(c, dti, node, prop, 1085 "/chosen has obsolete \"interrupt-controller\" property"); 1086} 1087WARNING(obsolete_chosen_interrupt_controller, 1088 check_obsolete_chosen_interrupt_controller, NULL); 1089 1090static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, 1091 struct node *node) 1092{ 1093 if (!streq(node->name, "chosen")) 1094 return; 1095 1096 if (node->parent != dti->dt) 1097 FAIL(c, dti, node, "chosen node must be at root node"); 1098} 1099WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); 1100 1101static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, 1102 struct node *node) 1103{ 1104 struct property *prop; 1105 1106 if (!streq(node->name, "chosen")) 1107 return; 1108 1109 prop = get_property(node, "bootargs"); 1110 if (!prop) 1111 return; 1112 1113 c->data = prop->name; 1114 check_is_string(c, dti, node); 1115} 1116WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); 1117 1118static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, 1119 struct node *node) 1120{ 1121 struct property *prop; 1122 1123 if (!streq(node->name, "chosen")) 1124 return; 1125 1126 prop = get_property(node, "stdout-path"); 1127 if (!prop) { 1128 prop = get_property(node, "linux,stdout-path"); 1129 if (!prop) 1130 return; 1131 FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); 1132 } 1133 1134 c->data = prop->name; 1135 check_is_string(c, dti, node); 1136} 1137WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); 1138 1139struct provider { 1140 const char *prop_name; 1141 const char *cell_name; 1142 bool optional; 1143}; 1144 1145static void check_property_phandle_args(struct check *c, 1146 struct dt_info *dti, 1147 struct node *node, 1148 struct property *prop, 1149 const struct provider *provider) 1150{ 1151 struct node *root = dti->dt; 1152 int cell, cellsize = 0; 1153 1154 if (prop->val.len % sizeof(cell_t)) { 1155 FAIL_PROP(c, dti, node, prop, 1156 "property size (%d) is invalid, expected multiple of %zu", 1157 prop->val.len, sizeof(cell_t)); 1158 return; 1159 } 1160 1161 for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { 1162 struct node *provider_node; 1163 struct property *cellprop; 1164 int phandle; 1165 1166 phandle = propval_cell_n(prop, cell); 1167 /* 1168 * Some bindings use a cell value 0 or -1 to skip over optional 1169 * entries when each index position has a specific definition. 1170 */ 1171 if (phandle == 0 || phandle == -1) { 1172 /* Give up if this is an overlay with external references */ 1173 if (dti->dtsflags & DTSF_PLUGIN) 1174 break; 1175 1176 cellsize = 0; 1177 continue; 1178 } 1179 1180 /* If we have markers, verify the current cell is a phandle */ 1181 if (prop->val.markers) { 1182 struct marker *m = prop->val.markers; 1183 for_each_marker_of_type(m, REF_PHANDLE) { 1184 if (m->offset == (cell * sizeof(cell_t))) 1185 break; 1186 } 1187 if (!m) 1188 FAIL_PROP(c, dti, node, prop, 1189 "cell %d is not a phandle reference", 1190 cell); 1191 } 1192 1193 provider_node = get_node_by_phandle(root, phandle); 1194 if (!provider_node) { 1195 FAIL_PROP(c, dti, node, prop, 1196 "Could not get phandle node for (cell %d)", 1197 cell); 1198 break; 1199 } 1200 1201 cellprop = get_property(provider_node, provider->cell_name); 1202 if (cellprop) { 1203 cellsize = propval_cell(cellprop); 1204 } else if (provider->optional) { 1205 cellsize = 0; 1206 } else { 1207 FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", 1208 provider->cell_name, 1209 provider_node->fullpath, 1210 prop->name, cell); 1211 break; 1212 } 1213 1214 if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { 1215 FAIL_PROP(c, dti, node, prop, 1216 "property size (%d) too small for cell size %d", 1217 prop->val.len, cellsize); 1218 } 1219 } 1220} 1221 1222static void check_provider_cells_property(struct check *c, 1223 struct dt_info *dti, 1224 struct node *node) 1225{ 1226 struct provider *provider = c->data; 1227 struct property *prop; 1228 1229 prop = get_property(node, provider->prop_name); 1230 if (!prop) 1231 return; 1232 1233 check_property_phandle_args(c, dti, node, prop, provider); 1234} 1235#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ 1236 static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ 1237 WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); 1238 1239WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); 1240WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); 1241WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); 1242WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); 1243WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); 1244WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); 1245WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); 1246WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); 1247WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); 1248WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); 1249WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); 1250WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); 1251WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); 1252WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); 1253WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); 1254WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); 1255 1256static bool prop_is_gpio(struct property *prop) 1257{ 1258 char *str; 1259 1260 /* 1261 * *-gpios and *-gpio can appear in property names, 1262 * so skip over any false matches (only one known ATM) 1263 */ 1264 if (strstr(prop->name, "nr-gpio")) 1265 return false; 1266 1267 str = strrchr(prop->name, '-'); 1268 if (str) 1269 str++; 1270 else 1271 str = prop->name; 1272 if (!(streq(str, "gpios") || streq(str, "gpio"))) 1273 return false; 1274 1275 return true; 1276} 1277 1278static void check_gpios_property(struct check *c, 1279 struct dt_info *dti, 1280 struct node *node) 1281{ 1282 struct property *prop; 1283 1284 /* Skip GPIO hog nodes which have 'gpios' property */ 1285 if (get_property(node, "gpio-hog")) 1286 return; 1287 1288 for_each_property(node, prop) { 1289 struct provider provider; 1290 1291 if (!prop_is_gpio(prop)) 1292 continue; 1293 1294 provider.prop_name = prop->name; 1295 provider.cell_name = "#gpio-cells"; 1296 provider.optional = false; 1297 check_property_phandle_args(c, dti, node, prop, &provider); 1298 } 1299 1300} 1301WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); 1302 1303static void check_deprecated_gpio_property(struct check *c, 1304 struct dt_info *dti, 1305 struct node *node) 1306{ 1307 struct property *prop; 1308 1309 for_each_property(node, prop) { 1310 char *str; 1311 1312 if (!prop_is_gpio(prop)) 1313 continue; 1314 1315 str = strstr(prop->name, "gpio"); 1316 if (!streq(str, "gpio")) 1317 continue; 1318 1319 FAIL_PROP(c, dti, node, prop, 1320 "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); 1321 } 1322 1323} 1324CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); 1325 1326static bool node_is_interrupt_provider(struct node *node) 1327{ 1328 struct property *prop; 1329 1330 prop = get_property(node, "interrupt-controller"); 1331 if (prop) 1332 return true; 1333 1334 prop = get_property(node, "interrupt-map"); 1335 if (prop) 1336 return true; 1337 1338 return false; 1339} 1340static void check_interrupts_property(struct check *c, 1341 struct dt_info *dti, 1342 struct node *node) 1343{ 1344 struct node *root = dti->dt; 1345 struct node *irq_node = NULL, *parent = node; 1346 struct property *irq_prop, *prop = NULL; 1347 int irq_cells, phandle; 1348 1349 irq_prop = get_property(node, "interrupts"); 1350 if (!irq_prop) 1351 return; 1352 1353 if (irq_prop->val.len % sizeof(cell_t)) 1354 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", 1355 irq_prop->val.len, sizeof(cell_t)); 1356 1357 while (parent && !prop) { 1358 if (parent != node && node_is_interrupt_provider(parent)) { 1359 irq_node = parent; 1360 break; 1361 } 1362 1363 prop = get_property(parent, "interrupt-parent"); 1364 if (prop) { 1365 phandle = propval_cell(prop); 1366 /* Give up if this is an overlay with external references */ 1367 if ((phandle == 0 || phandle == -1) && 1368 (dti->dtsflags & DTSF_PLUGIN)) 1369 return; 1370 1371 irq_node = get_node_by_phandle(root, phandle); 1372 if (!irq_node) { 1373 FAIL_PROP(c, dti, parent, prop, "Bad phandle"); 1374 return; 1375 } 1376 if (!node_is_interrupt_provider(irq_node)) 1377 FAIL(c, dti, irq_node, 1378 "Missing interrupt-controller or interrupt-map property"); 1379 1380 break; 1381 } 1382 1383 parent = parent->parent; 1384 } 1385 1386 if (!irq_node) { 1387 FAIL(c, dti, node, "Missing interrupt-parent"); 1388 return; 1389 } 1390 1391 prop = get_property(irq_node, "#interrupt-cells"); 1392 if (!prop) { 1393 FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); 1394 return; 1395 } 1396 1397 irq_cells = propval_cell(prop); 1398 if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { 1399 FAIL_PROP(c, dti, node, prop, 1400 "size is (%d), expected multiple of %d", 1401 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); 1402 } 1403} 1404WARNING(interrupts_property, check_interrupts_property, &phandle_references); 1405 1406static const struct bus_type graph_port_bus = { 1407 .name = "graph-port", 1408}; 1409 1410static const struct bus_type graph_ports_bus = { 1411 .name = "graph-ports", 1412}; 1413 1414static void check_graph_nodes(struct check *c, struct dt_info *dti, 1415 struct node *node) 1416{ 1417 struct node *child; 1418 1419 for_each_child(node, child) { 1420 if (!(strprefixeq(child->name, child->basenamelen, "endpoint") || 1421 get_property(child, "remote-endpoint"))) 1422 continue; 1423 1424 node->bus = &graph_port_bus; 1425 1426 /* The parent of 'port' nodes can be either 'ports' or a device */ 1427 if (!node->parent->bus && 1428 (streq(node->parent->name, "ports") || get_property(node, "reg"))) 1429 node->parent->bus = &graph_ports_bus; 1430 1431 break; 1432 } 1433 1434} 1435WARNING(graph_nodes, check_graph_nodes, NULL); 1436 1437static void check_graph_child_address(struct check *c, struct dt_info *dti, 1438 struct node *node) 1439{ 1440 int cnt = 0; 1441 struct node *child; 1442 1443 if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) 1444 return; 1445 1446 for_each_child(node, child) { 1447 struct property *prop = get_property(child, "reg"); 1448 1449 /* No error if we have any non-zero unit address */ 1450 if (prop && propval_cell(prop) != 0) 1451 return; 1452 1453 cnt++; 1454 } 1455 1456 if (cnt == 1 && node->addr_cells != -1) 1457 FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary", 1458 node->children->name); 1459} 1460WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes); 1461 1462static void check_graph_reg(struct check *c, struct dt_info *dti, 1463 struct node *node) 1464{ 1465 char unit_addr[9]; 1466 const char *unitname = get_unitname(node); 1467 struct property *prop; 1468 1469 prop = get_property(node, "reg"); 1470 if (!prop || !unitname) 1471 return; 1472 1473 if (!(prop->val.val && prop->val.len == sizeof(cell_t))) { 1474 FAIL(c, dti, node, "graph node malformed 'reg' property"); 1475 return; 1476 } 1477 1478 snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop)); 1479 if (!streq(unitname, unit_addr)) 1480 FAIL(c, dti, node, "graph node unit address error, expected \"%s\"", 1481 unit_addr); 1482 1483 if (node->parent->addr_cells != 1) 1484 FAIL_PROP(c, dti, node, get_property(node, "#address-cells"), 1485 "graph node '#address-cells' is %d, must be 1", 1486 node->parent->addr_cells); 1487 if (node->parent->size_cells != 0) 1488 FAIL_PROP(c, dti, node, get_property(node, "#size-cells"), 1489 "graph node '#size-cells' is %d, must be 0", 1490 node->parent->size_cells); 1491} 1492 1493static void check_graph_port(struct check *c, struct dt_info *dti, 1494 struct node *node) 1495{ 1496 if (node->bus != &graph_port_bus) 1497 return; 1498 1499 if (!strprefixeq(node->name, node->basenamelen, "port")) 1500 FAIL(c, dti, node, "graph port node name should be 'port'"); 1501 1502 check_graph_reg(c, dti, node); 1503} 1504WARNING(graph_port, check_graph_port, NULL, &graph_nodes); 1505 1506static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, 1507 struct node *endpoint) 1508{ 1509 int phandle; 1510 struct node *node; 1511 struct property *prop; 1512 1513 prop = get_property(endpoint, "remote-endpoint"); 1514 if (!prop) 1515 return NULL; 1516 1517 phandle = propval_cell(prop); 1518 /* Give up if this is an overlay with external references */ 1519 if (phandle == 0 || phandle == -1) 1520 return NULL; 1521 1522 node = get_node_by_phandle(dti->dt, phandle); 1523 if (!node) 1524 FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid"); 1525 1526 return node; 1527} 1528 1529static void check_graph_endpoint(struct check *c, struct dt_info *dti, 1530 struct node *node) 1531{ 1532 struct node *remote_node; 1533 1534 if (!node->parent || node->parent->bus != &graph_port_bus) 1535 return; 1536 1537 if (!strprefixeq(node->name, node->basenamelen, "endpoint")) 1538 FAIL(c, dti, node, "graph endpont node name should be 'endpoint'"); 1539 1540 check_graph_reg(c, dti, node); 1541 1542 remote_node = get_remote_endpoint(c, dti, node); 1543 if (!remote_node) 1544 return; 1545 1546 if (get_remote_endpoint(c, dti, remote_node) != node) 1547 FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional", 1548 remote_node->fullpath); 1549} 1550WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes); 1551 1552static struct check *check_table[] = { 1553 &duplicate_node_names, &duplicate_property_names, 1554 &node_name_chars, &node_name_format, &property_name_chars, 1555 &name_is_string, &name_properties, 1556 1557 &duplicate_label, 1558 1559 &explicit_phandles, 1560 &phandle_references, &path_references, 1561 &omit_unused_nodes, 1562 1563 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, 1564 &device_type_is_string, &model_is_string, &status_is_string, 1565 &label_is_string, 1566 1567 &compatible_is_string_list, &names_is_string_list, 1568 1569 &property_name_chars_strict, 1570 &node_name_chars_strict, 1571 1572 &addr_size_cells, &reg_format, &ranges_format, 1573 1574 &unit_address_vs_reg, 1575 &unit_address_format, 1576 1577 &pci_bridge, 1578 &pci_device_reg, 1579 &pci_device_bus_num, 1580 1581 &simple_bus_bridge, 1582 &simple_bus_reg, 1583 1584 &avoid_default_addr_size, 1585 &avoid_unnecessary_addr_size, 1586 &unique_unit_address, 1587 &obsolete_chosen_interrupt_controller, 1588 &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, 1589 1590 &clocks_property, 1591 &cooling_device_property, 1592 &dmas_property, 1593 &hwlocks_property, 1594 &interrupts_extended_property, 1595 &io_channels_property, 1596 &iommus_property, 1597 &mboxes_property, 1598 &msi_parent_property, 1599 &mux_controls_property, 1600 &phys_property, 1601 &power_domains_property, 1602 &pwms_property, 1603 &resets_property, 1604 &sound_dai_property, 1605 &thermal_sensors_property, 1606 1607 &deprecated_gpio_property, 1608 &gpios_property, 1609 &interrupts_property, 1610 1611 &alias_paths, 1612 1613 &graph_nodes, &graph_child_address, &graph_port, &graph_endpoint, 1614 1615 &always_fail, 1616}; 1617 1618static void enable_warning_error(struct check *c, bool warn, bool error) 1619{ 1620 int i; 1621 1622 /* Raising level, also raise it for prereqs */ 1623 if ((warn && !c->warn) || (error && !c->error)) 1624 for (i = 0; i < c->num_prereqs; i++) 1625 enable_warning_error(c->prereq[i], warn, error); 1626 1627 c->warn = c->warn || warn; 1628 c->error = c->error || error; 1629} 1630 1631static void disable_warning_error(struct check *c, bool warn, bool error) 1632{ 1633 int i; 1634 1635 /* Lowering level, also lower it for things this is the prereq 1636 * for */ 1637 if ((warn && c->warn) || (error && c->error)) { 1638 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1639 struct check *cc = check_table[i]; 1640 int j; 1641 1642 for (j = 0; j < cc->num_prereqs; j++) 1643 if (cc->prereq[j] == c) 1644 disable_warning_error(cc, warn, error); 1645 } 1646 } 1647 1648 c->warn = c->warn && !warn; 1649 c->error = c->error && !error; 1650} 1651 1652void parse_checks_option(bool warn, bool error, const char *arg) 1653{ 1654 int i; 1655 const char *name = arg; 1656 bool enable = true; 1657 1658 if ((strncmp(arg, "no-", 3) == 0) 1659 || (strncmp(arg, "no_", 3) == 0)) { 1660 name = arg + 3; 1661 enable = false; 1662 } 1663 1664 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1665 struct check *c = check_table[i]; 1666 1667 if (streq(c->name, name)) { 1668 if (enable) 1669 enable_warning_error(c, warn, error); 1670 else 1671 disable_warning_error(c, warn, error); 1672 return; 1673 } 1674 } 1675 1676 die("Unrecognized check name \"%s\"\n", name); 1677} 1678 1679void process_checks(bool force, struct dt_info *dti) 1680{ 1681 int i; 1682 int error = 0; 1683 1684 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1685 struct check *c = check_table[i]; 1686 1687 if (c->warn || c->error) 1688 error = error || run_check(c, dti); 1689 } 1690 1691 if (error) { 1692 if (!force) { 1693 fprintf(stderr, "ERROR: Input tree has errors, aborting " 1694 "(use -f to force output)\n"); 1695 exit(2); 1696 } else if (quiet < 3) { 1697 fprintf(stderr, "Warning: Input tree has errors, " 1698 "output forced\n"); 1699 } 1700 } 1701}