netdevices.mk: add missing dependency to kmod-hwmon-core
[openwrt/staging/wigyori.git] / package / kernel / dtc / patches / 0001-scripts-dtc-Update-to-version-with-overlays.patch
1 From 5f84cb93eef9f8a8ff7f49d593893f252744d0fe Mon Sep 17 00:00:00 2001
2 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
3 Date: Wed, 26 Aug 2015 18:28:08 +0300
4 Subject: [PATCH] scripts/dtc: Update to version with overlays
5
6 Update to mainline dtc with overlay support
7
8 Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
9 ---
10 checks.c | 20 +++++-
11 dtc-lexer.l | 5 ++
12 dtc-parser.y | 54 ++++++++++++++--
13 dtc.c | 83 ++++++++++++++++++++++--
14 dtc.h | 13 +++-
15 livetree.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16 treesource.c | 3 +
17 util.c | 2 +-
18 8 files changed, 367 insertions(+), 15 deletions(-)
19
20 diff --git a/checks.c b/checks.c
21 index 3bf0fa4..af25c2b 100644
22 --- a/checks.c
23 +++ b/checks.c
24 @@ -465,8 +465,12 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
25
26 refnode = get_node_by_ref(dt, m->ref);
27 if (! refnode) {
28 - FAIL(c, "Reference to non-existent node or label \"%s\"\n",
29 - m->ref);
30 + if (!source_is_plugin)
31 + FAIL(c, "Reference to non-existent node or "
32 + "label \"%s\"\n", m->ref);
33 + else /* mark the entry as unresolved */
34 + *((cell_t *)(prop->val.val + m->offset)) =
35 + cpu_to_fdt32(0xffffffff);
36 continue;
37 }
38
39 @@ -559,7 +563,7 @@ static void check_reg_format(struct check *c, struct node *dt,
40 size_cells = node_size_cells(node->parent);
41 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
42
43 - if ((prop->val.len % entrylen) != 0)
44 + if (!entrylen || (prop->val.len % entrylen) != 0)
45 FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
46 "(#address-cells == %d, #size-cells == %d)",
47 node->fullpath, prop->val.len, addr_cells, size_cells);
48 @@ -651,6 +655,15 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
49 }
50 TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
51
52 +static void check_deprecated_plugin_syntax(struct check *c,
53 + struct node *dt)
54 +{
55 + if (deprecated_plugin_syntax_warning)
56 + FAIL(c, "Use '/dts-v1/ /plugin/'; syntax. /dts-v1/; /plugin/; "
57 + "is going to be removed in next versions");
58 +}
59 +TREE_WARNING(deprecated_plugin_syntax, NULL);
60 +
61 static struct check *check_table[] = {
62 &duplicate_node_names, &duplicate_property_names,
63 &node_name_chars, &node_name_format, &property_name_chars,
64 @@ -668,6 +681,7 @@ static struct check *check_table[] = {
65
66 &avoid_default_addr_size,
67 &obsolete_chosen_interrupt_controller,
68 + &deprecated_plugin_syntax,
69
70 &always_fail,
71 };
72 diff --git a/dtc-lexer.l b/dtc-lexer.l
73 index 0ee1caf..dd44ba2 100644
74 --- a/dtc-lexer.l
75 +++ b/dtc-lexer.l
76 @@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...);
77 return DT_V1;
78 }
79
80 +<*>"/plugin/" {
81 + DPRINT("Keyword: /plugin/\n");
82 + return DT_PLUGIN;
83 + }
84 +
85 <*>"/memreserve/" {
86 DPRINT("Keyword: /memreserve/\n");
87 BEGIN_DEFAULT();
88 diff --git a/dtc-parser.y b/dtc-parser.y
89 index ea57e0a..7d9652d 100644
90 --- a/dtc-parser.y
91 +++ b/dtc-parser.y
92 @@ -19,6 +19,7 @@
93 */
94 %{
95 #include <stdio.h>
96 +#include <inttypes.h>
97
98 #include "dtc.h"
99 #include "srcpos.h"
100 @@ -52,9 +53,11 @@ extern bool treesource_error;
101 struct node *nodelist;
102 struct reserve_info *re;
103 uint64_t integer;
104 + bool is_plugin;
105 }
106
107 %token DT_V1
108 +%token DT_PLUGIN
109 %token DT_MEMRESERVE
110 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
111 %token DT_BITS
112 @@ -71,6 +74,7 @@ extern bool treesource_error;
113
114 %type <data> propdata
115 %type <data> propdataprefix
116 +%type <is_plugin> plugindecl
117 %type <re> memreserve
118 %type <re> memreserves
119 %type <array> arrayprefix
120 @@ -101,10 +105,39 @@ extern bool treesource_error;
121 %%
122
123 sourcefile:
124 - DT_V1 ';' memreserves devicetree
125 + basesource
126 + | pluginsource
127 + ;
128 +
129 +basesource:
130 + DT_V1 ';' plugindecl memreserves devicetree
131 + {
132 + source_is_plugin = $3;
133 + if (source_is_plugin)
134 + deprecated_plugin_syntax_warning = true;
135 + the_boot_info = build_boot_info($4, $5,
136 + guess_boot_cpuid($5));
137 + }
138 + ;
139 +
140 +plugindecl:
141 + /* empty */
142 + {
143 + $$ = false;
144 + }
145 + | DT_PLUGIN ';'
146 + {
147 + $$ = true;
148 + }
149 + ;
150 +
151 +pluginsource:
152 + DT_V1 DT_PLUGIN ';' memreserves devicetree
153 {
154 - the_boot_info = build_boot_info($3, $4,
155 - guess_boot_cpuid($4));
156 + source_is_plugin = true;
157 + deprecated_plugin_syntax_warning = false;
158 + the_boot_info = build_boot_info($4, $5,
159 + guess_boot_cpuid($5));
160 }
161 ;
162
163 @@ -144,10 +177,14 @@ devicetree:
164 {
165 struct node *target = get_node_by_ref($1, $2);
166
167 - if (target)
168 + if (target) {
169 merge_nodes(target, $3);
170 - else
171 - ERROR(&@2, "Label or path %s not found", $2);
172 + } else {
173 + if (symbol_fixup_support)
174 + add_orphan_node($1, $3, $2);
175 + else
176 + ERROR(&@2, "Label or path %s not found", $2);
177 + }
178 $$ = $1;
179 }
180 | devicetree DT_DEL_NODE DT_REF ';'
181 @@ -162,6 +199,11 @@ devicetree:
182
183 $$ = $1;
184 }
185 + | /* empty */
186 + {
187 + /* build empty node */
188 + $$ = name_node(build_node(NULL, NULL), "");
189 + }
190 ;
191
192 nodedef:
193 diff --git a/dtc.c b/dtc.c
194 index 8c4add6..ee37be9 100644
195 --- a/dtc.c
196 +++ b/dtc.c
197 @@ -18,6 +18,8 @@
198 * USA
199 */
200
201 +#include <sys/stat.h>
202 +
203 #include "dtc.h"
204 #include "srcpos.h"
205
206 @@ -29,6 +31,8 @@ int reservenum; /* Number of memory reservation slots */
207 int minsize; /* Minimum blob size */
208 int padsize; /* Additional padding to blob */
209 int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
210 +int symbol_fixup_support;
211 +int auto_label_aliases;
212
213 static void fill_fullpaths(struct node *tree, const char *prefix)
214 {
215 @@ -51,7 +55,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
216 #define FDT_VERSION(version) _FDT_VERSION(version)
217 #define _FDT_VERSION(version) #version
218 static const char usage_synopsis[] = "dtc [options] <input file>";
219 -static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv";
220 +static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:@Ahv";
221 static struct option const usage_long_opts[] = {
222 {"quiet", no_argument, NULL, 'q'},
223 {"in-format", a_argument, NULL, 'I'},
224 @@ -69,6 +73,8 @@ static struct option const usage_long_opts[] = {
225 {"phandle", a_argument, NULL, 'H'},
226 {"warning", a_argument, NULL, 'W'},
227 {"error", a_argument, NULL, 'E'},
228 + {"symbols", no_argument, NULL, '@'},
229 + {"auto-alias", no_argument, NULL, 'A'},
230 {"help", no_argument, NULL, 'h'},
231 {"version", no_argument, NULL, 'v'},
232 {NULL, no_argument, NULL, 0x0},
233 @@ -99,16 +105,63 @@ static const char * const usage_opts_help[] = {
234 "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
235 "\n\tEnable/disable warnings (prefix with \"no-\")",
236 "\n\tEnable/disable errors (prefix with \"no-\")",
237 + "\n\tEnable symbols/fixup support",
238 + "\n\tEnable auto-alias of labels",
239 "\n\tPrint this help and exit",
240 "\n\tPrint version and exit",
241 NULL,
242 };
243
244 +static const char *guess_type_by_name(const char *fname, const char *fallback)
245 +{
246 + const char *s;
247 +
248 + s = strrchr(fname, '.');
249 + if (s == NULL)
250 + return fallback;
251 + if (!strcasecmp(s, ".dts"))
252 + return "dts";
253 + if (!strcasecmp(s, ".dtb"))
254 + return "dtb";
255 + return fallback;
256 +}
257 +
258 +static const char *guess_input_format(const char *fname, const char *fallback)
259 +{
260 + struct stat statbuf;
261 + uint32_t magic;
262 + FILE *f;
263 +
264 + if (stat(fname, &statbuf) != 0)
265 + return fallback;
266 +
267 + if (S_ISDIR(statbuf.st_mode))
268 + return "fs";
269 +
270 + if (!S_ISREG(statbuf.st_mode))
271 + return fallback;
272 +
273 + f = fopen(fname, "r");
274 + if (f == NULL)
275 + return fallback;
276 + if (fread(&magic, 4, 1, f) != 1) {
277 + fclose(f);
278 + return fallback;
279 + }
280 + fclose(f);
281 +
282 + magic = fdt32_to_cpu(magic);
283 + if (magic == FDT_MAGIC)
284 + return "dtb";
285 +
286 + return guess_type_by_name(fname, fallback);
287 +}
288 +
289 int main(int argc, char *argv[])
290 {
291 struct boot_info *bi;
292 - const char *inform = "dts";
293 - const char *outform = "dts";
294 + const char *inform = NULL;
295 + const char *outform = NULL;
296 const char *outname = "-";
297 const char *depname = NULL;
298 bool force = false, sort = false;
299 @@ -186,7 +239,12 @@ int main(int argc, char *argv[])
300 case 'E':
301 parse_checks_option(false, true, optarg);
302 break;
303 -
304 + case '@':
305 + symbol_fixup_support = 1;
306 + break;
307 + case 'A':
308 + auto_label_aliases = 1;
309 + break;
310 case 'h':
311 usage(NULL);
312 default:
313 @@ -213,6 +271,17 @@ int main(int argc, char *argv[])
314 fprintf(depfile, "%s:", outname);
315 }
316
317 + if (inform == NULL)
318 + inform = guess_input_format(arg, "dts");
319 + if (outform == NULL) {
320 + outform = guess_type_by_name(outname, NULL);
321 + if (outform == NULL) {
322 + if (streq(inform, "dts"))
323 + outform = "dtb";
324 + else
325 + outform = "dts";
326 + }
327 + }
328 if (streq(inform, "dts"))
329 bi = dt_from_source(arg);
330 else if (streq(inform, "fs"))
331 @@ -236,6 +305,12 @@ int main(int argc, char *argv[])
332 if (sort)
333 sort_tree(bi);
334
335 + if (symbol_fixup_support || auto_label_aliases)
336 + generate_label_node(bi->dt, bi->dt);
337 +
338 + if (symbol_fixup_support)
339 + generate_fixups_node(bi->dt, bi->dt);
340 +
341 if (streq(outname, "-")) {
342 outf = stdout;
343 } else {
344 diff --git a/dtc.h b/dtc.h
345 index 56212c8..d025111 100644
346 --- a/dtc.h
347 +++ b/dtc.h
348 @@ -20,7 +20,7 @@
349 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
350 * USA
351 */
352 -
353 +#define _GNU_SOURCE
354 #include <stdio.h>
355 #include <string.h>
356 #include <stdlib.h>
357 @@ -54,6 +54,14 @@ extern int reservenum; /* Number of memory reservation slots */
358 extern int minsize; /* Minimum blob size */
359 extern int padsize; /* Additional padding to blob */
360 extern int phandle_format; /* Use linux,phandle or phandle properties */
361 +extern int symbol_fixup_support;/* enable symbols & fixup support */
362 +extern int auto_label_aliases; /* auto generate labels -> aliases */
363 +
364 +/*
365 + * Tree source globals
366 + */
367 +extern bool source_is_plugin;
368 +extern bool deprecated_plugin_syntax_warning;
369
370 #define PHANDLE_LEGACY 0x1
371 #define PHANDLE_EPAPR 0x2
372 @@ -194,6 +202,7 @@ struct node *build_node_delete(void);
373 struct node *name_node(struct node *node, char *name);
374 struct node *chain_node(struct node *first, struct node *list);
375 struct node *merge_nodes(struct node *old_node, struct node *new_node);
376 +void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
377
378 void add_property(struct node *node, struct property *prop);
379 void delete_property_by_name(struct node *node, char *name);
380 @@ -244,6 +253,8 @@ struct boot_info {
381 struct boot_info *build_boot_info(struct reserve_info *reservelist,
382 struct node *tree, uint32_t boot_cpuid_phys);
383 void sort_tree(struct boot_info *bi);
384 +void generate_label_node(struct node *node, struct node *dt);
385 +void generate_fixups_node(struct node *node, struct node *dt);
386
387 /* Checks */
388
389 diff --git a/livetree.c b/livetree.c
390 index e229b84..1ef9fc4 100644
391 --- a/livetree.c
392 +++ b/livetree.c
393 @@ -216,6 +216,34 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
394 return old_node;
395 }
396
397 +void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
398 +{
399 + static unsigned int next_orphan_fragment = 0;
400 + struct node *ovl = xmalloc(sizeof(*ovl));
401 + struct property *p;
402 + struct data d = empty_data;
403 + char *name;
404 + int ret;
405 +
406 + memset(ovl, 0, sizeof(*ovl));
407 +
408 + d = data_add_marker(d, REF_PHANDLE, ref);
409 + d = data_append_integer(d, 0xffffffff, 32);
410 +
411 + p = build_property("target", d);
412 + add_property(ovl, p);
413 +
414 + ret = asprintf(&name, "fragment@%u",
415 + next_orphan_fragment++);
416 + if (ret == -1)
417 + die("asprintf() failed\n");
418 + name_node(ovl, name);
419 + name_node(new_node, "__overlay__");
420 +
421 + add_child(dt, ovl);
422 + add_child(ovl, new_node);
423 +}
424 +
425 struct node *chain_node(struct node *first, struct node *list)
426 {
427 assert(first->next_sibling == NULL);
428 @@ -709,3 +737,177 @@ void sort_tree(struct boot_info *bi)
429 sort_reserve_entries(bi);
430 sort_node(bi->dt);
431 }
432 +
433 +void generate_label_node(struct node *node, struct node *dt)
434 +{
435 + struct node *c, *an;
436 + struct property *p;
437 + struct label *l;
438 + int has_label;
439 + char *gen_node_name;
440 +
441 + if (auto_label_aliases)
442 + gen_node_name = "aliases";
443 + else
444 + gen_node_name = "__symbols__";
445 +
446 + /* Make sure the label isn't already there */
447 + has_label = 0;
448 + for_each_label(node->labels, l) {
449 + has_label = 1;
450 + break;
451 + }
452 +
453 + if (has_label) {
454 +
455 + /* an is the aliases/__symbols__ node */
456 + an = get_subnode(dt, gen_node_name);
457 + /* if no node exists, create it */
458 + if (!an) {
459 + an = build_node(NULL, NULL);
460 + name_node(an, gen_node_name);
461 + add_child(dt, an);
462 + }
463 +
464 + /* now add the label in the node */
465 + for_each_label(node->labels, l) {
466 + /* check whether the label already exists */
467 + p = get_property(an, l->label);
468 + if (p) {
469 + fprintf(stderr, "WARNING: label %s already"
470 + " exists in /%s", l->label,
471 + gen_node_name);
472 + continue;
473 + }
474 +
475 + /* insert it */
476 + p = build_property(l->label,
477 + data_copy_escape_string(node->fullpath,
478 + strlen(node->fullpath)));
479 + add_property(an, p);
480 + }
481 +
482 + /* force allocation of a phandle for this node */
483 + if (symbol_fixup_support)
484 + (void)get_node_phandle(dt, node);
485 + }
486 +
487 + for_each_child(node, c)
488 + generate_label_node(c, dt);
489 +}
490 +
491 +static void add_fixup_entry(struct node *dt, struct node *node,
492 + struct property *prop, struct marker *m)
493 +{
494 + struct node *fn; /* local fixup node */
495 + struct property *p;
496 + char *fixups_name = "__fixups__";
497 + struct data d;
498 + char *entry;
499 + int ret;
500 +
501 + /* fn is the node we're putting entries in */
502 + fn = get_subnode(dt, fixups_name);
503 + /* if no node exists, create it */
504 + if (!fn) {
505 + fn = build_node(NULL, NULL);
506 + name_node(fn, fixups_name);
507 + add_child(dt, fn);
508 + }
509 +
510 + ret = asprintf(&entry, "%s:%s:%u",
511 + node->fullpath, prop->name, m->offset);
512 + if (ret == -1)
513 + die("asprintf() failed\n");
514 +
515 + p = get_property(fn, m->ref);
516 + d = data_append_data(p ? p->val : empty_data, entry, strlen(entry) + 1);
517 + if (!p)
518 + add_property(fn, build_property(m->ref, d));
519 + else
520 + p->val = d;
521 +}
522 +
523 +static void add_local_fixup_entry(struct node *dt, struct node *node,
524 + struct property *prop, struct marker *m,
525 + struct node *refnode)
526 +{
527 + struct node *lfn, *wn, *nwn; /* local fixup node, walk node, new */
528 + struct property *p;
529 + struct data d;
530 + char *local_fixups_name = "__local_fixups__";
531 + char *s, *e, *comp;
532 + int len;
533 +
534 + /* fn is the node we're putting entries in */
535 + lfn = get_subnode(dt, local_fixups_name);
536 + /* if no node exists, create it */
537 + if (!lfn) {
538 + lfn = build_node(NULL, NULL);
539 + name_node(lfn, local_fixups_name);
540 + add_child(dt, lfn);
541 + }
542 +
543 + /* walk the path components creating nodes if they don't exist */
544 + comp = NULL;
545 + /* start skipping the first / */
546 + s = node->fullpath + 1;
547 + wn = lfn;
548 + while (*s) {
549 + /* retrieve path component */
550 + e = strchr(s, '/');
551 + if (e == NULL)
552 + e = s + strlen(s);
553 + len = e - s;
554 + comp = xrealloc(comp, len + 1);
555 + memcpy(comp, s, len);
556 + comp[len] = '\0';
557 +
558 + /* if no node exists, create it */
559 + nwn = get_subnode(wn, comp);
560 + if (!nwn) {
561 + nwn = build_node(NULL, NULL);
562 + name_node(nwn, strdup(comp));
563 + add_child(wn, nwn);
564 + }
565 + wn = nwn;
566 +
567 + /* last path component */
568 + if (!*e)
569 + break;
570 +
571 + /* next path component */
572 + s = e + 1;
573 + }
574 + free(comp);
575 +
576 + p = get_property(wn, prop->name);
577 + d = data_append_cell(p ? p->val : empty_data, (cell_t)m->offset);
578 + if (!p)
579 + add_property(wn, build_property(prop->name, d));
580 + else
581 + p->val = d;
582 +}
583 +
584 +void generate_fixups_node(struct node *node, struct node *dt)
585 +{
586 + struct node *c;
587 + struct property *prop;
588 + struct marker *m;
589 + struct node *refnode;
590 +
591 + for_each_property(node, prop) {
592 + m = prop->val.markers;
593 + for_each_marker_of_type(m, REF_PHANDLE) {
594 + refnode = get_node_by_ref(dt, m->ref);
595 + if (!refnode)
596 + add_fixup_entry(dt, node, prop, m);
597 + else
598 + add_local_fixup_entry(dt, node, prop, m,
599 + refnode);
600 + }
601 + }
602 +
603 + for_each_child(node, c)
604 + generate_fixups_node(c, dt);
605 +}
606 diff --git a/treesource.c b/treesource.c
607 index a55d1d1..e1d6657 100644
608 --- a/treesource.c
609 +++ b/treesource.c
610 @@ -28,6 +28,9 @@ extern YYLTYPE yylloc;
611 struct boot_info *the_boot_info;
612 bool treesource_error;
613
614 +bool source_is_plugin;
615 +bool deprecated_plugin_syntax_warning;
616 +
617 struct boot_info *dt_from_source(const char *fname)
618 {
619 the_boot_info = NULL;
620 diff --git a/util.c b/util.c
621 index 9d65226..cbb945b 100644
622 --- a/util.c
623 +++ b/util.c
624 @@ -349,7 +349,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size)
625 void utilfdt_print_data(const char *data, int len)
626 {
627 int i;
628 - const char *p = data;
629 const char *s;
630
631 /* no data, don't print */
632 @@ -376,6 +375,7 @@ void utilfdt_print_data(const char *data, int len)
633 i < (len - 1) ? " " : "");
634 printf(">");
635 } else {
636 + const unsigned char *p = (const unsigned char *)data;
637 printf(" = [");
638 for (i = 0; i < len; i++)
639 printf("%02x%s", *p++, i < len - 1 ? " " : "");
640 --
641 2.7.0
642