Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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