cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

checks.c (54981B)


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