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, &reg_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, &reg_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, &reg_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, &reg_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