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 34 enum checkstatus { 35 UNCHECKED = 0, 36 PREREQ, 37 PASSED, 38 FAILED, 39 }; 40 41 struct check; 42 43 typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); 44 45 struct 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 75 static 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 115 static 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 127 static 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 160 out: 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 */ 172 static 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 } 177 CHECK(always_fail, check_always_fail, NULL); 178 179 static 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 197 static 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 226 static 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 248 static 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, node, "Duplicate node name"); 259 } 260 ERROR(duplicate_node_names, check_duplicate_node_names, NULL); 261 262 static 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 } 276 ERROR(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 284 static 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 } 293 ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); 294 295 static 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 } 304 CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); 305 306 static 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 } 312 ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); 313 314 static 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 (!prop) { 321 prop = get_property(node, "ranges"); 322 if (prop && !prop->val.len) 323 prop = NULL; 324 } 325 326 if (prop) { 327 if (!unitname[0]) 328 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); 329 } else { 330 if (unitname[0]) 331 FAIL(c, dti, node, "node has a unit name, but no reg property"); 332 } 333 } 334 WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); 335 336 static void check_property_name_chars(struct check *c, struct dt_info *dti, 337 struct node *node) 338 { 339 struct property *prop; 340 341 for_each_property(node, prop) { 342 int n = strspn(prop->name, c->data); 343 344 if (n < strlen(prop->name)) 345 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", 346 prop->name[n]); 347 } 348 } 349 ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); 350 351 static void check_property_name_chars_strict(struct check *c, 352 struct dt_info *dti, 353 struct node *node) 354 { 355 struct property *prop; 356 357 for_each_property(node, prop) { 358 const char *name = prop->name; 359 int n = strspn(name, c->data); 360 361 if (n == strlen(prop->name)) 362 continue; 363 364 /* Certain names are whitelisted */ 365 if (streq(name, "device_type")) 366 continue; 367 368 /* 369 * # is only allowed at the beginning of property names not counting 370 * the vendor prefix. 371 */ 372 if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { 373 name += n + 1; 374 n = strspn(name, c->data); 375 } 376 if (n < strlen(name)) 377 FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", 378 name[n]); 379 } 380 } 381 CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); 382 383 #define DESCLABEL_FMT "%s%s%s%s%s" 384 #define DESCLABEL_ARGS(node,prop,mark) \ 385 ((mark) ? "value of " : ""), \ 386 ((prop) ? "'" : ""), \ 387 ((prop) ? (prop)->name : ""), \ 388 ((prop) ? "' in " : ""), (node)->fullpath 389 390 static void check_duplicate_label(struct check *c, struct dt_info *dti, 391 const char *label, struct node *node, 392 struct property *prop, struct marker *mark) 393 { 394 struct node *dt = dti->dt; 395 struct node *othernode = NULL; 396 struct property *otherprop = NULL; 397 struct marker *othermark = NULL; 398 399 othernode = get_node_by_label(dt, label); 400 401 if (!othernode) 402 otherprop = get_property_by_label(dt, label, &othernode); 403 if (!othernode) 404 othermark = get_marker_label(dt, label, &othernode, 405 &otherprop); 406 407 if (!othernode) 408 return; 409 410 if ((othernode != node) || (otherprop != prop) || (othermark != mark)) 411 FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT 412 " and " DESCLABEL_FMT, 413 label, DESCLABEL_ARGS(node, prop, mark), 414 DESCLABEL_ARGS(othernode, otherprop, othermark)); 415 } 416 417 static void check_duplicate_label_node(struct check *c, struct dt_info *dti, 418 struct node *node) 419 { 420 struct label *l; 421 struct property *prop; 422 423 for_each_label(node->labels, l) 424 check_duplicate_label(c, dti, l->label, node, NULL, NULL); 425 426 for_each_property(node, prop) { 427 struct marker *m = prop->val.markers; 428 429 for_each_label(prop->labels, l) 430 check_duplicate_label(c, dti, l->label, node, prop, NULL); 431 432 for_each_marker_of_type(m, LABEL) 433 check_duplicate_label(c, dti, m->ref, node, prop, m); 434 } 435 } 436 ERROR(duplicate_label, check_duplicate_label_node, NULL); 437 438 static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, 439 struct node *node, const char *propname) 440 { 441 struct node *root = dti->dt; 442 struct property *prop; 443 struct marker *m; 444 cell_t phandle; 445 446 prop = get_property(node, propname); 447 if (!prop) 448 return 0; 449 450 if (prop->val.len != sizeof(cell_t)) { 451 FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", 452 prop->val.len, prop->name); 453 return 0; 454 } 455 456 m = prop->val.markers; 457 for_each_marker_of_type(m, REF_PHANDLE) { 458 assert(m->offset == 0); 459 if (node != get_node_by_ref(root, m->ref)) 460 /* "Set this node's phandle equal to some 461 * other node's phandle". That's nonsensical 462 * by construction. */ { 463 FAIL(c, dti, node, "%s is a reference to another node", 464 prop->name); 465 } 466 /* But setting this node's phandle equal to its own 467 * phandle is allowed - that means allocate a unique 468 * phandle for this node, even if it's not otherwise 469 * referenced. The value will be filled in later, so 470 * we treat it as having no phandle data for now. */ 471 return 0; 472 } 473 474 phandle = propval_cell(prop); 475 476 if ((phandle == 0) || (phandle == -1)) { 477 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", 478 phandle, prop->name); 479 return 0; 480 } 481 482 return phandle; 483 } 484 485 static void check_explicit_phandles(struct check *c, struct dt_info *dti, 486 struct node *node) 487 { 488 struct node *root = dti->dt; 489 struct node *other; 490 cell_t phandle, linux_phandle; 491 492 /* Nothing should have assigned phandles yet */ 493 assert(!node->phandle); 494 495 phandle = check_phandle_prop(c, dti, node, "phandle"); 496 497 linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); 498 499 if (!phandle && !linux_phandle) 500 /* No valid phandles; nothing further to check */ 501 return; 502 503 if (linux_phandle && phandle && (phandle != linux_phandle)) 504 FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" 505 " properties"); 506 507 if (linux_phandle && !phandle) 508 phandle = linux_phandle; 509 510 other = get_node_by_phandle(root, phandle); 511 if (other && (other != node)) { 512 FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", 513 phandle, other->fullpath); 514 return; 515 } 516 517 node->phandle = phandle; 518 } 519 ERROR(explicit_phandles, check_explicit_phandles, NULL); 520 521 static void check_name_properties(struct check *c, struct dt_info *dti, 522 struct node *node) 523 { 524 struct property **pp, *prop = NULL; 525 526 for (pp = &node->proplist; *pp; pp = &((*pp)->next)) 527 if (streq((*pp)->name, "name")) { 528 prop = *pp; 529 break; 530 } 531 532 if (!prop) 533 return; /* No name property, that's fine */ 534 535 if ((prop->val.len != node->basenamelen+1) 536 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { 537 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" 538 " of base node name)", prop->val.val); 539 } else { 540 /* The name property is correct, and therefore redundant. 541 * Delete it */ 542 *pp = prop->next; 543 free(prop->name); 544 data_free(prop->val); 545 free(prop); 546 } 547 } 548 ERROR_IF_NOT_STRING(name_is_string, "name"); 549 ERROR(name_properties, check_name_properties, NULL, &name_is_string); 550 551 /* 552 * Reference fixup functions 553 */ 554 555 static void fixup_phandle_references(struct check *c, struct dt_info *dti, 556 struct node *node) 557 { 558 struct node *dt = dti->dt; 559 struct property *prop; 560 561 for_each_property(node, prop) { 562 struct marker *m = prop->val.markers; 563 struct node *refnode; 564 cell_t phandle; 565 566 for_each_marker_of_type(m, REF_PHANDLE) { 567 assert(m->offset + sizeof(cell_t) <= prop->val.len); 568 569 refnode = get_node_by_ref(dt, m->ref); 570 if (! refnode) { 571 if (!(dti->dtsflags & DTSF_PLUGIN)) 572 FAIL(c, dti, node, "Reference to non-existent node or " 573 "label \"%s\"\n", m->ref); 574 else /* mark the entry as unresolved */ 575 *((fdt32_t *)(prop->val.val + m->offset)) = 576 cpu_to_fdt32(0xffffffff); 577 continue; 578 } 579 580 phandle = get_node_phandle(dt, refnode); 581 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 582 } 583 } 584 } 585 ERROR(phandle_references, fixup_phandle_references, NULL, 586 &duplicate_node_names, &explicit_phandles); 587 588 static void fixup_path_references(struct check *c, struct dt_info *dti, 589 struct node *node) 590 { 591 struct node *dt = dti->dt; 592 struct property *prop; 593 594 for_each_property(node, prop) { 595 struct marker *m = prop->val.markers; 596 struct node *refnode; 597 char *path; 598 599 for_each_marker_of_type(m, REF_PATH) { 600 assert(m->offset <= prop->val.len); 601 602 refnode = get_node_by_ref(dt, m->ref); 603 if (!refnode) { 604 FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", 605 m->ref); 606 continue; 607 } 608 609 path = refnode->fullpath; 610 prop->val = data_insert_at_marker(prop->val, m, path, 611 strlen(path) + 1); 612 } 613 } 614 } 615 ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); 616 617 /* 618 * Semantic checks 619 */ 620 WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); 621 WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); 622 WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); 623 624 WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); 625 WARNING_IF_NOT_STRING(model_is_string, "model"); 626 WARNING_IF_NOT_STRING(status_is_string, "status"); 627 WARNING_IF_NOT_STRING(label_is_string, "label"); 628 629 WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); 630 631 static void check_names_is_string_list(struct check *c, struct dt_info *dti, 632 struct node *node) 633 { 634 struct property *prop; 635 636 for_each_property(node, prop) { 637 const char *s = strrchr(prop->name, '-'); 638 if (!s || !streq(s, "-names")) 639 continue; 640 641 c->data = prop->name; 642 check_is_string_list(c, dti, node); 643 } 644 } 645 WARNING(names_is_string_list, check_names_is_string_list, NULL); 646 647 static void check_alias_paths(struct check *c, struct dt_info *dti, 648 struct node *node) 649 { 650 struct property *prop; 651 652 if (!streq(node->name, "aliases")) 653 return; 654 655 for_each_property(node, prop) { 656 if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { 657 FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", 658 prop->val.val); 659 continue; 660 } 661 if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) 662 FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); 663 } 664 } 665 WARNING(alias_paths, check_alias_paths, NULL); 666 667 static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, 668 struct node *node) 669 { 670 struct property *prop; 671 672 node->addr_cells = -1; 673 node->size_cells = -1; 674 675 prop = get_property(node, "#address-cells"); 676 if (prop) 677 node->addr_cells = propval_cell(prop); 678 679 prop = get_property(node, "#size-cells"); 680 if (prop) 681 node->size_cells = propval_cell(prop); 682 } 683 WARNING(addr_size_cells, fixup_addr_size_cells, NULL, 684 &address_cells_is_cell, &size_cells_is_cell); 685 686 #define node_addr_cells(n) \ 687 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) 688 #define node_size_cells(n) \ 689 (((n)->size_cells == -1) ? 1 : (n)->size_cells) 690 691 static void check_reg_format(struct check *c, struct dt_info *dti, 692 struct node *node) 693 { 694 struct property *prop; 695 int addr_cells, size_cells, entrylen; 696 697 prop = get_property(node, "reg"); 698 if (!prop) 699 return; /* No "reg", that's fine */ 700 701 if (!node->parent) { 702 FAIL(c, dti, node, "Root node has a \"reg\" property"); 703 return; 704 } 705 706 if (prop->val.len == 0) 707 FAIL_PROP(c, dti, node, prop, "property is empty"); 708 709 addr_cells = node_addr_cells(node->parent); 710 size_cells = node_size_cells(node->parent); 711 entrylen = (addr_cells + size_cells) * sizeof(cell_t); 712 713 if (!entrylen || (prop->val.len % entrylen) != 0) 714 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " 715 "(#address-cells == %d, #size-cells == %d)", 716 prop->val.len, addr_cells, size_cells); 717 } 718 WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); 719 720 static void check_ranges_format(struct check *c, struct dt_info *dti, 721 struct node *node) 722 { 723 struct property *prop; 724 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; 725 726 prop = get_property(node, "ranges"); 727 if (!prop) 728 return; 729 730 if (!node->parent) { 731 FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); 732 return; 733 } 734 735 p_addr_cells = node_addr_cells(node->parent); 736 p_size_cells = node_size_cells(node->parent); 737 c_addr_cells = node_addr_cells(node); 738 c_size_cells = node_size_cells(node); 739 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); 740 741 if (prop->val.len == 0) { 742 if (p_addr_cells != c_addr_cells) 743 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 744 "#address-cells (%d) differs from %s (%d)", 745 c_addr_cells, node->parent->fullpath, 746 p_addr_cells); 747 if (p_size_cells != c_size_cells) 748 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 749 "#size-cells (%d) differs from %s (%d)", 750 c_size_cells, node->parent->fullpath, 751 p_size_cells); 752 } else if ((prop->val.len % entrylen) != 0) { 753 FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " 754 "(parent #address-cells == %d, child #address-cells == %d, " 755 "#size-cells == %d)", prop->val.len, 756 p_addr_cells, c_addr_cells, c_size_cells); 757 } 758 } 759 WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); 760 761 static const struct bus_type pci_bus = { 762 .name = "PCI", 763 }; 764 765 static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) 766 { 767 struct property *prop; 768 cell_t *cells; 769 770 prop = get_property(node, "device_type"); 771 if (!prop || !streq(prop->val.val, "pci")) 772 return; 773 774 node->bus = &pci_bus; 775 776 if (!strprefixeq(node->name, node->basenamelen, "pci") && 777 !strprefixeq(node->name, node->basenamelen, "pcie")) 778 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); 779 780 prop = get_property(node, "ranges"); 781 if (!prop) 782 FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); 783 784 if (node_addr_cells(node) != 3) 785 FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); 786 if (node_size_cells(node) != 2) 787 FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); 788 789 prop = get_property(node, "bus-range"); 790 if (!prop) { 791 FAIL(c, dti, node, "missing bus-range for PCI bridge"); 792 return; 793 } 794 if (prop->val.len != (sizeof(cell_t) * 2)) { 795 FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); 796 return; 797 } 798 cells = (cell_t *)prop->val.val; 799 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) 800 FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); 801 if (fdt32_to_cpu(cells[1]) > 0xff) 802 FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); 803 } 804 WARNING(pci_bridge, check_pci_bridge, NULL, 805 &device_type_is_string, &addr_size_cells); 806 807 static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) 808 { 809 struct property *prop; 810 unsigned int bus_num, min_bus, max_bus; 811 cell_t *cells; 812 813 if (!node->parent || (node->parent->bus != &pci_bus)) 814 return; 815 816 prop = get_property(node, "reg"); 817 if (!prop) 818 return; 819 820 cells = (cell_t *)prop->val.val; 821 bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; 822 823 prop = get_property(node->parent, "bus-range"); 824 if (!prop) { 825 min_bus = max_bus = 0; 826 } else { 827 cells = (cell_t *)prop->val.val; 828 min_bus = fdt32_to_cpu(cells[0]); 829 max_bus = fdt32_to_cpu(cells[0]); 830 } 831 if ((bus_num < min_bus) || (bus_num > max_bus)) 832 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", 833 bus_num, min_bus, max_bus); 834 } 835 WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); 836 837 static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) 838 { 839 struct property *prop; 840 const char *unitname = get_unitname(node); 841 char unit_addr[5]; 842 unsigned int dev, func, reg; 843 cell_t *cells; 844 845 if (!node->parent || (node->parent->bus != &pci_bus)) 846 return; 847 848 prop = get_property(node, "reg"); 849 if (!prop) { 850 FAIL(c, dti, node, "missing PCI reg property"); 851 return; 852 } 853 854 cells = (cell_t *)prop->val.val; 855 if (cells[1] || cells[2]) 856 FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); 857 858 reg = fdt32_to_cpu(cells[0]); 859 dev = (reg & 0xf800) >> 11; 860 func = (reg & 0x700) >> 8; 861 862 if (reg & 0xff000000) 863 FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); 864 if (reg & 0x000000ff) 865 FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); 866 867 if (func == 0) { 868 snprintf(unit_addr, sizeof(unit_addr), "%x", dev); 869 if (streq(unitname, unit_addr)) 870 return; 871 } 872 873 snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); 874 if (streq(unitname, unit_addr)) 875 return; 876 877 FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", 878 unit_addr); 879 } 880 WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); 881 882 static const struct bus_type simple_bus = { 883 .name = "simple-bus", 884 }; 885 886 static bool node_is_compatible(struct node *node, const char *compat) 887 { 888 struct property *prop; 889 const char *str, *end; 890 891 prop = get_property(node, "compatible"); 892 if (!prop) 893 return false; 894 895 for (str = prop->val.val, end = str + prop->val.len; str < end; 896 str += strnlen(str, end - str) + 1) { 897 if (strprefixeq(str, end - str, compat)) 898 return true; 899 } 900 return false; 901 } 902 903 static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 904 { 905 if (node_is_compatible(node, "simple-bus")) 906 node->bus = &simple_bus; 907 } 908 WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); 909 910 static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 911 { 912 struct property *prop; 913 const char *unitname = get_unitname(node); 914 char unit_addr[17]; 915 unsigned int size; 916 uint64_t reg = 0; 917 cell_t *cells = NULL; 918 919 if (!node->parent || (node->parent->bus != &simple_bus)) 920 return; 921 922 prop = get_property(node, "reg"); 923 if (prop) 924 cells = (cell_t *)prop->val.val; 925 else { 926 prop = get_property(node, "ranges"); 927 if (prop && prop->val.len) 928 /* skip of child address */ 929 cells = ((cell_t *)prop->val.val) + node_addr_cells(node); 930 } 931 932 if (!cells) { 933 if (node->parent->parent && !(node->bus == &simple_bus)) 934 FAIL(c, dti, node, "missing or empty reg/ranges property"); 935 return; 936 } 937 938 size = node_addr_cells(node->parent); 939 while (size--) 940 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 941 942 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); 943 if (!streq(unitname, unit_addr)) 944 FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", 945 unit_addr); 946 } 947 WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); 948 949 static void check_unit_address_format(struct check *c, struct dt_info *dti, 950 struct node *node) 951 { 952 const char *unitname = get_unitname(node); 953 954 if (node->parent && node->parent->bus) 955 return; 956 957 if (!unitname[0]) 958 return; 959 960 if (!strncmp(unitname, "0x", 2)) { 961 FAIL(c, dti, node, "unit name should not have leading \"0x\""); 962 /* skip over 0x for next test */ 963 unitname += 2; 964 } 965 if (unitname[0] == '0' && isxdigit(unitname[1])) 966 FAIL(c, dti, node, "unit name should not have leading 0s"); 967 } 968 WARNING(unit_address_format, check_unit_address_format, NULL, 969 &node_name_format, &pci_bridge, &simple_bus_bridge); 970 971 /* 972 * Style checks 973 */ 974 static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, 975 struct node *node) 976 { 977 struct property *reg, *ranges; 978 979 if (!node->parent) 980 return; /* Ignore root node */ 981 982 reg = get_property(node, "reg"); 983 ranges = get_property(node, "ranges"); 984 985 if (!reg && !ranges) 986 return; 987 988 if (node->parent->addr_cells == -1) 989 FAIL(c, dti, node, "Relying on default #address-cells value"); 990 991 if (node->parent->size_cells == -1) 992 FAIL(c, dti, node, "Relying on default #size-cells value"); 993 } 994 WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, 995 &addr_size_cells); 996 997 static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, 998 struct node *node) 999 { 1000 struct property *prop; 1001 struct node *child; 1002 bool has_reg = false; 1003 1004 if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) 1005 return; 1006 1007 if (get_property(node, "ranges") || !node->children) 1008 return; 1009 1010 for_each_child(node, child) { 1011 prop = get_property(child, "reg"); 1012 if (prop) 1013 has_reg = true; 1014 } 1015 1016 if (!has_reg) 1017 FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); 1018 } 1019 WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); 1020 1021 static void check_obsolete_chosen_interrupt_controller(struct check *c, 1022 struct dt_info *dti, 1023 struct node *node) 1024 { 1025 struct node *dt = dti->dt; 1026 struct node *chosen; 1027 struct property *prop; 1028 1029 if (node != dt) 1030 return; 1031 1032 1033 chosen = get_node_by_path(dt, "/chosen"); 1034 if (!chosen) 1035 return; 1036 1037 prop = get_property(chosen, "interrupt-controller"); 1038 if (prop) 1039 FAIL_PROP(c, dti, node, prop, 1040 "/chosen has obsolete \"interrupt-controller\" property"); 1041 } 1042 WARNING(obsolete_chosen_interrupt_controller, 1043 check_obsolete_chosen_interrupt_controller, NULL); 1044 1045 static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, 1046 struct node *node) 1047 { 1048 if (!streq(node->name, "chosen")) 1049 return; 1050 1051 if (node->parent != dti->dt) 1052 FAIL(c, dti, node, "chosen node must be at root node"); 1053 } 1054 WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); 1055 1056 static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, 1057 struct node *node) 1058 { 1059 struct property *prop; 1060 1061 if (!streq(node->name, "chosen")) 1062 return; 1063 1064 prop = get_property(node, "bootargs"); 1065 if (!prop) 1066 return; 1067 1068 c->data = prop->name; 1069 check_is_string(c, dti, node); 1070 } 1071 WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); 1072 1073 static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, 1074 struct node *node) 1075 { 1076 struct property *prop; 1077 1078 if (!streq(node->name, "chosen")) 1079 return; 1080 1081 prop = get_property(node, "stdout-path"); 1082 if (!prop) { 1083 prop = get_property(node, "linux,stdout-path"); 1084 if (!prop) 1085 return; 1086 FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); 1087 } 1088 1089 c->data = prop->name; 1090 check_is_string(c, dti, node); 1091 } 1092 WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); 1093 1094 struct provider { 1095 const char *prop_name; 1096 const char *cell_name; 1097 bool optional; 1098 }; 1099 1100 static void check_property_phandle_args(struct check *c, 1101 struct dt_info *dti, 1102 struct node *node, 1103 struct property *prop, 1104 const struct provider *provider) 1105 { 1106 struct node *root = dti->dt; 1107 int cell, cellsize = 0; 1108 1109 if (prop->val.len % sizeof(cell_t)) { 1110 FAIL_PROP(c, dti, node, prop, 1111 "property size (%d) is invalid, expected multiple of %zu", 1112 prop->val.len, sizeof(cell_t)); 1113 return; 1114 } 1115 1116 for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { 1117 struct node *provider_node; 1118 struct property *cellprop; 1119 int phandle; 1120 1121 phandle = propval_cell_n(prop, cell); 1122 /* 1123 * Some bindings use a cell value 0 or -1 to skip over optional 1124 * entries when each index position has a specific definition. 1125 */ 1126 if (phandle == 0 || phandle == -1) { 1127 /* Give up if this is an overlay with external references */ 1128 if (dti->dtsflags & DTSF_PLUGIN) 1129 break; 1130 1131 cellsize = 0; 1132 continue; 1133 } 1134 1135 /* If we have markers, verify the current cell is a phandle */ 1136 if (prop->val.markers) { 1137 struct marker *m = prop->val.markers; 1138 for_each_marker_of_type(m, REF_PHANDLE) { 1139 if (m->offset == (cell * sizeof(cell_t))) 1140 break; 1141 } 1142 if (!m) 1143 FAIL_PROP(c, dti, node, prop, 1144 "cell %d is not a phandle reference", 1145 cell); 1146 } 1147 1148 provider_node = get_node_by_phandle(root, phandle); 1149 if (!provider_node) { 1150 FAIL_PROP(c, dti, node, prop, 1151 "Could not get phandle node for (cell %d)", 1152 cell); 1153 break; 1154 } 1155 1156 cellprop = get_property(provider_node, provider->cell_name); 1157 if (cellprop) { 1158 cellsize = propval_cell(cellprop); 1159 } else if (provider->optional) { 1160 cellsize = 0; 1161 } else { 1162 FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", 1163 provider->cell_name, 1164 provider_node->fullpath, 1165 prop->name, cell); 1166 break; 1167 } 1168 1169 if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { 1170 FAIL_PROP(c, dti, node, prop, 1171 "property size (%d) too small for cell size %d", 1172 prop->val.len, cellsize); 1173 } 1174 } 1175 } 1176 1177 static void check_provider_cells_property(struct check *c, 1178 struct dt_info *dti, 1179 struct node *node) 1180 { 1181 struct provider *provider = c->data; 1182 struct property *prop; 1183 1184 prop = get_property(node, provider->prop_name); 1185 if (!prop) 1186 return; 1187 1188 check_property_phandle_args(c, dti, node, prop, provider); 1189 } 1190 #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ 1191 static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ 1192 WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); 1193 1194 WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); 1195 WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); 1196 WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); 1197 WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); 1198 WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); 1199 WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); 1200 WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); 1201 WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); 1202 WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); 1203 WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); 1204 WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); 1205 WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); 1206 WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); 1207 WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); 1208 WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); 1209 WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); 1210 1211 static bool prop_is_gpio(struct property *prop) 1212 { 1213 char *str; 1214 1215 /* 1216 * *-gpios and *-gpio can appear in property names, 1217 * so skip over any false matches (only one known ATM) 1218 */ 1219 if (strstr(prop->name, "nr-gpio")) 1220 return false; 1221 1222 str = strrchr(prop->name, '-'); 1223 if (str) 1224 str++; 1225 else 1226 str = prop->name; 1227 if (!(streq(str, "gpios") || streq(str, "gpio"))) 1228 return false; 1229 1230 return true; 1231 } 1232 1233 static void check_gpios_property(struct check *c, 1234 struct dt_info *dti, 1235 struct node *node) 1236 { 1237 struct property *prop; 1238 1239 /* Skip GPIO hog nodes which have 'gpios' property */ 1240 if (get_property(node, "gpio-hog")) 1241 return; 1242 1243 for_each_property(node, prop) { 1244 struct provider provider; 1245 1246 if (!prop_is_gpio(prop)) 1247 continue; 1248 1249 provider.prop_name = prop->name; 1250 provider.cell_name = "#gpio-cells"; 1251 provider.optional = false; 1252 check_property_phandle_args(c, dti, node, prop, &provider); 1253 } 1254 1255 } 1256 WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); 1257 1258 static void check_deprecated_gpio_property(struct check *c, 1259 struct dt_info *dti, 1260 struct node *node) 1261 { 1262 struct property *prop; 1263 1264 for_each_property(node, prop) { 1265 char *str; 1266 1267 if (!prop_is_gpio(prop)) 1268 continue; 1269 1270 str = strstr(prop->name, "gpio"); 1271 if (!streq(str, "gpio")) 1272 continue; 1273 1274 FAIL_PROP(c, dti, node, prop, 1275 "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); 1276 } 1277 1278 } 1279 CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); 1280 1281 static bool node_is_interrupt_provider(struct node *node) 1282 { 1283 struct property *prop; 1284 1285 prop = get_property(node, "interrupt-controller"); 1286 if (prop) 1287 return true; 1288 1289 prop = get_property(node, "interrupt-map"); 1290 if (prop) 1291 return true; 1292 1293 return false; 1294 } 1295 static void check_interrupts_property(struct check *c, 1296 struct dt_info *dti, 1297 struct node *node) 1298 { 1299 struct node *root = dti->dt; 1300 struct node *irq_node = NULL, *parent = node; 1301 struct property *irq_prop, *prop = NULL; 1302 int irq_cells, phandle; 1303 1304 irq_prop = get_property(node, "interrupts"); 1305 if (!irq_prop) 1306 return; 1307 1308 if (irq_prop->val.len % sizeof(cell_t)) 1309 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", 1310 irq_prop->val.len, sizeof(cell_t)); 1311 1312 while (parent && !prop) { 1313 if (parent != node && node_is_interrupt_provider(parent)) { 1314 irq_node = parent; 1315 break; 1316 } 1317 1318 prop = get_property(parent, "interrupt-parent"); 1319 if (prop) { 1320 phandle = propval_cell(prop); 1321 /* Give up if this is an overlay with external references */ 1322 if ((phandle == 0 || phandle == -1) && 1323 (dti->dtsflags & DTSF_PLUGIN)) 1324 return; 1325 1326 irq_node = get_node_by_phandle(root, phandle); 1327 if (!irq_node) { 1328 FAIL_PROP(c, dti, parent, prop, "Bad phandle"); 1329 return; 1330 } 1331 if (!node_is_interrupt_provider(irq_node)) 1332 FAIL(c, dti, irq_node, 1333 "Missing interrupt-controller or interrupt-map property"); 1334 1335 break; 1336 } 1337 1338 parent = parent->parent; 1339 } 1340 1341 if (!irq_node) { 1342 FAIL(c, dti, node, "Missing interrupt-parent"); 1343 return; 1344 } 1345 1346 prop = get_property(irq_node, "#interrupt-cells"); 1347 if (!prop) { 1348 FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); 1349 return; 1350 } 1351 1352 irq_cells = propval_cell(prop); 1353 if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { 1354 FAIL_PROP(c, dti, node, prop, 1355 "size is (%d), expected multiple of %d", 1356 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); 1357 } 1358 } 1359 WARNING(interrupts_property, check_interrupts_property, &phandle_references); 1360 1361 static struct check *check_table[] = { 1362 &duplicate_node_names, &duplicate_property_names, 1363 &node_name_chars, &node_name_format, &property_name_chars, 1364 &name_is_string, &name_properties, 1365 1366 &duplicate_label, 1367 1368 &explicit_phandles, 1369 &phandle_references, &path_references, 1370 1371 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, 1372 &device_type_is_string, &model_is_string, &status_is_string, 1373 &label_is_string, 1374 1375 &compatible_is_string_list, &names_is_string_list, 1376 1377 &property_name_chars_strict, 1378 &node_name_chars_strict, 1379 1380 &addr_size_cells, ®_format, &ranges_format, 1381 1382 &unit_address_vs_reg, 1383 &unit_address_format, 1384 1385 &pci_bridge, 1386 &pci_device_reg, 1387 &pci_device_bus_num, 1388 1389 &simple_bus_bridge, 1390 &simple_bus_reg, 1391 1392 &avoid_default_addr_size, 1393 &avoid_unnecessary_addr_size, 1394 &obsolete_chosen_interrupt_controller, 1395 &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, 1396 1397 &clocks_property, 1398 &cooling_device_property, 1399 &dmas_property, 1400 &hwlocks_property, 1401 &interrupts_extended_property, 1402 &io_channels_property, 1403 &iommus_property, 1404 &mboxes_property, 1405 &msi_parent_property, 1406 &mux_controls_property, 1407 &phys_property, 1408 &power_domains_property, 1409 &pwms_property, 1410 &resets_property, 1411 &sound_dai_property, 1412 &thermal_sensors_property, 1413 1414 &deprecated_gpio_property, 1415 &gpios_property, 1416 &interrupts_property, 1417 1418 &alias_paths, 1419 1420 &always_fail, 1421 }; 1422 1423 static void enable_warning_error(struct check *c, bool warn, bool error) 1424 { 1425 int i; 1426 1427 /* Raising level, also raise it for prereqs */ 1428 if ((warn && !c->warn) || (error && !c->error)) 1429 for (i = 0; i < c->num_prereqs; i++) 1430 enable_warning_error(c->prereq[i], warn, error); 1431 1432 c->warn = c->warn || warn; 1433 c->error = c->error || error; 1434 } 1435 1436 static void disable_warning_error(struct check *c, bool warn, bool error) 1437 { 1438 int i; 1439 1440 /* Lowering level, also lower it for things this is the prereq 1441 * for */ 1442 if ((warn && c->warn) || (error && c->error)) { 1443 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1444 struct check *cc = check_table[i]; 1445 int j; 1446 1447 for (j = 0; j < cc->num_prereqs; j++) 1448 if (cc->prereq[j] == c) 1449 disable_warning_error(cc, warn, error); 1450 } 1451 } 1452 1453 c->warn = c->warn && !warn; 1454 c->error = c->error && !error; 1455 } 1456 1457 void parse_checks_option(bool warn, bool error, const char *arg) 1458 { 1459 int i; 1460 const char *name = arg; 1461 bool enable = true; 1462 1463 if ((strncmp(arg, "no-", 3) == 0) 1464 || (strncmp(arg, "no_", 3) == 0)) { 1465 name = arg + 3; 1466 enable = false; 1467 } 1468 1469 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1470 struct check *c = check_table[i]; 1471 1472 if (streq(c->name, name)) { 1473 if (enable) 1474 enable_warning_error(c, warn, error); 1475 else 1476 disable_warning_error(c, warn, error); 1477 return; 1478 } 1479 } 1480 1481 die("Unrecognized check name \"%s\"\n", name); 1482 } 1483 1484 void process_checks(bool force, struct dt_info *dti) 1485 { 1486 int i; 1487 int error = 0; 1488 1489 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1490 struct check *c = check_table[i]; 1491 1492 if (c->warn || c->error) 1493 error = error || run_check(c, dti); 1494 } 1495 1496 if (error) { 1497 if (!force) { 1498 fprintf(stderr, "ERROR: Input tree has errors, aborting " 1499 "(use -f to force output)\n"); 1500 exit(2); 1501 } else if (quiet < 3) { 1502 fprintf(stderr, "Warning: Input tree has errors, " 1503 "output forced\n"); 1504 } 1505 } 1506 } 1507