~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/dtc/checks.c

Version: ~ [ linux-5.0-rc6 ] ~ [ linux-4.20.10 ] ~ [ linux-4.19.23 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.101 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.158 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.174 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.134 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp