Lines Matching +full:c +full:- +full:define +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
10 #define TRACE(c, ...) \ argument
12 fprintf(stderr, "=== %s: ", (c)->name); \
17 #define TRACE(c, fmt, ...) do { } while (0) argument
29 typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node);
32 const char *name; member
42 #define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \
45 .name = #nm_, \
54 #define WARNING(nm_, fn_, d_, ...) \
56 #define ERROR(nm_, fn_, d_, ...) \
58 #define CHECK(nm_, fn_, d_, ...) \
61 static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, in check_msg() argument
71 if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2))) in check_msg()
74 if (prop && prop->srcpos) in check_msg()
75 pos = prop->srcpos; in check_msg()
76 else if (node && node->srcpos) in check_msg()
77 pos = node->srcpos; in check_msg()
83 } else if (streq(dti->outname, "-")) { in check_msg()
86 xasprintf(&str, "%s", dti->outname); in check_msg()
90 (c->error) ? "ERROR" : "Warning", c->name); in check_msg()
94 xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name); in check_msg()
96 xasprintf_append(&str, "%s: ", node->fullpath); in check_msg()
106 pos = node->srcpos; in check_msg()
107 while (pos->next) { in check_msg()
108 pos = pos->next; in check_msg()
119 #define FAIL(c, dti, node, ...) \ argument
121 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
122 (c)->status = FAILED; \
123 check_msg((c), dti, node, NULL, __VA_ARGS__); \
126 #define FAIL_PROP(c, dti, node, prop, ...) \ argument
128 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
129 (c)->status = FAILED; \
130 check_msg((c), dti, node, prop, __VA_ARGS__); \
134 static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) in check_nodes_props() argument
138 TRACE(c, "%s", node->fullpath); in check_nodes_props()
139 if (c->fn) in check_nodes_props()
140 c->fn(c, dti, node); in check_nodes_props()
143 check_nodes_props(c, dti, child); in check_nodes_props()
154 static bool run_check(struct check *c, struct dt_info *dti) in run_check() argument
156 struct node *dt = dti->dt; in run_check()
160 assert(!c->inprogress); in run_check()
162 if (c->status != UNCHECKED) in run_check()
165 c->inprogress = true; in run_check()
167 for (i = 0; i < c->num_prereqs; i++) { in run_check()
168 struct check *prq = c->prereq[i]; in run_check()
170 if (prq->status != PASSED) { in run_check()
171 c->status = PREREQ; in run_check()
172 check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", in run_check()
173 c->prereq[i]->name); in run_check()
177 if (c->status != UNCHECKED) in run_check()
180 check_nodes_props(c, dti, dt); in run_check()
182 if (c->status == UNCHECKED) in run_check()
183 c->status = PASSED; in run_check()
185 TRACE(c, "\tCompleted, status %d", c->status); in run_check()
188 c->inprogress = false; in run_check()
189 if ((c->status != PASSED) && (c->error)) in run_check()
199 static inline void check_always_fail(struct check *c, struct dt_info *dti, in check_always_fail() argument
202 FAIL(c, dti, node, "always_fail check"); in check_always_fail()
206 static void check_is_string(struct check *c, struct dt_info *dti, in check_is_string() argument
210 char *propname = c->data; in check_is_string()
216 if (!data_is_one_string(prop->val)) in check_is_string()
217 FAIL_PROP(c, dti, node, prop, "property is not a string"); in check_is_string()
219 #define WARNING_IF_NOT_STRING(nm, propname) \
221 #define ERROR_IF_NOT_STRING(nm, propname) \
224 static void check_is_string_list(struct check *c, struct dt_info *dti, in check_is_string_list() argument
229 char *propname = c->data; in check_is_string_list()
236 str = prop->val.val; in check_is_string_list()
237 rem = prop->val.len; in check_is_string_list()
241 FAIL_PROP(c, dti, node, prop, "property is not a string list"); in check_is_string_list()
244 rem -= l + 1; in check_is_string_list()
248 #define WARNING_IF_NOT_STRING_LIST(nm, propname) \
250 #define ERROR_IF_NOT_STRING_LIST(nm, propname) \
253 static void check_is_cell(struct check *c, struct dt_info *dti, in check_is_cell() argument
257 char *propname = c->data; in check_is_cell()
263 if (prop->val.len != sizeof(cell_t)) in check_is_cell()
264 FAIL_PROP(c, dti, node, prop, "property is not a single cell"); in check_is_cell()
266 #define WARNING_IF_NOT_CELL(nm, propname) \
268 #define ERROR_IF_NOT_CELL(nm, propname) \
275 static void check_duplicate_node_names(struct check *c, struct dt_info *dti, in check_duplicate_node_names() argument
281 for (child2 = child->next_sibling; in check_duplicate_node_names()
283 child2 = child2->next_sibling) in check_duplicate_node_names()
284 if (streq(child->name, child2->name)) in check_duplicate_node_names()
285 FAIL(c, dti, child2, "Duplicate node name"); in check_duplicate_node_names()
289 static void check_duplicate_property_names(struct check *c, struct dt_info *dti, in check_duplicate_property_names() argument
295 for (prop2 = prop->next; prop2; prop2 = prop2->next) { in check_duplicate_property_names()
296 if (prop2->deleted) in check_duplicate_property_names()
298 if (streq(prop->name, prop2->name)) in check_duplicate_property_names()
299 FAIL_PROP(c, dti, node, prop, "Duplicate property name"); in check_duplicate_property_names()
305 #define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
306 #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
307 #define DIGITS "0123456789"
308 #define NODECHARS LOWERCASE UPPERCASE DIGITS ",._+-@"
309 #define PROPCHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
310 #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-"
312 static void check_node_name_chars(struct check *c, struct dt_info *dti, in check_node_name_chars() argument
315 size_t n = strspn(node->name, c->data); in check_node_name_chars()
317 if (n < strlen(node->name)) in check_node_name_chars()
318 FAIL(c, dti, node, "Bad character '%c' in node name", in check_node_name_chars()
319 node->name[n]); in check_node_name_chars()
323 static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, in check_node_name_chars_strict() argument
326 int n = strspn(node->name, c->data); in check_node_name_chars_strict()
328 if (n < node->basenamelen) in check_node_name_chars_strict()
329 FAIL(c, dti, node, "Character '%c' not recommended in node name", in check_node_name_chars_strict()
330 node->name[n]); in check_node_name_chars_strict()
334 static void check_node_name_format(struct check *c, struct dt_info *dti, in check_node_name_format() argument
338 FAIL(c, dti, node, "multiple '@' characters in node name"); in check_node_name_format()
342 static void check_node_name_vs_property_name(struct check *c, in check_node_name_vs_property_name() argument
346 if (!node->parent) in check_node_name_vs_property_name()
349 if (get_property(node->parent, node->name)) { in check_node_name_vs_property_name()
350 FAIL(c, dti, node, "node name and property name conflict"); in check_node_name_vs_property_name()
356 static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, in check_unit_address_vs_reg() argument
369 if (prop && !prop->val.len) in check_unit_address_vs_reg()
375 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); in check_unit_address_vs_reg()
378 FAIL(c, dti, node, "node has a unit name, but no reg or ranges property"); in check_unit_address_vs_reg()
383 static void check_property_name_chars(struct check *c, struct dt_info *dti, in check_property_name_chars() argument
389 size_t n = strspn(prop->name, c->data); in check_property_name_chars()
391 if (n < strlen(prop->name)) in check_property_name_chars()
392 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", in check_property_name_chars()
393 prop->name[n]); in check_property_name_chars()
398 static void check_property_name_chars_strict(struct check *c, in check_property_name_chars_strict() argument
405 const char *name = prop->name; in check_property_name_chars_strict() local
406 size_t n = strspn(name, c->data); in check_property_name_chars_strict()
408 if (n == strlen(prop->name)) in check_property_name_chars_strict()
412 if (streq(name, "device_type")) in check_property_name_chars_strict()
419 if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { in check_property_name_chars_strict()
420 name += n + 1; in check_property_name_chars_strict()
421 n = strspn(name, c->data); in check_property_name_chars_strict()
423 if (n < strlen(name)) in check_property_name_chars_strict()
424 FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", in check_property_name_chars_strict()
425 name[n]); in check_property_name_chars_strict()
430 #define DESCLABEL_FMT "%s%s%s%s%s"
431 #define DESCLABEL_ARGS(node,prop,mark) \
434 ((prop) ? (prop)->name : ""), \
435 ((prop) ? "' in " : ""), (node)->fullpath
437 static void check_duplicate_label(struct check *c, struct dt_info *dti, in check_duplicate_label() argument
441 struct node *dt = dti->dt; in check_duplicate_label()
458 FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT in check_duplicate_label()
464 static void check_duplicate_label_node(struct check *c, struct dt_info *dti, in check_duplicate_label_node() argument
470 for_each_label(node->labels, l) in check_duplicate_label_node()
471 check_duplicate_label(c, dti, l->label, node, NULL, NULL); in check_duplicate_label_node()
474 struct marker *m = prop->val.markers; in check_duplicate_label_node()
476 for_each_label(prop->labels, l) in check_duplicate_label_node()
477 check_duplicate_label(c, dti, l->label, node, prop, NULL); in check_duplicate_label_node()
480 check_duplicate_label(c, dti, m->ref, node, prop, m); in check_duplicate_label_node()
485 static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, in check_phandle_prop() argument
488 struct node *root = dti->dt; in check_phandle_prop()
497 if (prop->val.len != sizeof(cell_t)) { in check_phandle_prop()
498 FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", in check_phandle_prop()
499 prop->val.len, prop->name); in check_phandle_prop()
503 m = prop->val.markers; in check_phandle_prop()
505 assert(m->offset == 0); in check_phandle_prop()
506 if (node != get_node_by_ref(root, m->ref)) in check_phandle_prop()
510 FAIL(c, dti, node, "%s is a reference to another node", in check_phandle_prop()
511 prop->name); in check_phandle_prop()
514 * phandle is allowed - that means allocate a unique in check_phandle_prop()
524 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", in check_phandle_prop()
525 phandle, prop->name); in check_phandle_prop()
532 static void check_explicit_phandles(struct check *c, struct dt_info *dti, in check_explicit_phandles() argument
535 struct node *root = dti->dt; in check_explicit_phandles()
540 assert(!node->phandle); in check_explicit_phandles()
542 phandle = check_phandle_prop(c, dti, node, "phandle"); in check_explicit_phandles()
544 linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); in check_explicit_phandles()
551 FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" in check_explicit_phandles()
559 FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", in check_explicit_phandles()
560 phandle, other->fullpath); in check_explicit_phandles()
564 node->phandle = phandle; in check_explicit_phandles()
568 static void check_name_properties(struct check *c, struct dt_info *dti, in check_name_properties() argument
573 for (pp = &node->proplist; *pp; pp = &((*pp)->next)) in check_name_properties()
574 if (streq((*pp)->name, "name")) { in check_name_properties()
580 return; /* No name property, that's fine */ in check_name_properties()
582 if ((prop->val.len != node->basenamelen + 1U) in check_name_properties()
583 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { in check_name_properties()
584 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" in check_name_properties()
585 " of base node name)", prop->val.val); in check_name_properties()
587 /* The name property is correct, and therefore redundant. in check_name_properties()
589 *pp = prop->next; in check_name_properties()
590 free(prop->name); in check_name_properties()
591 data_free(prop->val); in check_name_properties()
595 ERROR_IF_NOT_STRING(name_is_string, "name");
602 static void fixup_phandle_references(struct check *c, struct dt_info *dti, in fixup_phandle_references() argument
605 struct node *dt = dti->dt; in fixup_phandle_references()
609 struct marker *m = prop->val.markers; in fixup_phandle_references()
614 assert(m->offset + sizeof(cell_t) <= prop->val.len); in fixup_phandle_references()
616 refnode = get_node_by_ref(dt, m->ref); in fixup_phandle_references()
618 if (!(dti->dtsflags & DTSF_PLUGIN)) in fixup_phandle_references()
619 FAIL(c, dti, node, "Reference to non-existent node or " in fixup_phandle_references()
620 "label \"%s\"\n", m->ref); in fixup_phandle_references()
622 *((fdt32_t *)(prop->val.val + m->offset)) = in fixup_phandle_references()
628 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); in fixup_phandle_references()
637 static void fixup_path_references(struct check *c, struct dt_info *dti, in fixup_path_references() argument
640 struct node *dt = dti->dt; in fixup_path_references()
644 struct marker *m = prop->val.markers; in fixup_path_references()
649 assert(m->offset <= prop->val.len); in fixup_path_references()
651 refnode = get_node_by_ref(dt, m->ref); in fixup_path_references()
653 FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", in fixup_path_references()
654 m->ref); in fixup_path_references()
658 path = refnode->fullpath; in fixup_path_references()
659 prop->val = data_insert_at_marker(prop->val, m, path, in fixup_path_references()
668 static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti, in fixup_omit_unused_nodes() argument
671 if (generate_symbols && node->labels) in fixup_omit_unused_nodes()
673 if (node->omit_if_unused && !node->is_referenced) in fixup_omit_unused_nodes()
681 WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
682 WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
691 static void check_names_is_string_list(struct check *c, struct dt_info *dti, in check_names_is_string_list() argument
697 if (!strends(prop->name, "-names")) in check_names_is_string_list()
700 c->data = prop->name; in check_names_is_string_list()
701 check_is_string_list(c, dti, node); in check_names_is_string_list()
706 static void check_alias_paths(struct check *c, struct dt_info *dti, in check_alias_paths() argument
711 if (!streq(node->name, "aliases")) in check_alias_paths()
715 if (streq(prop->name, "phandle") in check_alias_paths()
716 || streq(prop->name, "linux,phandle")) { in check_alias_paths()
720 if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { in check_alias_paths()
721 FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", in check_alias_paths()
722 prop->val.val); in check_alias_paths()
725 if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) in check_alias_paths()
726 FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); in check_alias_paths()
731 static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, in fixup_addr_size_cells() argument
736 node->addr_cells = -1; in fixup_addr_size_cells()
737 node->size_cells = -1; in fixup_addr_size_cells()
739 prop = get_property(node, "#address-cells"); in fixup_addr_size_cells()
741 node->addr_cells = propval_cell(prop); in fixup_addr_size_cells()
743 prop = get_property(node, "#size-cells"); in fixup_addr_size_cells()
745 node->size_cells = propval_cell(prop); in fixup_addr_size_cells()
750 #define node_addr_cells(n) \
751 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
752 #define node_size_cells(n) \
753 (((n)->size_cells == -1) ? 1 : (n)->size_cells)
755 static void check_reg_format(struct check *c, struct dt_info *dti, in check_reg_format() argument
765 if (!node->parent) { in check_reg_format()
766 FAIL(c, dti, node, "Root node has a \"reg\" property"); in check_reg_format()
770 if (prop->val.len == 0) in check_reg_format()
771 FAIL_PROP(c, dti, node, prop, "property is empty"); in check_reg_format()
773 addr_cells = node_addr_cells(node->parent); in check_reg_format()
774 size_cells = node_size_cells(node->parent); in check_reg_format()
777 if (!is_multiple_of(prop->val.len, entrylen)) in check_reg_format()
778 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " in check_reg_format()
779 "(#address-cells == %d, #size-cells == %d)", in check_reg_format()
780 prop->val.len, addr_cells, size_cells); in check_reg_format()
784 static void check_ranges_format(struct check *c, struct dt_info *dti, in check_ranges_format() argument
789 const char *ranges = c->data; in check_ranges_format()
795 if (!node->parent) { in check_ranges_format()
796 FAIL_PROP(c, dti, node, prop, "Root node has a \"%s\" property", in check_ranges_format()
801 p_addr_cells = node_addr_cells(node->parent); in check_ranges_format()
802 p_size_cells = node_size_cells(node->parent); in check_ranges_format()
807 if (prop->val.len == 0) { in check_ranges_format()
809 FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its " in check_ranges_format()
810 "#address-cells (%d) differs from %s (%d)", in check_ranges_format()
811 ranges, c_addr_cells, node->parent->fullpath, in check_ranges_format()
814 FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its " in check_ranges_format()
815 "#size-cells (%d) differs from %s (%d)", in check_ranges_format()
816 ranges, c_size_cells, node->parent->fullpath, in check_ranges_format()
818 } else if (!is_multiple_of(prop->val.len, entrylen)) { in check_ranges_format()
819 FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) " in check_ranges_format()
820 "(parent #address-cells == %d, child #address-cells == %d, " in check_ranges_format()
821 "#size-cells == %d)", ranges, prop->val.len, in check_ranges_format()
826 WARNING(dma_ranges_format, check_ranges_format, "dma-ranges", &addr_size_cells);
829 .name = "PCI",
832 static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) in check_pci_bridge() argument
838 if (!prop || !streq(prop->val.val, "pci")) in check_pci_bridge()
841 node->bus = &pci_bus; in check_pci_bridge()
843 if (!strprefixeq(node->name, node->basenamelen, "pci") && in check_pci_bridge()
844 !strprefixeq(node->name, node->basenamelen, "pcie")) in check_pci_bridge()
845 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); in check_pci_bridge()
849 FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); in check_pci_bridge()
852 FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); in check_pci_bridge()
854 FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); in check_pci_bridge()
856 prop = get_property(node, "bus-range"); in check_pci_bridge()
860 if (prop->val.len != (sizeof(cell_t) * 2)) { in check_pci_bridge()
861 FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); in check_pci_bridge()
864 cells = (cell_t *)prop->val.val; in check_pci_bridge()
866 FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); in check_pci_bridge()
868 FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); in check_pci_bridge()
873 static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) in check_pci_device_bus_num() argument
879 if (!node->parent || (node->parent->bus != &pci_bus)) in check_pci_device_bus_num()
886 cells = (cell_t *)prop->val.val; in check_pci_device_bus_num()
889 prop = get_property(node->parent, "bus-range"); in check_pci_device_bus_num()
893 cells = (cell_t *)prop->val.val; in check_pci_device_bus_num()
898 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", in check_pci_device_bus_num()
903 static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) in check_pci_device_reg() argument
911 if (!node->parent || (node->parent->bus != &pci_bus)) in check_pci_device_reg()
918 cells = (cell_t *)prop->val.val; in check_pci_device_reg()
920 FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); in check_pci_device_reg()
927 FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); in check_pci_device_reg()
929 FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); in check_pci_device_reg()
941 FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", in check_pci_device_reg()
947 .name = "simple-bus",
959 for (str = prop->val.val, end = str + prop->val.len; str < end; in node_is_compatible()
960 str += strnlen(str, end - str) + 1) { in node_is_compatible()
967 static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) in check_simple_bus_bridge() argument
969 if (node_is_compatible(node, "simple-bus")) in check_simple_bus_bridge()
970 node->bus = &simple_bus; in check_simple_bus_bridge()
975 static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) in check_simple_bus_reg() argument
984 if (!node->parent || (node->parent->bus != &simple_bus)) in check_simple_bus_reg()
989 cells = (cell_t *)prop->val.val; in check_simple_bus_reg()
992 if (prop && prop->val.len) in check_simple_bus_reg()
994 cells = ((cell_t *)prop->val.val) + node_addr_cells(node); in check_simple_bus_reg()
998 if (node->parent->parent && !(node->bus == &simple_bus)) in check_simple_bus_reg()
999 FAIL(c, dti, node, "missing or empty reg/ranges property"); in check_simple_bus_reg()
1003 size = node_addr_cells(node->parent); in check_simple_bus_reg()
1004 while (size--) in check_simple_bus_reg()
1009 FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", in check_simple_bus_reg()
1015 .name = "i2c-bus",
1018 static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) in check_i2c_bus_bridge() argument
1020 if (strprefixeq(node->name, node->basenamelen, "i2c-bus") || in check_i2c_bus_bridge()
1021 strprefixeq(node->name, node->basenamelen, "i2c-arb")) { in check_i2c_bus_bridge()
1022 node->bus = &i2c_bus; in check_i2c_bus_bridge()
1023 } else if (strprefixeq(node->name, node->basenamelen, "i2c")) { in check_i2c_bus_bridge()
1026 if (strprefixeq(child->name, node->basenamelen, "i2c-bus")) in check_i2c_bus_bridge()
1029 node->bus = &i2c_bus; in check_i2c_bus_bridge()
1033 if (!node->children) in check_i2c_bus_bridge()
1037 FAIL(c, dti, node, "incorrect #address-cells for I2C bus"); in check_i2c_bus_bridge()
1039 FAIL(c, dti, node, "incorrect #size-cells for I2C bus"); in check_i2c_bus_bridge()
1044 #define I2C_OWN_SLAVE_ADDRESS (1U << 30)
1045 #define I2C_TEN_BIT_ADDRESS (1U << 31)
1047 static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node) in check_i2c_bus_reg() argument
1056 if (!node->parent || (node->parent->bus != &i2c_bus)) in check_i2c_bus_reg()
1061 cells = (cell_t *)prop->val.val; in check_i2c_bus_reg()
1064 FAIL(c, dti, node, "missing or empty reg property"); in check_i2c_bus_reg()
1073 FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"", in check_i2c_bus_reg()
1076 for (len = prop->val.len; len > 0; len -= 4) { in check_i2c_bus_reg()
1082 FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", in check_i2c_bus_reg()
1085 …FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\". Set I2C_TEN_BIT… in check_i2c_bus_reg()
1092 .name = "spi-bus",
1095 static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) in check_spi_bus_bridge() argument
1099 if (strprefixeq(node->name, node->basenamelen, "spi")) { in check_spi_bus_bridge()
1100 node->bus = &spi_bus; in check_spi_bus_bridge()
1102 /* Try to detect SPI buses which don't have proper node name */ in check_spi_bus_bridge()
1111 if (strprefixeq(prop->name, 4, "spi-")) { in check_spi_bus_bridge()
1112 node->bus = &spi_bus; in check_spi_bus_bridge()
1116 if (node->bus == &spi_bus) in check_spi_bus_bridge()
1120 if (node->bus == &spi_bus && get_property(node, "reg")) in check_spi_bus_bridge()
1121 FAIL(c, dti, node, "node name for SPI buses should be 'spi'"); in check_spi_bus_bridge()
1123 if (node->bus != &spi_bus || !node->children) in check_spi_bus_bridge()
1126 if (get_property(node, "spi-slave")) in check_spi_bus_bridge()
1129 FAIL(c, dti, node, "incorrect #address-cells for SPI bus"); in check_spi_bus_bridge()
1131 FAIL(c, dti, node, "incorrect #size-cells for SPI bus"); in check_spi_bus_bridge()
1136 static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node) in check_spi_bus_reg() argument
1144 if (!node->parent || (node->parent->bus != &spi_bus)) in check_spi_bus_reg()
1147 if (get_property(node->parent, "spi-slave")) in check_spi_bus_reg()
1152 cells = (cell_t *)prop->val.val; in check_spi_bus_reg()
1155 FAIL(c, dti, node, "missing or empty reg property"); in check_spi_bus_reg()
1162 FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"", in check_spi_bus_reg()
1167 static void check_unit_address_format(struct check *c, struct dt_info *dti, in check_unit_address_format() argument
1172 if (node->parent && node->parent->bus) in check_unit_address_format()
1179 FAIL(c, dti, node, "unit name should not have leading \"0x\""); in check_unit_address_format()
1184 FAIL(c, dti, node, "unit name should not have leading 0s"); in check_unit_address_format()
1192 static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, in check_avoid_default_addr_size() argument
1197 if (!node->parent) in check_avoid_default_addr_size()
1206 if (node->parent->addr_cells == -1) in check_avoid_default_addr_size()
1207 FAIL(c, dti, node, "Relying on default #address-cells value"); in check_avoid_default_addr_size()
1209 if (node->parent->size_cells == -1) in check_avoid_default_addr_size()
1210 FAIL(c, dti, node, "Relying on default #size-cells value"); in check_avoid_default_addr_size()
1215 static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, in check_avoid_unnecessary_addr_size() argument
1222 if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) in check_avoid_unnecessary_addr_size()
1225 if (get_property(node, "ranges") || !node->children) in check_avoid_unnecessary_addr_size()
1235 …FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" pro… in check_avoid_unnecessary_addr_size()
1245 char *str = prop->val.val; in node_is_disabled()
1253 static void check_unique_unit_address_common(struct check *c, in check_unique_unit_address_common() argument
1260 if (node->addr_cells < 0 || node->size_cells < 0) in check_unique_unit_address_common()
1263 if (!node->children) in check_unique_unit_address_common()
1285 FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath); in check_unique_unit_address_common()
1290 static void check_unique_unit_address(struct check *c, struct dt_info *dti, in check_unique_unit_address() argument
1293 check_unique_unit_address_common(c, dti, node, false); in check_unique_unit_address()
1297 static void check_unique_unit_address_if_enabled(struct check *c, struct dt_info *dti, in check_unique_unit_address_if_enabled() argument
1300 check_unique_unit_address_common(c, dti, node, true); in check_unique_unit_address_if_enabled()
1305 static void check_obsolete_chosen_interrupt_controller(struct check *c, in check_obsolete_chosen_interrupt_controller() argument
1309 struct node *dt = dti->dt; in check_obsolete_chosen_interrupt_controller()
1321 prop = get_property(chosen, "interrupt-controller"); in check_obsolete_chosen_interrupt_controller()
1323 FAIL_PROP(c, dti, node, prop, in check_obsolete_chosen_interrupt_controller()
1324 "/chosen has obsolete \"interrupt-controller\" property"); in check_obsolete_chosen_interrupt_controller()
1329 static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, in check_chosen_node_is_root() argument
1332 if (!streq(node->name, "chosen")) in check_chosen_node_is_root()
1335 if (node->parent != dti->dt) in check_chosen_node_is_root()
1336 FAIL(c, dti, node, "chosen node must be at root node"); in check_chosen_node_is_root()
1340 static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, in check_chosen_node_bootargs() argument
1345 if (!streq(node->name, "chosen")) in check_chosen_node_bootargs()
1352 c->data = prop->name; in check_chosen_node_bootargs()
1353 check_is_string(c, dti, node); in check_chosen_node_bootargs()
1357 static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, in check_chosen_node_stdout_path() argument
1362 if (!streq(node->name, "chosen")) in check_chosen_node_stdout_path()
1365 prop = get_property(node, "stdout-path"); in check_chosen_node_stdout_path()
1367 prop = get_property(node, "linux,stdout-path"); in check_chosen_node_stdout_path()
1370 FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); in check_chosen_node_stdout_path()
1373 c->data = prop->name; in check_chosen_node_stdout_path()
1374 check_is_string(c, dti, node); in check_chosen_node_stdout_path()
1384 static void check_property_phandle_args(struct check *c, in check_property_phandle_args() argument
1390 struct node *root = dti->dt; in check_property_phandle_args()
1393 if (!is_multiple_of(prop->val.len, sizeof(cell_t))) { in check_property_phandle_args()
1394 FAIL_PROP(c, dti, node, prop, in check_property_phandle_args()
1396 prop->val.len, sizeof(cell_t)); in check_property_phandle_args()
1400 for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { in check_property_phandle_args()
1408 * Some bindings use a cell value 0 or -1 to skip over optional in check_property_phandle_args()
1413 if (dti->dtsflags & DTSF_PLUGIN) in check_property_phandle_args()
1421 if (prop->val.markers) { in check_property_phandle_args()
1422 struct marker *m = prop->val.markers; in check_property_phandle_args()
1424 if (m->offset == (cell * sizeof(cell_t))) in check_property_phandle_args()
1428 FAIL_PROP(c, dti, node, prop, in check_property_phandle_args()
1435 FAIL_PROP(c, dti, node, prop, in check_property_phandle_args()
1441 cellprop = get_property(provider_node, provider->cell_name); in check_property_phandle_args()
1444 } else if (provider->optional) { in check_property_phandle_args()
1447 FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", in check_property_phandle_args()
1448 provider->cell_name, in check_property_phandle_args()
1449 provider_node->fullpath, in check_property_phandle_args()
1450 prop->name, cell); in check_property_phandle_args()
1455 if ((expected <= cell) || prop->val.len < expected) { in check_property_phandle_args()
1456 FAIL_PROP(c, dti, node, prop, in check_property_phandle_args()
1458 prop->val.len, cellsize); in check_property_phandle_args()
1464 static void check_provider_cells_property(struct check *c, in check_provider_cells_property() argument
1468 struct provider *provider = c->data; in check_provider_cells_property()
1471 prop = get_property(node, provider->prop_name); in check_provider_cells_property()
1475 check_property_phandle_args(c, dti, node, prop, provider); in check_provider_cells_property()
1477 #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
1482 WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
1483 WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
1484 WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
1485 WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
1486 WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
1487 WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
1488 WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
1489 WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
1490 WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
1491 WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
1492 WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
1493 WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
1494 WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
1495 WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
1496 WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells");
1497 WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
1502 * *-gpios and *-gpio can appear in property names, in prop_is_gpio()
1505 if (strends(prop->name, ",nr-gpios")) in prop_is_gpio()
1508 return strends(prop->name, "-gpios") || in prop_is_gpio()
1509 streq(prop->name, "gpios") || in prop_is_gpio()
1510 strends(prop->name, "-gpio") || in prop_is_gpio()
1511 streq(prop->name, "gpio"); in prop_is_gpio()
1514 static void check_gpios_property(struct check *c, in check_gpios_property() argument
1521 if (get_property(node, "gpio-hog")) in check_gpios_property()
1530 provider.prop_name = prop->name; in check_gpios_property()
1531 provider.cell_name = "#gpio-cells"; in check_gpios_property()
1533 check_property_phandle_args(c, dti, node, prop, &provider); in check_gpios_property()
1539 static void check_deprecated_gpio_property(struct check *c, in check_deprecated_gpio_property() argument
1549 if (!strends(prop->name, "gpio")) in check_deprecated_gpio_property()
1552 FAIL_PROP(c, dti, node, prop, in check_deprecated_gpio_property()
1553 "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); in check_deprecated_gpio_property()
1563 prop = get_property(node, "interrupt-controller"); in node_is_interrupt_provider()
1567 prop = get_property(node, "interrupt-map"); in node_is_interrupt_provider()
1574 static void check_interrupt_provider(struct check *c, in check_interrupt_provider() argument
1581 prop = get_property(node, "#interrupt-cells"); in check_interrupt_provider()
1583 FAIL(c, dti, node, in check_interrupt_provider()
1584 "Missing '#interrupt-cells' in interrupt provider"); in check_interrupt_provider()
1589 FAIL(c, dti, node, in check_interrupt_provider()
1590 "'#interrupt-cells' found, but node is not an interrupt provider"); in check_interrupt_provider()
1596 static void check_interrupt_map(struct check *c, in check_interrupt_map() argument
1600 struct node *root = dti->dt; in check_interrupt_map()
1604 irq_map_prop = get_property(node, "interrupt-map"); in check_interrupt_map()
1608 if (node->addr_cells < 0) { in check_interrupt_map()
1609 FAIL(c, dti, node, in check_interrupt_map()
1610 "Missing '#address-cells' in interrupt-map provider"); in check_interrupt_map()
1614 cellsize += propval_cell(get_property(node, "#interrupt-cells")); in check_interrupt_map()
1616 prop = get_property(node, "interrupt-map-mask"); in check_interrupt_map()
1617 if (prop && (prop->val.len != (cellsize * sizeof(cell_t)))) in check_interrupt_map()
1618 FAIL_PROP(c, dti, node, prop, in check_interrupt_map()
1620 prop->val.len, cellsize * sizeof(cell_t)); in check_interrupt_map()
1622 if (!is_multiple_of(irq_map_prop->val.len, sizeof(cell_t))) { in check_interrupt_map()
1623 FAIL_PROP(c, dti, node, irq_map_prop, in check_interrupt_map()
1625 irq_map_prop->val.len, sizeof(cell_t)); in check_interrupt_map()
1629 map_cells = irq_map_prop->val.len / sizeof(cell_t); in check_interrupt_map()
1637 FAIL_PROP(c, dti, node, irq_map_prop, in check_interrupt_map()
1639 irq_map_prop->val.len, (cell + cellsize) * sizeof(cell_t)); in check_interrupt_map()
1647 if (!(dti->dtsflags & DTSF_PLUGIN)) in check_interrupt_map()
1648 FAIL_PROP(c, dti, node, irq_map_prop, in check_interrupt_map()
1656 FAIL_PROP(c, dti, node, irq_map_prop, in check_interrupt_map()
1662 cellprop = get_property(provider_node, "#interrupt-cells"); in check_interrupt_map()
1666 …FAIL(c, dti, node, "Missing property '#interrupt-cells' in node %s or bad phandle (referred from i… in check_interrupt_map()
1667 provider_node->fullpath, cell); in check_interrupt_map()
1671 cellprop = get_property(provider_node, "#address-cells"); in check_interrupt_map()
1680 static void check_interrupts_property(struct check *c, in check_interrupts_property() argument
1684 struct node *root = dti->dt; in check_interrupts_property()
1693 if (!is_multiple_of(irq_prop->val.len, sizeof(cell_t))) in check_interrupts_property()
1694 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", in check_interrupts_property()
1695 irq_prop->val.len, sizeof(cell_t)); in check_interrupts_property()
1703 prop = get_property(parent, "interrupt-parent"); in check_interrupts_property()
1709 if (dti->dtsflags & DTSF_PLUGIN) in check_interrupts_property()
1711 FAIL_PROP(c, dti, parent, prop, "Invalid phandle"); in check_interrupts_property()
1717 FAIL_PROP(c, dti, parent, prop, "Bad phandle"); in check_interrupts_property()
1721 FAIL(c, dti, irq_node, in check_interrupts_property()
1722 "Missing interrupt-controller or interrupt-map property"); in check_interrupts_property()
1727 parent = parent->parent; in check_interrupts_property()
1731 FAIL(c, dti, node, "Missing interrupt-parent"); in check_interrupts_property()
1735 prop = get_property(irq_node, "#interrupt-cells"); in check_interrupts_property()
1742 if (!is_multiple_of(irq_prop->val.len, irq_cells * sizeof(cell_t))) { in check_interrupts_property()
1743 FAIL_PROP(c, dti, node, prop, in check_interrupts_property()
1745 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); in check_interrupts_property()
1751 .name = "graph-port",
1755 .name = "graph-ports",
1758 static void check_graph_nodes(struct check *c, struct dt_info *dti, in check_graph_nodes() argument
1764 if (!(strprefixeq(child->name, child->basenamelen, "endpoint") || in check_graph_nodes()
1765 get_property(child, "remote-endpoint"))) in check_graph_nodes()
1768 node->bus = &graph_port_bus; in check_graph_nodes()
1771 if (!node->parent->bus && in check_graph_nodes()
1772 (streq(node->parent->name, "ports") || get_property(node, "reg"))) in check_graph_nodes()
1773 node->parent->bus = &graph_ports_bus; in check_graph_nodes()
1781 static void check_graph_child_address(struct check *c, struct dt_info *dti, in check_graph_child_address() argument
1787 if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) in check_graph_child_address()
1793 /* No error if we have any non-zero unit address */ in check_graph_child_address()
1800 if (cnt == 1 && node->addr_cells != -1) in check_graph_child_address()
1801 …FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not nece… in check_graph_child_address()
1802 node->children->name); in check_graph_child_address()
1806 static void check_graph_reg(struct check *c, struct dt_info *dti, in check_graph_reg() argument
1817 if (!(prop->val.val && prop->val.len == sizeof(cell_t))) { in check_graph_reg()
1818 FAIL(c, dti, node, "graph node malformed 'reg' property"); in check_graph_reg()
1824 FAIL(c, dti, node, "graph node unit address error, expected \"%s\"", in check_graph_reg()
1827 if (node->parent->addr_cells != 1) in check_graph_reg()
1828 FAIL_PROP(c, dti, node, get_property(node, "#address-cells"), in check_graph_reg()
1829 "graph node '#address-cells' is %d, must be 1", in check_graph_reg()
1830 node->parent->addr_cells); in check_graph_reg()
1831 if (node->parent->size_cells != 0) in check_graph_reg()
1832 FAIL_PROP(c, dti, node, get_property(node, "#size-cells"), in check_graph_reg()
1833 "graph node '#size-cells' is %d, must be 0", in check_graph_reg()
1834 node->parent->size_cells); in check_graph_reg()
1837 static void check_graph_port(struct check *c, struct dt_info *dti, in check_graph_port() argument
1840 if (node->bus != &graph_port_bus) in check_graph_port()
1843 if (!strprefixeq(node->name, node->basenamelen, "port")) in check_graph_port()
1844 FAIL(c, dti, node, "graph port node name should be 'port'"); in check_graph_port()
1846 check_graph_reg(c, dti, node); in check_graph_port()
1850 static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, in get_remote_endpoint() argument
1857 prop = get_property(endpoint, "remote-endpoint"); in get_remote_endpoint()
1866 node = get_node_by_phandle(dti->dt, phandle); in get_remote_endpoint()
1868 FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid"); in get_remote_endpoint()
1873 static void check_graph_endpoint(struct check *c, struct dt_info *dti, in check_graph_endpoint() argument
1878 if (!node->parent || node->parent->bus != &graph_port_bus) in check_graph_endpoint()
1881 if (!strprefixeq(node->name, node->basenamelen, "endpoint")) in check_graph_endpoint()
1882 FAIL(c, dti, node, "graph endpoint node name should be 'endpoint'"); in check_graph_endpoint()
1884 check_graph_reg(c, dti, node); in check_graph_endpoint()
1886 remote_node = get_remote_endpoint(c, dti, node); in check_graph_endpoint()
1890 if (get_remote_endpoint(c, dti, remote_node) != node) in check_graph_endpoint()
1891 FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional", in check_graph_endpoint()
1892 remote_node->fullpath); in check_graph_endpoint()
1987 static void enable_warning_error(struct check *c, bool warn, bool error) in enable_warning_error() argument
1992 if ((warn && !c->warn) || (error && !c->error)) in enable_warning_error()
1993 for (i = 0; i < c->num_prereqs; i++) in enable_warning_error()
1994 enable_warning_error(c->prereq[i], warn, error); in enable_warning_error()
1996 c->warn = c->warn || warn; in enable_warning_error()
1997 c->error = c->error || error; in enable_warning_error()
2000 static void disable_warning_error(struct check *c, bool warn, bool error) in disable_warning_error() argument
2006 if ((warn && c->warn) || (error && c->error)) { in disable_warning_error()
2011 for (j = 0; j < cc->num_prereqs; j++) in disable_warning_error()
2012 if (cc->prereq[j] == c) in disable_warning_error()
2017 c->warn = c->warn && !warn; in disable_warning_error()
2018 c->error = c->error && !error; in disable_warning_error()
2024 const char *name = arg; in parse_checks_option() local
2027 if ((strncmp(arg, "no-", 3) == 0) in parse_checks_option()
2029 name = arg + 3; in parse_checks_option()
2034 struct check *c = check_table[i]; in parse_checks_option() local
2036 if (streq(c->name, name)) { in parse_checks_option()
2038 enable_warning_error(c, warn, error); in parse_checks_option()
2040 disable_warning_error(c, warn, error); in parse_checks_option()
2045 die("Unrecognized check name \"%s\"\n", name); in parse_checks_option()
2054 struct check *c = check_table[i]; in process_checks() local
2056 if (c->warn || c->error) in process_checks()
2057 error = error || run_check(c, dti); in process_checks()
2063 "(use -f to force output)\n"); in process_checks()