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