History

scripts/dtc: Update to upstream version v1.4.5-3-gb1a60033c110

This adds the following commits from upstream: b1a60033c110 tests: Add a test for overlays syntactic sugar 737b2df39cc8 overlay: Add syntactic sugar version of overlays 497432fd2131 checks: Use proper format modifier for size_t 22a65c5331c2 dtc: Bump version to v1.4.5 c575d8059fff Add fdtoverlay to .gitignore b6a6f9490d19 fdtoverlay: Sanity check blob size 8c1eb1526d2d pylibfdt: Use Python2 explicitly ee3d26f6960b checks: add interrupts property check c1e7738988f5 checks: add gpio binding properties check b3bbac02d5e3 checks: add phandle with arg property checks fe50bd1ecc1d fdtget: Split out cell list display into a new function 62d812308d11 README: Add a note about test_tree1.dts 5bed86aee9e8 pylibfdt: Add support for fdt_subnode_offset() 46f31b65b3b3 pylibfdt: Add support for fdt_node_offset_by_phandle() a3ae43723687 pylibfdt: Add support for fdt_parent_offset() a198af80344c pylibfdt: Add support for fdt_get_phandle() b9eba92ea50f tests: Return a failure code when any tests fail 155faf6cc209 pylibfdt: Use local pylibfdt module 50e5cd07f325 pylibfdt: Add a test for use of uint32_t ab78860f09f5 pylibfdt: Add stdint include to fix uint32_t 36f511fb1113 tests: Add stacked overlay tests on fdtoverlay 1bb00655d3e5 fdt: Allow stacked overlays phandle references a33c2247ac8d Introduce fdt_setprop_placeholder() method 0016f8c2aa32 dtc: change default phandles to ePAPR style instead of both e3b9a9588a35 tests: fdtoverlay unit test 42409146f2db fdtoverlay: A tool that applies overlays aae22722fc8d manual: Document missing options 13ce6e1c2fc4 dtc: fix sprintf() format string error, again d990b8013889 Makefile: Fix build on MSYS2 and Cygwin 51f56dedf8ea Clean up shared library compile/link options 21a2bc896e3d Suppress expected error message in fdtdump test 2a42b14d0d03 dtc: check.c fix compile error a10cb3c818d3 Fix get_node_by_path string equality check 548aea2c436a fdtdump: Discourage use of fdtdump c2258841a785 fdtdump: Fix over-zealous version check 9067ee4be0e6 Fix a few whitespace and style nits e56f2b07be38 pylibfdt: Use setup.py to build the swig file 896f1c133265 pylibfdt: Use Makefile constructs to implement NO_PYTHON 90db6d9989ca pylibfdt: Allow setup.py to operate stand-alone e20d9658cd8f Add Coverity Scan support b04a2cf08862 pylibfdt: Fix code style in setup.py 1c5170d3a466 pylibfdt: Rename libfdt.swig to libfdt.i 580a9f6c2880 Add a libfdt function to write a property placeholder ab15256d8d02 pylibfdt: Use the call function to simplify the Makefile 9f2e3a3a1f19 pylibfdt: Use the correct libfdt version in the module e91c652af215 pylibfdt: Enable installation of Python module 8a892fd85d94 pylibfdt: Allow building to be disabled 741cdff85d3e .travis.yml: Add builds with and without Python library prerequisites 14c4171f4f9a pylibfdt: Use package_dir to set the package directory 89a5062ab231 pylibfdt: Use environment to pass C flags and files 4e0e0d049757 pylibfdt: Allow pkg-config to be supplied in the environment 6afd7d9688f5 Correct typo: s/pylibgfdt/pylibfdt/

Rob Herring committed 9 years ago

Commit 4201d051 parent 432232316 files · +1603 −230Browse files

Showing the changes to scripts/dtc (16 of 16 files). Show all

Unified · Split

16 files
  1. scripts/dtc/checks.c +281 −1
  2. scripts/dtc/dtc-lexer.lex.c_shipped +5 −5
  3. scripts/dtc/dtc-parser.tab.c_shipped +224 −206
  4. scripts/dtc/dtc-parser.y +17 −3
  5. scripts/dtc/dtc.c +1 −1
  6. scripts/dtc/dtc.h +3 −0
  7. scripts/dtc/libfdt/fdt_addresses.c +96 −0
  8. scripts/dtc/libfdt/fdt_empty_tree.c +0 −1
  9. scripts/dtc/libfdt/fdt_overlay.c +861 −0
  10. scripts/dtc/libfdt/fdt_ro.c +2 −2
  11. scripts/dtc/libfdt/fdt_rw.c +19 −5
  12. scripts/dtc/libfdt/fdt_sw.c +14 −2
  13. scripts/dtc/libfdt/fdt_wip.c +2 −2
  14. scripts/dtc/libfdt/libfdt.h +47 −0
  15. scripts/dtc/livetree.c +30 −1
  16. scripts/dtc/version_gen.h +1 −1
scripts/dtc/checks.c+281−1
@@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no · 872 unmodified lines
873873 while (size--)
874874 reg = (reg << 32) | fdt32_to_cpu(*(cells++));
875875
876− snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg);
876+ snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
877877 if (!streq(unitname, unit_addr))
878878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
879879 node->fullpath, unit_addr);
@@ -956,6 +956,265 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, · 76 unmodified lines
956956 WARNING(obsolete_chosen_interrupt_controller,
957957 check_obsolete_chosen_interrupt_controller, NULL);
958958
959+struct provider {
960+ const char *prop_name;
961+ const char *cell_name;
962+ bool optional;
963+};
964+
965+static void check_property_phandle_args(struct check *c,
966+ struct dt_info *dti,
967+ struct node *node,
968+ struct property *prop,
969+ const struct provider *provider)
970+{
971+ struct node *root = dti->dt;
972+ int cell, cellsize = 0;
973+
974+ if (prop->val.len % sizeof(cell_t)) {
975+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
976+ prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
977+ return;
978+ }
979+
980+ for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
981+ struct node *provider_node;
982+ struct property *cellprop;
983+ int phandle;
984+
985+ phandle = propval_cell_n(prop, cell);
986+ /*
987+ * Some bindings use a cell value 0 or -1 to skip over optional
988+ * entries when each index position has a specific definition.
989+ */
990+ if (phandle == 0 || phandle == -1) {
991+ cellsize = 0;
992+ continue;
993+ }
994+
995+ /* If we have markers, verify the current cell is a phandle */
996+ if (prop->val.markers) {
997+ struct marker *m = prop->val.markers;
998+ for_each_marker_of_type(m, REF_PHANDLE) {
999+ if (m->offset == (cell * sizeof(cell_t)))
1000+ break;
1001+ }
1002+ if (!m)
1003+ FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
1004+ prop->name, cell, node->fullpath);
1005+ }
1006+
1007+ provider_node = get_node_by_phandle(root, phandle);
1008+ if (!provider_node) {
1009+ FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
1010+ node->fullpath, prop->name, cell);
1011+ break;
1012+ }
1013+
1014+ cellprop = get_property(provider_node, provider->cell_name);
1015+ if (cellprop) {
1016+ cellsize = propval_cell(cellprop);
1017+ } else if (provider->optional) {
1018+ cellsize = 0;
1019+ } else {
1020+ FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
1021+ provider->cell_name,
1022+ provider_node->fullpath,
1023+ node->fullpath, prop->name, cell);
1024+ break;
1025+ }
1026+
1027+ if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
1028+ FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
1029+ prop->name, prop->val.len, cellsize, node->fullpath);
1030+ }
1031+ }
1032+}
1033+
1034+static void check_provider_cells_property(struct check *c,
1035+ struct dt_info *dti,
1036+ struct node *node)
1037+{
1038+ struct provider *provider = c->data;
1039+ struct property *prop;
1040+
1041+ prop = get_property(node, provider->prop_name);
1042+ if (!prop)
1043+ return;
1044+
1045+ check_property_phandle_args(c, dti, node, prop, provider);
1046+}
1047+#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
1048+ static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
1049+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
1050+
1051+WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
1052+WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
1053+WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
1054+WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
1055+WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
1056+WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
1057+WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
1058+WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
1059+WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
1060+WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
1061+WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
1062+WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
1063+WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
1064+WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
1065+WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
1066+WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
1067+
1068+static bool prop_is_gpio(struct property *prop)
1069+{
1070+ char *str;
1071+
1072+ /*
1073+ * *-gpios and *-gpio can appear in property names,
1074+ * so skip over any false matches (only one known ATM)
1075+ */
1076+ if (strstr(prop->name, "nr-gpio"))
1077+ return false;
1078+
1079+ str = strrchr(prop->name, '-');
1080+ if (str)
1081+ str++;
1082+ else
1083+ str = prop->name;
1084+ if (!(streq(str, "gpios") || streq(str, "gpio")))
1085+ return false;
1086+
1087+ return true;
1088+}
1089+
1090+static void check_gpios_property(struct check *c,
1091+ struct dt_info *dti,
1092+ struct node *node)
1093+{
1094+ struct property *prop;
1095+
1096+ /* Skip GPIO hog nodes which have 'gpios' property */
1097+ if (get_property(node, "gpio-hog"))
1098+ return;
1099+
1100+ for_each_property(node, prop) {
1101+ struct provider provider;
1102+
1103+ if (!prop_is_gpio(prop))
1104+ continue;
1105+
1106+ provider.prop_name = prop->name;
1107+ provider.cell_name = "#gpio-cells";
1108+ provider.optional = false;
1109+ check_property_phandle_args(c, dti, node, prop, &provider);
1110+ }
1111+
1112+}
1113+WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
1114+
1115+static void check_deprecated_gpio_property(struct check *c,
1116+ struct dt_info *dti,
1117+ struct node *node)
1118+{
1119+ struct property *prop;
1120+
1121+ for_each_property(node, prop) {
1122+ char *str;
1123+
1124+ if (!prop_is_gpio(prop))
1125+ continue;
1126+
1127+ str = strstr(prop->name, "gpio");
1128+ if (!streq(str, "gpio"))
1129+ continue;
1130+
1131+ FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
1132+ node->fullpath, prop->name);
1133+ }
1134+
1135+}
1136+CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
1137+
1138+static bool node_is_interrupt_provider(struct node *node)
1139+{
1140+ struct property *prop;
1141+
1142+ prop = get_property(node, "interrupt-controller");
1143+ if (prop)
1144+ return true;
1145+
1146+ prop = get_property(node, "interrupt-map");
1147+ if (prop)
1148+ return true;
1149+
1150+ return false;
1151+}
1152+static void check_interrupts_property(struct check *c,
1153+ struct dt_info *dti,
1154+ struct node *node)
1155+{
1156+ struct node *root = dti->dt;
1157+ struct node *irq_node = NULL, *parent = node;
1158+ struct property *irq_prop, *prop = NULL;
1159+ int irq_cells, phandle;
1160+
1161+ irq_prop = get_property(node, "interrupts");
1162+ if (!irq_prop)
1163+ return;
1164+
1165+ if (irq_prop->val.len % sizeof(cell_t))
1166+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
1167+ irq_prop->name, irq_prop->val.len, sizeof(cell_t),
1168+ node->fullpath);
1169+
1170+ while (parent && !prop) {
1171+ if (parent != node && node_is_interrupt_provider(parent)) {
1172+ irq_node = parent;
1173+ break;
1174+ }
1175+
1176+ prop = get_property(parent, "interrupt-parent");
1177+ if (prop) {
1178+ phandle = propval_cell(prop);
1179+ irq_node = get_node_by_phandle(root, phandle);
1180+ if (!irq_node) {
1181+ FAIL(c, dti, "Bad interrupt-parent phandle for %s",
1182+ node->fullpath);
1183+ return;
1184+ }
1185+ if (!node_is_interrupt_provider(irq_node))
1186+ FAIL(c, dti,
1187+ "Missing interrupt-controller or interrupt-map property in %s",
1188+ irq_node->fullpath);
1189+
1190+ break;
1191+ }
1192+
1193+ parent = parent->parent;
1194+ }
1195+
1196+ if (!irq_node) {
1197+ FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
1198+ return;
1199+ }
1200+
1201+ prop = get_property(irq_node, "#interrupt-cells");
1202+ if (!prop) {
1203+ FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
1204+ irq_node->fullpath);
1205+ return;
1206+ }
1207+
1208+ irq_cells = propval_cell(prop);
1209+ if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
1210+ FAIL(c, dti,
1211+ "interrupts size is (%d), expected multiple of %d in %s",
1212+ irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
1213+ node->fullpath);
1214+ }
1215+}
1216+WARNING(interrupts_property, check_interrupts_property, &phandle_references);
1217+
9591218 static struct check *check_table[] = {
9601219 &duplicate_node_names, &duplicate_property_names,
9611220 &node_name_chars, &node_name_format, &property_name_chars,
@@ -987,6 +1246,27 @@ static struct check *check_table[] = { · 25 unmodified lines
9871246 &avoid_default_addr_size,
9881247 &obsolete_chosen_interrupt_controller,
9891248
1249+ &clocks_property,
1250+ &cooling_device_property,
1251+ &dmas_property,
1252+ &hwlocks_property,
1253+ &interrupts_extended_property,
1254+ &io_channels_property,
1255+ &iommus_property,
1256+ &mboxes_property,
1257+ &msi_parent_property,
1258+ &mux_controls_property,
1259+ &phys_property,
1260+ &power_domains_property,
1261+ &pwms_property,
1262+ &resets_property,
1263+ &sound_dais_property,
1264+ &thermal_sensors_property,
1265+
1266+ &deprecated_gpio_property,
1267+ &gpios_property,
1268+ &interrupts_property,
1269+
9901270 &always_fail,
9911271 };
9921272
scripts/dtc/dtc-lexer.lex.c_shipped+5−5
@@ -1397,7 +1397,7 @@ static int yy_get_next_buffer (void) · 1396 unmodified lines
13971397 {
13981398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
13991399 char *source = (yytext_ptr);
1400− yy_size_t number_to_move, i;
1400+ int number_to_move, i;
14011401 int ret_val;
14021402
14031403 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -1426,7 +1426,7 @@ static int yy_get_next_buffer (void) · 22 unmodified lines
14261426 /* Try to read more data. */
14271427
14281428 /* First move last chars to start of buffer. */
1429− number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
1429+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
14301430
14311431 for ( i = 0; i < number_to_move; ++i )
14321432 *(dest++) = *(source++);
@@ -1508,7 +1508,7 @@ static int yy_get_next_buffer (void) · 75 unmodified lines
15081508 else
15091509 ret_val = EOB_ACT_CONTINUE_SCAN;
15101510
1511− if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1511+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
15121512 /* Extend the array by 50%, plus the number we really need. */
15131513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
15141514 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
@@ -1987,10 +1987,10 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) · 472 unmodified lines
19871987 YY_BUFFER_STATE b;
19881988 char *buf;
19891989 yy_size_t n;
1990− yy_size_t i;
1990+ int i;
19911991
19921992 /* Get memory for full buffer, including space for trailing EOB's. */
1993− n = (yy_size_t) _yybytes_len + 2;
1993+ n = (yy_size_t) (_yybytes_len + 2);
19941994 buf = (char *) yyalloc(n );
19951995 if ( ! buf )
19961996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
scripts/dtc/dtc-parser.tab.c_shipped+224−206
@@ -448,7 +448,7 @@ union yyalloc · 447 unmodified lines
448448 /* YYNNTS -- Number of nonterminals. */
449449 #define YYNNTS 30
450450 /* YYNRULES -- Number of rules. */
451−#define YYNRULES 84
451+#define YYNRULES 85
452452 /* YYNSTATES -- Number of states. */
453453 #define YYNSTATES 149
454454
@@ -499,14 +499,14 @@ static const yytype_uint8 yytranslate[] = · 44 unmodified lines
499499 static const yytype_uint16 yyrline[] =
500500 {
501501 0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
502− 153, 161, 165, 170, 181, 191, 206, 214, 217, 224,
503− 228, 232, 236, 244, 248, 252, 256, 260, 276, 286,
504− 294, 297, 301, 308, 324, 329, 348, 362, 369, 370,
505− 371, 378, 382, 383, 387, 388, 392, 393, 397, 398,
506− 402, 403, 407, 408, 412, 413, 414, 418, 419, 420,
507− 421, 422, 426, 427, 428, 432, 433, 434, 438, 439,
508− 448, 457, 461, 462, 463, 464, 469, 472, 476, 484,
509− 487, 491, 499, 503, 507
502+ 153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
503+ 238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
504+ 300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
505+ 384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
506+ 412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
507+ 434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
508+ 453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
509+ 498, 501, 505, 513, 517, 521
510510 };
511511 #endif
512512
@@ -582,20 +582,20 @@ static const yytype_int8 yypact[] = · 69 unmodified lines
582582 static const yytype_uint8 yydefact[] =
583583 {
584584 0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
585− 0, 7, 0, 38, 39, 0, 0, 10, 0, 2,
586− 8, 4, 0, 0, 0, 72, 0, 41, 42, 44,
587− 46, 48, 50, 52, 54, 57, 64, 67, 71, 0,
588− 17, 11, 0, 0, 0, 0, 73, 74, 75, 40,
585+ 16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
586+ 8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
587+ 47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
588+ 18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
589589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590590 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
591− 79, 0, 0, 14, 12, 45, 0, 47, 49, 51,
592− 53, 55, 56, 60, 61, 59, 58, 62, 63, 65,
593− 66, 69, 68, 70, 0, 0, 0, 0, 18, 0,
594− 79, 15, 13, 0, 0, 0, 20, 30, 82, 22,
595− 84, 0, 81, 80, 43, 21, 83, 0, 0, 16,
596− 29, 19, 31, 0, 23, 32, 26, 0, 76, 34,
597− 0, 0, 0, 0, 37, 36, 24, 35, 33, 0,
598− 77, 78, 25, 0, 28, 0, 0, 0, 27
591+ 80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
592+ 54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
593+ 67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
594+ 80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
595+ 85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
596+ 30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
597+ 0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
598+ 78, 79, 26, 0, 29, 0, 0, 0, 28
599599 };
600600
601601 /* YYPGOTO[NTERM-NUM]. */
@@ -678,28 +678,28 @@ static const yytype_uint8 yystos[] = · 76 unmodified lines
678678 static const yytype_uint8 yyr1[] =
679679 {
680680 0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
681− 53, 54, 54, 54, 54, 54, 55, 56, 56, 57,
682− 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
683− 59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
684− 61, 62, 63, 63, 64, 64, 65, 65, 66, 66,
685− 67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
686− 70, 70, 71, 71, 71, 72, 72, 72, 73, 73,
687− 73, 73, 74, 74, 74, 74, 75, 75, 75, 76,
688− 76, 76, 77, 77, 77
681+ 53, 54, 54, 54, 54, 54, 54, 55, 56, 56,
682+ 57, 57, 57, 57, 58, 58, 58, 58, 58, 58,
683+ 58, 59, 59, 59, 60, 60, 60, 60, 60, 61,
684+ 61, 61, 62, 63, 63, 64, 64, 65, 65, 66,
685+ 66, 67, 67, 68, 68, 69, 69, 69, 70, 70,
686+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 73,
687+ 73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
688+ 76, 76, 76, 77, 77, 77
689689 };
690690
691691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
692692 static const yytype_uint8 yyr2[] =
693693 {
694694 0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
695− 2, 2, 3, 4, 3, 4, 5, 0, 2, 4,
696− 2, 3, 2, 2, 3, 4, 2, 9, 5, 2,
697− 0, 2, 2, 3, 1, 2, 2, 2, 1, 1,
698− 3, 1, 1, 5, 1, 3, 1, 3, 1, 3,
699− 1, 3, 1, 3, 1, 3, 3, 1, 3, 3,
700− 3, 3, 3, 3, 1, 3, 3, 1, 3, 3,
701− 3, 1, 1, 2, 2, 2, 0, 2, 2, 0,
702− 2, 2, 2, 3, 2
695+ 2, 2, 3, 4, 3, 4, 0, 5, 0, 2,
696+ 4, 2, 3, 2, 2, 3, 4, 2, 9, 5,
697+ 2, 0, 2, 2, 3, 1, 2, 2, 2, 1,
698+ 1, 3, 1, 1, 5, 1, 3, 1, 3, 1,
699+ 3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
700+ 3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
701+ 3, 3, 1, 1, 2, 2, 2, 0, 2, 2,
702+ 0, 2, 2, 2, 3, 2
703703 };
704704
705705
@@ -1572,17 +1572,26 @@ yyreduce: · 866 unmodified lines
15721572 {
15731573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
15741574
1575− if (target)
1575+ if (target) {
15761576 merge_nodes(target, (yyvsp[0].node));
1577− else
1578− ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
1577+ } else {
1578+ /*
1579+ * We rely on the rule being always:
1580+ * versioninfo plugindecl memreserves devicetree
1581+ * so $-1 is what we want (plugindecl)
1582+ */
1583+ if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
1584+ add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
1585+ else
1586+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
1587+ }
15791588 (yyval.node) = (yyvsp[-2].node);
15801589 }
1581−#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */
1590+#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
15821591 break;
15831592
15841593 case 15:
1585−#line 192 "dtc-parser.y" /* yacc.c:1646 */
1594+#line 201 "dtc-parser.y" /* yacc.c:1646 */
15861595 {
15871596 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
15881597
@@ -1594,100 +1603,109 @@ yyreduce: · 5 unmodified lines
15941603
15951604 (yyval.node) = (yyvsp[-3].node);
15961605 }
1597−#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */
1606+#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
15981607 break;
15991608
16001609 case 16:
1601−#line 207 "dtc-parser.y" /* yacc.c:1646 */
1610+#line 213 "dtc-parser.y" /* yacc.c:1646 */
16021611 {
1603− (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
1612+ /* build empty node */
1613+ (yyval.node) = name_node(build_node(NULL, NULL), "");
16041614 }
1605−#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */
1615+#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
16061616 break;
16071617
16081618 case 17:
1609−#line 214 "dtc-parser.y" /* yacc.c:1646 */
1619+#line 221 "dtc-parser.y" /* yacc.c:1646 */
16101620 {
1611− (yyval.proplist) = NULL;
1621+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
16121622 }
1613−#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */
1623+#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
16141624 break;
16151625
16161626 case 18:
1617−#line 218 "dtc-parser.y" /* yacc.c:1646 */
1627+#line 228 "dtc-parser.y" /* yacc.c:1646 */
16181628 {
1619− (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
1629+ (yyval.proplist) = NULL;
16201630 }
1621−#line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */
1631+#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
16221632 break;
16231633
16241634 case 19:
1625−#line 225 "dtc-parser.y" /* yacc.c:1646 */
1635+#line 232 "dtc-parser.y" /* yacc.c:1646 */
16261636 {
1627− (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
1637+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
16281638 }
1629−#line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */
1639+#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
16301640 break;
16311641
16321642 case 20:
1633−#line 229 "dtc-parser.y" /* yacc.c:1646 */
1643+#line 239 "dtc-parser.y" /* yacc.c:1646 */
16341644 {
1635− (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
1645+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
16361646 }
1637−#line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */
1647+#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
16381648 break;
16391649
16401650 case 21:
1641−#line 233 "dtc-parser.y" /* yacc.c:1646 */
1651+#line 243 "dtc-parser.y" /* yacc.c:1646 */
16421652 {
1643− (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
1653+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
16441654 }
1645−#line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */
1655+#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
16461656 break;
16471657
16481658 case 22:
1649−#line 237 "dtc-parser.y" /* yacc.c:1646 */
1659+#line 247 "dtc-parser.y" /* yacc.c:1646 */
1660+ {
1661+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
1662+ }
1663+#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */
1664+ break;
1665+
1666+ case 23:
1667+#line 251 "dtc-parser.y" /* yacc.c:1646 */
16501668 {
16511669 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
16521670 (yyval.prop) = (yyvsp[0].prop);
16531671 }
1654−#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */
1672+#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
16551673 break;
16561674
1657− case 23:
1658−#line 245 "dtc-parser.y" /* yacc.c:1646 */
1675+ case 24:
1676+#line 259 "dtc-parser.y" /* yacc.c:1646 */
16591677 {
16601678 (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
16611679 }
1662−#line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */
1680+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
16631681 break;
16641682
1665− case 24:
1666−#line 249 "dtc-parser.y" /* yacc.c:1646 */
1683+ case 25:
1684+#line 263 "dtc-parser.y" /* yacc.c:1646 */
16671685 {
16681686 (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
16691687 }
1670−#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */
1688+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
16711689 break;
16721690
1673− case 25:
1674−#line 253 "dtc-parser.y" /* yacc.c:1646 */
1691+ case 26:
1692+#line 267 "dtc-parser.y" /* yacc.c:1646 */
16751693 {
16761694 (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
16771695 }
1678−#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */
1696+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
16791697 break;
16801698
1681− case 26:
1682−#line 257 "dtc-parser.y" /* yacc.c:1646 */
1699+ case 27:
1700+#line 271 "dtc-parser.y" /* yacc.c:1646 */
16831701 {
16841702 (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
16851703 }
1686−#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */
1704+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
16871705 break;
16881706
1689− case 27:
1690−#line 261 "dtc-parser.y" /* yacc.c:1646 */
1707+ case 28:
1708+#line 275 "dtc-parser.y" /* yacc.c:1646 */
16911709 {
16921710 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
16931711 struct data d;
@@ -1703,11 +1721,11 @@ yyreduce: · 9 unmodified lines
17031721 (yyval.data) = data_merge((yyvsp[-8].data), d);
17041722 fclose(f);
17051723 }
1706−#line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */
1724+#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
17071725 break;
17081726
1709− case 28:
1710−#line 277 "dtc-parser.y" /* yacc.c:1646 */
1727+ case 29:
1728+#line 291 "dtc-parser.y" /* yacc.c:1646 */
17111729 {
17121730 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
17131731 struct data d = empty_data;
@@ -1717,43 +1735,43 @@ yyreduce: · 3 unmodified lines
17171735 (yyval.data) = data_merge((yyvsp[-4].data), d);
17181736 fclose(f);
17191737 }
1720−#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */
1738+#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
17211739 break;
17221740
1723− case 29:
1724−#line 287 "dtc-parser.y" /* yacc.c:1646 */
1741+ case 30:
1742+#line 301 "dtc-parser.y" /* yacc.c:1646 */
17251743 {
17261744 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
17271745 }
1728−#line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */
1746+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
17291747 break;
17301748
1731− case 30:
1732−#line 294 "dtc-parser.y" /* yacc.c:1646 */
1749+ case 31:
1750+#line 308 "dtc-parser.y" /* yacc.c:1646 */
17331751 {
17341752 (yyval.data) = empty_data;
17351753 }
1736−#line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */
1754+#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
17371755 break;
17381756
1739− case 31:
1740−#line 298 "dtc-parser.y" /* yacc.c:1646 */
1757+ case 32:
1758+#line 312 "dtc-parser.y" /* yacc.c:1646 */
17411759 {
17421760 (yyval.data) = (yyvsp[-1].data);
17431761 }
1744−#line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */
1762+#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
17451763 break;
17461764
1747− case 32:
1748−#line 302 "dtc-parser.y" /* yacc.c:1646 */
1765+ case 33:
1766+#line 316 "dtc-parser.y" /* yacc.c:1646 */
17491767 {
17501768 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
17511769 }
1752−#line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */
1770+#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
17531771 break;
17541772
1755− case 33:
1756−#line 309 "dtc-parser.y" /* yacc.c:1646 */
1773+ case 34:
1774+#line 323 "dtc-parser.y" /* yacc.c:1646 */
17571775 {
17581776 unsigned long long bits;
17591777
@@ -1769,20 +1787,20 @@ yyreduce: · 9 unmodified lines
17691787 (yyval.array).data = empty_data;
17701788 (yyval.array).bits = bits;
17711789 }
1772−#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */
1790+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
17731791 break;
17741792
1775− case 34:
1776−#line 325 "dtc-parser.y" /* yacc.c:1646 */
1793+ case 35:
1794+#line 339 "dtc-parser.y" /* yacc.c:1646 */
17771795 {
17781796 (yyval.array).data = empty_data;
17791797 (yyval.array).bits = 32;
17801798 }
1781−#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */
1799+#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
17821800 break;
17831801
1784− case 35:
1785−#line 330 "dtc-parser.y" /* yacc.c:1646 */
1802+ case 36:
1803+#line 344 "dtc-parser.y" /* yacc.c:1646 */
17861804 {
17871805 if ((yyvsp[-1].array).bits < 64) {
17881806 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1801,11 +1819,11 @@ yyreduce: · 12 unmodified lines
18011819
18021820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
18031821 }
1804−#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */
1822+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
18051823 break;
18061824
1807− case 36:
1808−#line 349 "dtc-parser.y" /* yacc.c:1646 */
1825+ case 37:
1826+#line 363 "dtc-parser.y" /* yacc.c:1646 */
18091827 {
18101828 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
18111829
@@ -1819,129 +1837,129 @@ yyreduce: · 7 unmodified lines
18191837
18201838 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
18211839 }
1822−#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
1840+#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
18231841 break;
18241842
1825− case 37:
1826−#line 363 "dtc-parser.y" /* yacc.c:1646 */
1843+ case 38:
1844+#line 377 "dtc-parser.y" /* yacc.c:1646 */
18271845 {
18281846 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
18291847 }
1830−#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */
1848+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
18311849 break;
18321850
1833− case 40:
1834−#line 372 "dtc-parser.y" /* yacc.c:1646 */
1851+ case 41:
1852+#line 386 "dtc-parser.y" /* yacc.c:1646 */
18351853 {
18361854 (yyval.integer) = (yyvsp[-1].integer);
18371855 }
1838−#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */
1856+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
18391857 break;
18401858
1841− case 43:
1842−#line 383 "dtc-parser.y" /* yacc.c:1646 */
1859+ case 44:
1860+#line 397 "dtc-parser.y" /* yacc.c:1646 */
18431861 { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
1844−#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */
1862+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
18451863 break;
18461864
1847− case 45:
1848−#line 388 "dtc-parser.y" /* yacc.c:1646 */
1865+ case 46:
1866+#line 402 "dtc-parser.y" /* yacc.c:1646 */
18491867 { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
1850−#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */
1868+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
18511869 break;
18521870
1853− case 47:
1854−#line 393 "dtc-parser.y" /* yacc.c:1646 */
1871+ case 48:
1872+#line 407 "dtc-parser.y" /* yacc.c:1646 */
18551873 { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
1856−#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
1874+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
18571875 break;
18581876
1859− case 49:
1860−#line 398 "dtc-parser.y" /* yacc.c:1646 */
1877+ case 50:
1878+#line 412 "dtc-parser.y" /* yacc.c:1646 */
18611879 { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
1862−#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
1880+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
18631881 break;
18641882
1865− case 51:
1866−#line 403 "dtc-parser.y" /* yacc.c:1646 */
1883+ case 52:
1884+#line 417 "dtc-parser.y" /* yacc.c:1646 */
18671885 { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
1868−#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
1886+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
18691887 break;
18701888
1871− case 53:
1872−#line 408 "dtc-parser.y" /* yacc.c:1646 */
1889+ case 54:
1890+#line 422 "dtc-parser.y" /* yacc.c:1646 */
18731891 { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
1874−#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
1892+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
18751893 break;
18761894
1877− case 55:
1878−#line 413 "dtc-parser.y" /* yacc.c:1646 */
1895+ case 56:
1896+#line 427 "dtc-parser.y" /* yacc.c:1646 */
18791897 { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
1880−#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
1898+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
18811899 break;
18821900
1883− case 56:
1884−#line 414 "dtc-parser.y" /* yacc.c:1646 */
1901+ case 57:
1902+#line 428 "dtc-parser.y" /* yacc.c:1646 */
18851903 { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
1886−#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
1904+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
18871905 break;
18881906
1889− case 58:
1890−#line 419 "dtc-parser.y" /* yacc.c:1646 */
1907+ case 59:
1908+#line 433 "dtc-parser.y" /* yacc.c:1646 */
18911909 { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
1892−#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
1910+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
18931911 break;
18941912
1895− case 59:
1896−#line 420 "dtc-parser.y" /* yacc.c:1646 */
1913+ case 60:
1914+#line 434 "dtc-parser.y" /* yacc.c:1646 */
18971915 { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
1898−#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
1916+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
18991917 break;
19001918
1901− case 60:
1902−#line 421 "dtc-parser.y" /* yacc.c:1646 */
1919+ case 61:
1920+#line 435 "dtc-parser.y" /* yacc.c:1646 */
19031921 { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
1904−#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
1922+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
19051923 break;
19061924
1907− case 61:
1908−#line 422 "dtc-parser.y" /* yacc.c:1646 */
1925+ case 62:
1926+#line 436 "dtc-parser.y" /* yacc.c:1646 */
19091927 { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
1910−#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
1928+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
19111929 break;
19121930
1913− case 62:
1914−#line 426 "dtc-parser.y" /* yacc.c:1646 */
1931+ case 63:
1932+#line 440 "dtc-parser.y" /* yacc.c:1646 */
19151933 { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
1916−#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
1934+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
19171935 break;
19181936
1919− case 63:
1920−#line 427 "dtc-parser.y" /* yacc.c:1646 */
1937+ case 64:
1938+#line 441 "dtc-parser.y" /* yacc.c:1646 */
19211939 { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
1922−#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
1940+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
19231941 break;
19241942
1925− case 65:
1926−#line 432 "dtc-parser.y" /* yacc.c:1646 */
1943+ case 66:
1944+#line 446 "dtc-parser.y" /* yacc.c:1646 */
19271945 { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
1928−#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
1946+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
19291947 break;
19301948
1931− case 66:
1932−#line 433 "dtc-parser.y" /* yacc.c:1646 */
1949+ case 67:
1950+#line 447 "dtc-parser.y" /* yacc.c:1646 */
19331951 { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
1934−#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
1952+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
19351953 break;
19361954
1937− case 68:
1938−#line 438 "dtc-parser.y" /* yacc.c:1646 */
1955+ case 69:
1956+#line 452 "dtc-parser.y" /* yacc.c:1646 */
19391957 { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
1940−#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
1958+#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */
19411959 break;
19421960
1943− case 69:
1944−#line 440 "dtc-parser.y" /* yacc.c:1646 */
1961+ case 70:
1962+#line 454 "dtc-parser.y" /* yacc.c:1646 */
19451963 {
19461964 if ((yyvsp[0].integer) != 0) {
19471965 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1950,11 +1968,11 @@ yyreduce: · 2 unmodified lines
19501968 (yyval.integer) = 0;
19511969 }
19521970 }
1953−#line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */
1971+#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
19541972 break;
19551973
1956− case 70:
1957−#line 449 "dtc-parser.y" /* yacc.c:1646 */
1974+ case 71:
1975+#line 463 "dtc-parser.y" /* yacc.c:1646 */
19581976 {
19591977 if ((yyvsp[0].integer) != 0) {
19601978 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1963,103 +1981,103 @@ yyreduce: · 2 unmodified lines
19631981 (yyval.integer) = 0;
19641982 }
19651983 }
1966−#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */
1984+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
19671985 break;
19681986
1969− case 73:
1970−#line 462 "dtc-parser.y" /* yacc.c:1646 */
1987+ case 74:
1988+#line 476 "dtc-parser.y" /* yacc.c:1646 */
19711989 { (yyval.integer) = -(yyvsp[0].integer); }
1972−#line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */
1990+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
19731991 break;
19741992
1975− case 74:
1976−#line 463 "dtc-parser.y" /* yacc.c:1646 */
1993+ case 75:
1994+#line 477 "dtc-parser.y" /* yacc.c:1646 */
19771995 { (yyval.integer) = ~(yyvsp[0].integer); }
1978−#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */
1996+#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */
19791997 break;
19801998
1981− case 75:
1982−#line 464 "dtc-parser.y" /* yacc.c:1646 */
1999+ case 76:
2000+#line 478 "dtc-parser.y" /* yacc.c:1646 */
19832001 { (yyval.integer) = !(yyvsp[0].integer); }
1984−#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
2002+#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */
19852003 break;
19862004
1987− case 76:
1988−#line 469 "dtc-parser.y" /* yacc.c:1646 */
2005+ case 77:
2006+#line 483 "dtc-parser.y" /* yacc.c:1646 */
19892007 {
19902008 (yyval.data) = empty_data;
19912009 }
1992−#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */
2010+#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
19932011 break;
19942012
1995− case 77:
1996−#line 473 "dtc-parser.y" /* yacc.c:1646 */
2013+ case 78:
2014+#line 487 "dtc-parser.y" /* yacc.c:1646 */
19972015 {
19982016 (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
19992017 }
2000−#line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */
2018+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
20012019 break;
20022020
2003− case 78:
2004−#line 477 "dtc-parser.y" /* yacc.c:1646 */
2021+ case 79:
2022+#line 491 "dtc-parser.y" /* yacc.c:1646 */
20052023 {
20062024 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
20072025 }
2008−#line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */
2026+#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
20092027 break;
20102028
2011− case 79:
2012−#line 484 "dtc-parser.y" /* yacc.c:1646 */
2029+ case 80:
2030+#line 498 "dtc-parser.y" /* yacc.c:1646 */
20132031 {
20142032 (yyval.nodelist) = NULL;
20152033 }
2016−#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */
2034+#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
20172035 break;
20182036
2019− case 80:
2020−#line 488 "dtc-parser.y" /* yacc.c:1646 */
2037+ case 81:
2038+#line 502 "dtc-parser.y" /* yacc.c:1646 */
20212039 {
20222040 (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
20232041 }
2024−#line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */
2042+#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
20252043 break;
20262044
2027− case 81:
2028−#line 492 "dtc-parser.y" /* yacc.c:1646 */
2045+ case 82:
2046+#line 506 "dtc-parser.y" /* yacc.c:1646 */
20292047 {
20302048 ERROR(&(yylsp[0]), "Properties must precede subnodes");
20312049 YYERROR;
20322050 }
2033−#line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */
2051+#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
20342052 break;
20352053
2036− case 82:
2037−#line 500 "dtc-parser.y" /* yacc.c:1646 */
2054+ case 83:
2055+#line 514 "dtc-parser.y" /* yacc.c:1646 */
20382056 {
20392057 (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
20402058 }
2041−#line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */
2059+#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
20422060 break;
20432061
2044− case 83:
2045−#line 504 "dtc-parser.y" /* yacc.c:1646 */
2062+ case 84:
2063+#line 518 "dtc-parser.y" /* yacc.c:1646 */
20462064 {
20472065 (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
20482066 }
2049−#line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */
2067+#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
20502068 break;
20512069
2052− case 84:
2053−#line 508 "dtc-parser.y" /* yacc.c:1646 */
2070+ case 85:
2071+#line 522 "dtc-parser.y" /* yacc.c:1646 */
20542072 {
20552073 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
20562074 (yyval.node) = (yyvsp[0].node);
20572075 }
2058−#line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */
2076+#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
20592077 break;
20602078
20612079
2062−#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */
2080+#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
20632081 default: break;
20642082 }
20652083 /* User semantic actions sometimes alter yychar, and that requires
@@ -2294,7 +2312,7 @@ yyreturn: · 228 unmodified lines
22942312 #endif
22952313 return yyresult;
22962314 }
2297−#line 514 "dtc-parser.y" /* yacc.c:1906 */
2315+#line 528 "dtc-parser.y" /* yacc.c:1906 */
22982316
22992317
23002318 void yyerror(char const *s)
scripts/dtc/dtc-parser.y+17−3
@@ -182,10 +182,19 @@ devicetree: · 181 unmodified lines
182182 {
183183 struct node *target = get_node_by_ref($1, $2);
184184
185− if (target)
185+ if (target) {
186186 merge_nodes(target, $3);
187− else
188− ERROR(&@2, "Label or path %s not found", $2);
187+ } else {
188+ /*
189+ * We rely on the rule being always:
190+ * versioninfo plugindecl memreserves devicetree
191+ * so $-1 is what we want (plugindecl)
192+ */
193+ if ($<flags>-1 & DTSF_PLUGIN)
194+ add_orphan_node($1, $3, $2);
195+ else
196+ ERROR(&@2, "Label or path %s not found", $2);
197+ }
189198 $$ = $1;
190199 }
191200 | devicetree DT_DEL_NODE DT_REF ';'
@@ -200,6 +209,11 @@ devicetree: · 8 unmodified lines
200209
201210 $$ = $1;
202211 }
212+ | /* empty */
213+ {
214+ /* build empty node */
215+ $$ = name_node(build_node(NULL, NULL), "");
216+ }
203217 ;
204218
205219 nodedef:
scripts/dtc/dtc.c+1−1
@@ -31,7 +31,7 @@ int reservenum; /* Number of memory reservation slots */ · 30 unmodified lines
3131 int minsize; /* Minimum blob size */
3232 int padsize; /* Additional padding to blob */
3333 int alignsize; /* Additional padding to blob accroding to the alignsize */
34−int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
34+int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
3535 int generate_symbols; /* enable symbols & fixup support */
3636 int generate_fixups; /* suppress generation of fixups on symbol support */
3737 int auto_label_aliases; /* auto generate labels -> aliases */
scripts/dtc/dtc.h+3−0
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include <ctype.h>
3232 #include <errno.h>
3333 #include <unistd.h>
34+#include <inttypes.h>
3435
3536 #include <libfdt_env.h>
3637 #include <fdt.h>
@@ -202,6 +203,7 @@ struct node *build_node_delete(void); · 165 unmodified lines
202203 struct node *name_node(struct node *node, char *name);
203204 struct node *chain_node(struct node *first, struct node *list);
204205 struct node *merge_nodes(struct node *old_node, struct node *new_node);
206+void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
205207
206208 void add_property(struct node *node, struct property *prop);
207209 void delete_property_by_name(struct node *node, char *name);
@@ -215,6 +217,7 @@ void append_to_property(struct node *node, · 7 unmodified lines
215217 const char *get_unitname(struct node *node);
216218 struct property *get_property(struct node *node, const char *propname);
217219 cell_t propval_cell(struct property *prop);
220+cell_t propval_cell_n(struct property *prop, int n);
218221 struct property *get_property_by_label(struct node *tree, const char *label,
219222 struct node **node);
220223 struct marker *get_marker_label(struct node *tree, const char *label,
scripts/dtc/libfdt/fdt_addresses.c+96−0
@@ -0,0 +1,96 @@
1+/*
2+ * libfdt - Flat Device Tree manipulation
3+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
4+ *
5+ * libfdt is dual licensed: you can use it either under the terms of
6+ * the GPL, or the BSD license, at your option.
7+ *
8+ * a) This library is free software; you can redistribute it and/or
9+ * modify it under the terms of the GNU General Public License as
10+ * published by the Free Software Foundation; either version 2 of the
11+ * License, or (at your option) any later version.
12+ *
13+ * This library is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+ * GNU General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU General Public
19+ * License along with this library; if not, write to the Free
20+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21+ * MA 02110-1301 USA
22+ *
23+ * Alternatively,
24+ *
25+ * b) Redistribution and use in source and binary forms, with or
26+ * without modification, are permitted provided that the following
27+ * conditions are met:
28+ *
29+ * 1. Redistributions of source code must retain the above
30+ * copyright notice, this list of conditions and the following
31+ * disclaimer.
32+ * 2. Redistributions in binary form must reproduce the above
33+ * copyright notice, this list of conditions and the following
34+ * disclaimer in the documentation and/or other materials
35+ * provided with the distribution.
36+ *
37+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50+ */
51+#include "libfdt_env.h"
52+
53+#include <fdt.h>
54+#include <libfdt.h>
55+
56+#include "libfdt_internal.h"
57+
58+int fdt_address_cells(const void *fdt, int nodeoffset)
59+{
60+ const fdt32_t *ac;
61+ int val;
62+ int len;
63+
64+ ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
65+ if (!ac)
66+ return 2;
67+
68+ if (len != sizeof(*ac))
69+ return -FDT_ERR_BADNCELLS;
70+
71+ val = fdt32_to_cpu(*ac);
72+ if ((val <= 0) || (val > FDT_MAX_NCELLS))
73+ return -FDT_ERR_BADNCELLS;
74+
75+ return val;
76+}
77+
78+int fdt_size_cells(const void *fdt, int nodeoffset)
79+{
80+ const fdt32_t *sc;
81+ int val;
82+ int len;
83+
84+ sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
85+ if (!sc)
86+ return 2;
87+
88+ if (len != sizeof(*sc))
89+ return -FDT_ERR_BADNCELLS;
90+
91+ val = fdt32_to_cpu(*sc);
92+ if ((val < 0) || (val > FDT_MAX_NCELLS))
93+ return -FDT_ERR_BADNCELLS;
94+
95+ return val;
96+}
scripts/dtc/libfdt/fdt_empty_tree.c+0−1
@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize) · 80 unmodified lines
8181
8282 return fdt_open_into(buf, buf, bufsize);
8383 }
84−
scripts/dtc/libfdt/fdt_overlay.c+861−0
@@ -0,0 +1,861 @@
1+#include "libfdt_env.h"
2+
3+#include <fdt.h>
4+#include <libfdt.h>
5+
6+#include "libfdt_internal.h"
7+
8+/**
9+ * overlay_get_target_phandle - retrieves the target phandle of a fragment
10+ * @fdto: pointer to the device tree overlay blob
11+ * @fragment: node offset of the fragment in the overlay
12+ *
13+ * overlay_get_target_phandle() retrieves the target phandle of an
14+ * overlay fragment when that fragment uses a phandle (target
15+ * property) instead of a path (target-path property).
16+ *
17+ * returns:
18+ * the phandle pointed by the target property
19+ * 0, if the phandle was not found
20+ * -1, if the phandle was malformed
21+ */
22+static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
23+{
24+ const fdt32_t *val;
25+ int len;
26+
27+ val = fdt_getprop(fdto, fragment, "target", &len);
28+ if (!val)
29+ return 0;
30+
31+ if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
32+ return (uint32_t)-1;
33+
34+ return fdt32_to_cpu(*val);
35+}
36+
37+/**
38+ * overlay_get_target - retrieves the offset of a fragment's target
39+ * @fdt: Base device tree blob
40+ * @fdto: Device tree overlay blob
41+ * @fragment: node offset of the fragment in the overlay
42+ * @pathp: pointer which receives the path of the target (or NULL)
43+ *
44+ * overlay_get_target() retrieves the target offset in the base
45+ * device tree of a fragment, no matter how the actual targetting is
46+ * done (through a phandle or a path)
47+ *
48+ * returns:
49+ * the targetted node offset in the base device tree
50+ * Negative error code on error
51+ */
52+static int overlay_get_target(const void *fdt, const void *fdto,
53+ int fragment, char const **pathp)
54+{
55+ uint32_t phandle;
56+ const char *path = NULL;
57+ int path_len = 0, ret;
58+
59+ /* Try first to do a phandle based lookup */
60+ phandle = overlay_get_target_phandle(fdto, fragment);
61+ if (phandle == (uint32_t)-1)
62+ return -FDT_ERR_BADPHANDLE;
63+
64+ /* no phandle, try path */
65+ if (!phandle) {
66+ /* And then a path based lookup */
67+ path = fdt_getprop(fdto, fragment, "target-path", &path_len);
68+ if (path)
69+ ret = fdt_path_offset(fdt, path);
70+ else
71+ ret = path_len;
72+ } else
73+ ret = fdt_node_offset_by_phandle(fdt, phandle);
74+
75+ /*
76+ * If we haven't found either a target or a
77+ * target-path property in a node that contains a
78+ * __overlay__ subnode (we wouldn't be called
79+ * otherwise), consider it a improperly written
80+ * overlay
81+ */
82+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
83+ ret = -FDT_ERR_BADOVERLAY;
84+
85+ /* return on error */
86+ if (ret < 0)
87+ return ret;
88+
89+ /* return pointer to path (if available) */
90+ if (pathp)
91+ *pathp = path ? path : NULL;
92+
93+ return ret;
94+}
95+
96+/**
97+ * overlay_phandle_add_offset - Increases a phandle by an offset
98+ * @fdt: Base device tree blob
99+ * @node: Device tree overlay blob
100+ * @name: Name of the property to modify (phandle or linux,phandle)
101+ * @delta: offset to apply
102+ *
103+ * overlay_phandle_add_offset() increments a node phandle by a given
104+ * offset.
105+ *
106+ * returns:
107+ * 0 on success.
108+ * Negative error code on error
109+ */
110+static int overlay_phandle_add_offset(void *fdt, int node,
111+ const char *name, uint32_t delta)
112+{
113+ const fdt32_t *val;
114+ uint32_t adj_val;
115+ int len;
116+
117+ val = fdt_getprop(fdt, node, name, &len);
118+ if (!val)
119+ return len;
120+
121+ if (len != sizeof(*val))
122+ return -FDT_ERR_BADPHANDLE;
123+
124+ adj_val = fdt32_to_cpu(*val);
125+ if ((adj_val + delta) < adj_val)
126+ return -FDT_ERR_NOPHANDLES;
127+
128+ adj_val += delta;
129+ if (adj_val == (uint32_t)-1)
130+ return -FDT_ERR_NOPHANDLES;
131+
132+ return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
133+}
134+
135+/**
136+ * overlay_adjust_node_phandles - Offsets the phandles of a node
137+ * @fdto: Device tree overlay blob
138+ * @node: Offset of the node we want to adjust
139+ * @delta: Offset to shift the phandles of
140+ *
141+ * overlay_adjust_node_phandles() adds a constant to all the phandles
142+ * of a given node. This is mainly use as part of the overlay
143+ * application process, when we want to update all the overlay
144+ * phandles to not conflict with the overlays of the base device tree.
145+ *
146+ * returns:
147+ * 0 on success
148+ * Negative error code on failure
149+ */
150+static int overlay_adjust_node_phandles(void *fdto, int node,
151+ uint32_t delta)
152+{
153+ int child;
154+ int ret;
155+
156+ ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
157+ if (ret && ret != -FDT_ERR_NOTFOUND)
158+ return ret;
159+
160+ ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
161+ if (ret && ret != -FDT_ERR_NOTFOUND)
162+ return ret;
163+
164+ fdt_for_each_subnode(child, fdto, node) {
165+ ret = overlay_adjust_node_phandles(fdto, child, delta);
166+ if (ret)
167+ return ret;
168+ }
169+
170+ return 0;
171+}
172+
173+/**
174+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
175+ * @fdto: Device tree overlay blob
176+ * @delta: Offset to shift the phandles of
177+ *
178+ * overlay_adjust_local_phandles() adds a constant to all the
179+ * phandles of an overlay. This is mainly use as part of the overlay
180+ * application process, when we want to update all the overlay
181+ * phandles to not conflict with the overlays of the base device tree.
182+ *
183+ * returns:
184+ * 0 on success
185+ * Negative error code on failure
186+ */
187+static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
188+{
189+ /*
190+ * Start adjusting the phandles from the overlay root
191+ */
192+ return overlay_adjust_node_phandles(fdto, 0, delta);
193+}
194+
195+/**
196+ * overlay_update_local_node_references - Adjust the overlay references
197+ * @fdto: Device tree overlay blob
198+ * @tree_node: Node offset of the node to operate on
199+ * @fixup_node: Node offset of the matching local fixups node
200+ * @delta: Offset to shift the phandles of
201+ *
202+ * overlay_update_local_nodes_references() update the phandles
203+ * pointing to a node within the device tree overlay by adding a
204+ * constant delta.
205+ *
206+ * This is mainly used as part of a device tree application process,
207+ * where you want the device tree overlays phandles to not conflict
208+ * with the ones from the base device tree before merging them.
209+ *
210+ * returns:
211+ * 0 on success
212+ * Negative error code on failure
213+ */
214+static int overlay_update_local_node_references(void *fdto,
215+ int tree_node,
216+ int fixup_node,
217+ uint32_t delta)
218+{
219+ int fixup_prop;
220+ int fixup_child;
221+ int ret;
222+
223+ fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
224+ const fdt32_t *fixup_val;
225+ const char *tree_val;
226+ const char *name;
227+ int fixup_len;
228+ int tree_len;
229+ int i;
230+
231+ fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
232+ &name, &fixup_len);
233+ if (!fixup_val)
234+ return fixup_len;
235+
236+ if (fixup_len % sizeof(uint32_t))
237+ return -FDT_ERR_BADOVERLAY;
238+
239+ tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
240+ if (!tree_val) {
241+ if (tree_len == -FDT_ERR_NOTFOUND)
242+ return -FDT_ERR_BADOVERLAY;
243+
244+ return tree_len;
245+ }
246+
247+ for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
248+ fdt32_t adj_val;
249+ uint32_t poffset;
250+
251+ poffset = fdt32_to_cpu(fixup_val[i]);
252+
253+ /*
254+ * phandles to fixup can be unaligned.
255+ *
256+ * Use a memcpy for the architectures that do
257+ * not support unaligned accesses.
258+ */
259+ memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
260+
261+ adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
262+
263+ ret = fdt_setprop_inplace_namelen_partial(fdto,
264+ tree_node,
265+ name,
266+ strlen(name),
267+ poffset,
268+ &adj_val,
269+ sizeof(adj_val));
270+ if (ret == -FDT_ERR_NOSPACE)
271+ return -FDT_ERR_BADOVERLAY;
272+
273+ if (ret)
274+ return ret;
275+ }
276+ }
277+
278+ fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
279+ const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
280+ NULL);
281+ int tree_child;
282+
283+ tree_child = fdt_subnode_offset(fdto, tree_node,
284+ fixup_child_name);
285+ if (tree_child == -FDT_ERR_NOTFOUND)
286+ return -FDT_ERR_BADOVERLAY;
287+ if (tree_child < 0)
288+ return tree_child;
289+
290+ ret = overlay_update_local_node_references(fdto,
291+ tree_child,
292+ fixup_child,
293+ delta);
294+ if (ret)
295+ return ret;
296+ }
297+
298+ return 0;
299+}
300+
301+/**
302+ * overlay_update_local_references - Adjust the overlay references
303+ * @fdto: Device tree overlay blob
304+ * @delta: Offset to shift the phandles of
305+ *
306+ * overlay_update_local_references() update all the phandles pointing
307+ * to a node within the device tree overlay by adding a constant
308+ * delta to not conflict with the base overlay.
309+ *
310+ * This is mainly used as part of a device tree application process,
311+ * where you want the device tree overlays phandles to not conflict
312+ * with the ones from the base device tree before merging them.
313+ *
314+ * returns:
315+ * 0 on success
316+ * Negative error code on failure
317+ */
318+static int overlay_update_local_references(void *fdto, uint32_t delta)
319+{
320+ int fixups;
321+
322+ fixups = fdt_path_offset(fdto, "/__local_fixups__");
323+ if (fixups < 0) {
324+ /* There's no local phandles to adjust, bail out */
325+ if (fixups == -FDT_ERR_NOTFOUND)
326+ return 0;
327+
328+ return fixups;
329+ }
330+
331+ /*
332+ * Update our local references from the root of the tree
333+ */
334+ return overlay_update_local_node_references(fdto, 0, fixups,
335+ delta);
336+}
337+
338+/**
339+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
340+ * @fdt: Base Device Tree blob
341+ * @fdto: Device tree overlay blob
342+ * @symbols_off: Node offset of the symbols node in the base device tree
343+ * @path: Path to a node holding a phandle in the overlay
344+ * @path_len: number of path characters to consider
345+ * @name: Name of the property holding the phandle reference in the overlay
346+ * @name_len: number of name characters to consider
347+ * @poffset: Offset within the overlay property where the phandle is stored
348+ * @label: Label of the node referenced by the phandle
349+ *
350+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
351+ * a node in the base device tree.
352+ *
353+ * This is part of the device tree overlay application process, when
354+ * you want all the phandles in the overlay to point to the actual
355+ * base dt nodes.
356+ *
357+ * returns:
358+ * 0 on success
359+ * Negative error code on failure
360+ */
361+static int overlay_fixup_one_phandle(void *fdt, void *fdto,
362+ int symbols_off,
363+ const char *path, uint32_t path_len,
364+ const char *name, uint32_t name_len,
365+ int poffset, const char *label)
366+{
367+ const char *symbol_path;
368+ uint32_t phandle;
369+ fdt32_t phandle_prop;
370+ int symbol_off, fixup_off;
371+ int prop_len;
372+
373+ if (symbols_off < 0)
374+ return symbols_off;
375+
376+ symbol_path = fdt_getprop(fdt, symbols_off, label,
377+ &prop_len);
378+ if (!symbol_path)
379+ return prop_len;
380+
381+ symbol_off = fdt_path_offset(fdt, symbol_path);
382+ if (symbol_off < 0)
383+ return symbol_off;
384+
385+ phandle = fdt_get_phandle(fdt, symbol_off);
386+ if (!phandle)
387+ return -FDT_ERR_NOTFOUND;
388+
389+ fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
390+ if (fixup_off == -FDT_ERR_NOTFOUND)
391+ return -FDT_ERR_BADOVERLAY;
392+ if (fixup_off < 0)
393+ return fixup_off;
394+
395+ phandle_prop = cpu_to_fdt32(phandle);
396+ return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
397+ name, name_len, poffset,
398+ &phandle_prop,
399+ sizeof(phandle_prop));
400+};
401+
402+/**
403+ * overlay_fixup_phandle - Set an overlay phandle to the base one
404+ * @fdt: Base Device Tree blob
405+ * @fdto: Device tree overlay blob
406+ * @symbols_off: Node offset of the symbols node in the base device tree
407+ * @property: Property offset in the overlay holding the list of fixups
408+ *
409+ * overlay_fixup_phandle() resolves all the overlay phandles pointed
410+ * to in a __fixups__ property, and updates them to match the phandles
411+ * in use in the base device tree.
412+ *
413+ * This is part of the device tree overlay application process, when
414+ * you want all the phandles in the overlay to point to the actual
415+ * base dt nodes.
416+ *
417+ * returns:
418+ * 0 on success
419+ * Negative error code on failure
420+ */
421+static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
422+ int property)
423+{
424+ const char *value;
425+ const char *label;
426+ int len;
427+
428+ value = fdt_getprop_by_offset(fdto, property,
429+ &label, &len);
430+ if (!value) {
431+ if (len == -FDT_ERR_NOTFOUND)
432+ return -FDT_ERR_INTERNAL;
433+
434+ return len;
435+ }
436+
437+ do {
438+ const char *path, *name, *fixup_end;
439+ const char *fixup_str = value;
440+ uint32_t path_len, name_len;
441+ uint32_t fixup_len;
442+ char *sep, *endptr;
443+ int poffset, ret;
444+
445+ fixup_end = memchr(value, '\0', len);
446+ if (!fixup_end)
447+ return -FDT_ERR_BADOVERLAY;
448+ fixup_len = fixup_end - fixup_str;
449+
450+ len -= fixup_len + 1;
451+ value += fixup_len + 1;
452+
453+ path = fixup_str;
454+ sep = memchr(fixup_str, ':', fixup_len);
455+ if (!sep || *sep != ':')
456+ return -FDT_ERR_BADOVERLAY;
457+
458+ path_len = sep - path;
459+ if (path_len == (fixup_len - 1))
460+ return -FDT_ERR_BADOVERLAY;
461+
462+ fixup_len -= path_len + 1;
463+ name = sep + 1;
464+ sep = memchr(name, ':', fixup_len);
465+ if (!sep || *sep != ':')
466+ return -FDT_ERR_BADOVERLAY;
467+
468+ name_len = sep - name;
469+ if (!name_len)
470+ return -FDT_ERR_BADOVERLAY;
471+
472+ poffset = strtoul(sep + 1, &endptr, 10);
473+ if ((*endptr != '\0') || (endptr <= (sep + 1)))
474+ return -FDT_ERR_BADOVERLAY;
475+
476+ ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
477+ path, path_len, name, name_len,
478+ poffset, label);
479+ if (ret)
480+ return ret;
481+ } while (len > 0);
482+
483+ return 0;
484+}
485+
486+/**
487+ * overlay_fixup_phandles - Resolve the overlay phandles to the base
488+ * device tree
489+ * @fdt: Base Device Tree blob
490+ * @fdto: Device tree overlay blob
491+ *
492+ * overlay_fixup_phandles() resolves all the overlay phandles pointing
493+ * to nodes in the base device tree.
494+ *
495+ * This is one of the steps of the device tree overlay application
496+ * process, when you want all the phandles in the overlay to point to
497+ * the actual base dt nodes.
498+ *
499+ * returns:
500+ * 0 on success
501+ * Negative error code on failure
502+ */
503+static int overlay_fixup_phandles(void *fdt, void *fdto)
504+{
505+ int fixups_off, symbols_off;
506+ int property;
507+
508+ /* We can have overlays without any fixups */
509+ fixups_off = fdt_path_offset(fdto, "/__fixups__");
510+ if (fixups_off == -FDT_ERR_NOTFOUND)
511+ return 0; /* nothing to do */
512+ if (fixups_off < 0)
513+ return fixups_off;
514+
515+ /* And base DTs without symbols */
516+ symbols_off = fdt_path_offset(fdt, "/__symbols__");
517+ if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
518+ return symbols_off;
519+
520+ fdt_for_each_property_offset(property, fdto, fixups_off) {
521+ int ret;
522+
523+ ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
524+ if (ret)
525+ return ret;
526+ }
527+
528+ return 0;
529+}
530+
531+/**
532+ * overlay_apply_node - Merges a node into the base device tree
533+ * @fdt: Base Device Tree blob
534+ * @target: Node offset in the base device tree to apply the fragment to
535+ * @fdto: Device tree overlay blob
536+ * @node: Node offset in the overlay holding the changes to merge
537+ *
538+ * overlay_apply_node() merges a node into a target base device tree
539+ * node pointed.
540+ *
541+ * This is part of the final step in the device tree overlay
542+ * application process, when all the phandles have been adjusted and
543+ * resolved and you just have to merge overlay into the base device
544+ * tree.
545+ *
546+ * returns:
547+ * 0 on success
548+ * Negative error code on failure
549+ */
550+static int overlay_apply_node(void *fdt, int target,
551+ void *fdto, int node)
552+{
553+ int property;
554+ int subnode;
555+
556+ fdt_for_each_property_offset(property, fdto, node) {
557+ const char *name;
558+ const void *prop;
559+ int prop_len;
560+ int ret;
561+
562+ prop = fdt_getprop_by_offset(fdto, property, &name,
563+ &prop_len);
564+ if (prop_len == -FDT_ERR_NOTFOUND)
565+ return -FDT_ERR_INTERNAL;
566+ if (prop_len < 0)
567+ return prop_len;
568+
569+ ret = fdt_setprop(fdt, target, name, prop, prop_len);
570+ if (ret)
571+ return ret;
572+ }
573+
574+ fdt_for_each_subnode(subnode, fdto, node) {
575+ const char *name = fdt_get_name(fdto, subnode, NULL);
576+ int nnode;
577+ int ret;
578+
579+ nnode = fdt_add_subnode(fdt, target, name);
580+ if (nnode == -FDT_ERR_EXISTS) {
581+ nnode = fdt_subnode_offset(fdt, target, name);
582+ if (nnode == -FDT_ERR_NOTFOUND)
583+ return -FDT_ERR_INTERNAL;
584+ }
585+
586+ if (nnode < 0)
587+ return nnode;
588+
589+ ret = overlay_apply_node(fdt, nnode, fdto, subnode);
590+ if (ret)
591+ return ret;
592+ }
593+
594+ return 0;
595+}
596+
597+/**
598+ * overlay_merge - Merge an overlay into its base device tree
599+ * @fdt: Base Device Tree blob
600+ * @fdto: Device tree overlay blob
601+ *
602+ * overlay_merge() merges an overlay into its base device tree.
603+ *
604+ * This is the next to last step in the device tree overlay application
605+ * process, when all the phandles have been adjusted and resolved and
606+ * you just have to merge overlay into the base device tree.
607+ *
608+ * returns:
609+ * 0 on success
610+ * Negative error code on failure
611+ */
612+static int overlay_merge(void *fdt, void *fdto)
613+{
614+ int fragment;
615+
616+ fdt_for_each_subnode(fragment, fdto, 0) {
617+ int overlay;
618+ int target;
619+ int ret;
620+
621+ /*
622+ * Each fragments will have an __overlay__ node. If
623+ * they don't, it's not supposed to be merged
624+ */
625+ overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
626+ if (overlay == -FDT_ERR_NOTFOUND)
627+ continue;
628+
629+ if (overlay < 0)
630+ return overlay;
631+
632+ target = overlay_get_target(fdt, fdto, fragment, NULL);
633+ if (target < 0)
634+ return target;
635+
636+ ret = overlay_apply_node(fdt, target, fdto, overlay);
637+ if (ret)
638+ return ret;
639+ }
640+
641+ return 0;
642+}
643+
644+static int get_path_len(const void *fdt, int nodeoffset)
645+{
646+ int len = 0, namelen;
647+ const char *name;
648+
649+ FDT_CHECK_HEADER(fdt);
650+
651+ for (;;) {
652+ name = fdt_get_name(fdt, nodeoffset, &namelen);
653+ if (!name)
654+ return namelen;
655+
656+ /* root? we're done */
657+ if (namelen == 0)
658+ break;
659+
660+ nodeoffset = fdt_parent_offset(fdt, nodeoffset);
661+ if (nodeoffset < 0)
662+ return nodeoffset;
663+ len += namelen + 1;
664+ }
665+
666+ /* in case of root pretend it's "/" */
667+ if (len == 0)
668+ len++;
669+ return len;
670+}
671+
672+/**
673+ * overlay_symbol_update - Update the symbols of base tree after a merge
674+ * @fdt: Base Device Tree blob
675+ * @fdto: Device tree overlay blob
676+ *
677+ * overlay_symbol_update() updates the symbols of the base tree with the
678+ * symbols of the applied overlay
679+ *
680+ * This is the last step in the device tree overlay application
681+ * process, allowing the reference of overlay symbols by subsequent
682+ * overlay operations.
683+ *
684+ * returns:
685+ * 0 on success
686+ * Negative error code on failure
687+ */
688+static int overlay_symbol_update(void *fdt, void *fdto)
689+{
690+ int root_sym, ov_sym, prop, path_len, fragment, target;
691+ int len, frag_name_len, ret, rel_path_len;
692+ const char *s, *e;
693+ const char *path;
694+ const char *name;
695+ const char *frag_name;
696+ const char *rel_path;
697+ const char *target_path;
698+ char *buf;
699+ void *p;
700+
701+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
702+
703+ /* if no overlay symbols exist no problem */
704+ if (ov_sym < 0)
705+ return 0;
706+
707+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
708+
709+ /* it no root symbols exist we should create them */
710+ if (root_sym == -FDT_ERR_NOTFOUND)
711+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
712+
713+ /* any error is fatal now */
714+ if (root_sym < 0)
715+ return root_sym;
716+
717+ /* iterate over each overlay symbol */
718+ fdt_for_each_property_offset(prop, fdto, ov_sym) {
719+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
720+ if (!path)
721+ return path_len;
722+
723+ /* verify it's a string property (terminated by a single \0) */
724+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
725+ return -FDT_ERR_BADVALUE;
726+
727+ /* keep end marker to avoid strlen() */
728+ e = path + path_len;
729+
730+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
731+
732+ if (*path != '/')
733+ return -FDT_ERR_BADVALUE;
734+
735+ /* get fragment name first */
736+ s = strchr(path + 1, '/');
737+ if (!s)
738+ return -FDT_ERR_BADOVERLAY;
739+
740+ frag_name = path + 1;
741+ frag_name_len = s - path - 1;
742+
743+ /* verify format; safe since "s" lies in \0 terminated prop */
744+ len = sizeof("/__overlay__/") - 1;
745+ if ((e - s) < len || memcmp(s, "/__overlay__/", len))
746+ return -FDT_ERR_BADOVERLAY;
747+
748+ rel_path = s + len;
749+ rel_path_len = e - rel_path;
750+
751+ /* find the fragment index in which the symbol lies */
752+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
753+ frag_name_len);
754+ /* not found? */
755+ if (ret < 0)
756+ return -FDT_ERR_BADOVERLAY;
757+ fragment = ret;
758+
759+ /* an __overlay__ subnode must exist */
760+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
761+ if (ret < 0)
762+ return -FDT_ERR_BADOVERLAY;
763+
764+ /* get the target of the fragment */
765+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
766+ if (ret < 0)
767+ return ret;
768+ target = ret;
769+
770+ /* if we have a target path use */
771+ if (!target_path) {
772+ ret = get_path_len(fdt, target);
773+ if (ret < 0)
774+ return ret;
775+ len = ret;
776+ } else {
777+ len = strlen(target_path);
778+ }
779+
780+ ret = fdt_setprop_placeholder(fdt, root_sym, name,
781+ len + (len > 1) + rel_path_len + 1, &p);
782+ if (ret < 0)
783+ return ret;
784+
785+ if (!target_path) {
786+ /* again in case setprop_placeholder changed it */
787+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
788+ if (ret < 0)
789+ return ret;
790+ target = ret;
791+ }
792+
793+ buf = p;
794+ if (len > 1) { /* target is not root */
795+ if (!target_path) {
796+ ret = fdt_get_path(fdt, target, buf, len + 1);
797+ if (ret < 0)
798+ return ret;
799+ } else
800+ memcpy(buf, target_path, len + 1);
801+
802+ } else
803+ len--;
804+
805+ buf[len] = '/';
806+ memcpy(buf + len + 1, rel_path, rel_path_len);
807+ buf[len + 1 + rel_path_len] = '\0';
808+ }
809+
810+ return 0;
811+}
812+
813+int fdt_overlay_apply(void *fdt, void *fdto)
814+{
815+ uint32_t delta = fdt_get_max_phandle(fdt);
816+ int ret;
817+
818+ FDT_CHECK_HEADER(fdt);
819+ FDT_CHECK_HEADER(fdto);
820+
821+ ret = overlay_adjust_local_phandles(fdto, delta);
822+ if (ret)
823+ goto err;
824+
825+ ret = overlay_update_local_references(fdto, delta);
826+ if (ret)
827+ goto err;
828+
829+ ret = overlay_fixup_phandles(fdt, fdto);
830+ if (ret)
831+ goto err;
832+
833+ ret = overlay_merge(fdt, fdto);
834+ if (ret)
835+ goto err;
836+
837+ ret = overlay_symbol_update(fdt, fdto);
838+ if (ret)
839+ goto err;
840+
841+ /*
842+ * The overlay has been damaged, erase its magic.
843+ */
844+ fdt_set_magic(fdto, ~0);
845+
846+ return 0;
847+
848+err:
849+ /*
850+ * The overlay might have been damaged, erase its magic.
851+ */
852+ fdt_set_magic(fdto, ~0);
853+
854+ /*
855+ * The base device tree might have been damaged, erase its
856+ * magic.
857+ */
858+ fdt_set_magic(fdt, ~0);
859+
860+ return ret;
861+}
scripts/dtc/libfdt/fdt_ro.c+2−2
@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset, · 59 unmodified lines
6060 {
6161 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
6262
63− if (! p)
63+ if (!p)
6464 /* short match */
6565 return 0;
6666
@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, · 260 unmodified lines
327327 const struct fdt_property *prop;
328328
329329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
330− if (! prop)
330+ if (!prop)
331331 return NULL;
332332
333333 return prop->data;
scripts/dtc/libfdt/fdt_rw.c+19−5
@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, · 206 unmodified lines
207207 int err;
208208
209209 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
210− if (! (*prop))
210+ if (!*prop)
211211 return oldlen;
212212
213213 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
@@ -269,8 +269,8 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) · 55 unmodified lines
269269 return 0;
270270 }
271271
272−int fdt_setprop(void *fdt, int nodeoffset, const char *name,
273− const void *val, int len)
272+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
273+ int len, void **prop_data)
274274 {
275275 struct fdt_property *prop;
276276 int err;
@@ -283,8 +283,22 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, · 6 unmodified lines
283283 if (err)
284284 return err;
285285
286+ *prop_data = prop->data;
287+ return 0;
288+}
289+
290+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
291+ const void *val, int len)
292+{
293+ void *prop_data;
294+ int err;
295+
296+ err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
297+ if (err)
298+ return err;
299+
286300 if (len)
287− memcpy(prop->data, val, len);
301+ memcpy(prop_data, val, len);
288302 return 0;
289303 }
290304
@@ -323,7 +337,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) · 32 unmodified lines
323337 FDT_RW_CHECK_HEADER(fdt);
324338
325339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
326− if (! prop)
340+ if (!prop)
327341 return len;
328342
329343 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
scripts/dtc/libfdt/fdt_sw.c+14−2
@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) · 219 unmodified lines
220220 return offset;
221221 }
222222
223−int fdt_property(void *fdt, const char *name, const void *val, int len)
223+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
224224 {
225225 struct fdt_property *prop;
226226 int nameoff;
@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len) · 11 unmodified lines
238238 prop->tag = cpu_to_fdt32(FDT_PROP);
239239 prop->nameoff = cpu_to_fdt32(nameoff);
240240 prop->len = cpu_to_fdt32(len);
241− memcpy(prop->data, val, len);
241+ *valp = prop->data;
242+ return 0;
243+}
244+
245+int fdt_property(void *fdt, const char *name, const void *val, int len)
246+{
247+ void *ptr;
248+ int ret;
249+
250+ ret = fdt_property_placeholder(fdt, name, len, &ptr);
251+ if (ret)
252+ return ret;
253+ memcpy(ptr, val, len);
242254 return 0;
243255 }
244256
scripts/dtc/libfdt/fdt_wip.c+2−2
@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, · 81 unmodified lines
8282 int proplen;
8383
8484 propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
85− if (! propval)
85+ if (!propval)
8686 return proplen;
8787
8888 if (proplen != len)
@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) · 18 unmodified lines
107107 int len;
108108
109109 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
110− if (! prop)
110+ if (!prop)
111111 return len;
112112
113113 _fdt_nop_region(prop, len + sizeof(*prop));
scripts/dtc/libfdt/libfdt.h+47−0
@@ -1314,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) · 1313 unmodified lines
13141314 {
13151315 return fdt_property_u32(fdt, name, val);
13161316 }
1317+
1318+/**
1319+ * fdt_property_placeholder - add a new property and return a ptr to its value
1320+ *
1321+ * @fdt: pointer to the device tree blob
1322+ * @name: name of property to add
1323+ * @len: length of property value in bytes
1324+ * @valp: returns a pointer to where where the value should be placed
1325+ *
1326+ * returns:
1327+ * 0, on success
1328+ * -FDT_ERR_BADMAGIC,
1329+ * -FDT_ERR_NOSPACE, standard meanings
1330+ */
1331+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1332+
13171333 #define fdt_property_string(fdt, name, str) \
13181334 fdt_property(fdt, name, str, strlen(str)+1)
13191335 int fdt_end_node(void *fdt);
@@ -1432,6 +1448,37 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name); · 112 unmodified lines
14321448 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
14331449 const void *val, int len);
14341450
1451+/**
1452+ * fdt_setprop _placeholder - allocate space for a property
1453+ * @fdt: pointer to the device tree blob
1454+ * @nodeoffset: offset of the node whose property to change
1455+ * @name: name of the property to change
1456+ * @len: length of the property value
1457+ * @prop_data: return pointer to property data
1458+ *
1459+ * fdt_setprop_placeholer() allocates the named property in the given node.
1460+ * If the property exists it is resized. In either case a pointer to the
1461+ * property data is returned.
1462+ *
1463+ * This function may insert or delete data from the blob, and will
1464+ * therefore change the offsets of some existing nodes.
1465+ *
1466+ * returns:
1467+ * 0, on success
1468+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1469+ * contain the new property value
1470+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1471+ * -FDT_ERR_BADLAYOUT,
1472+ * -FDT_ERR_BADMAGIC,
1473+ * -FDT_ERR_BADVERSION,
1474+ * -FDT_ERR_BADSTATE,
1475+ * -FDT_ERR_BADSTRUCTURE,
1476+ * -FDT_ERR_BADLAYOUT,
1477+ * -FDT_ERR_TRUNCATED, standard meanings
1478+ */
1479+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1480+ int len, void **prop_data);
1481+
14351482 /**
14361483 * fdt_setprop_u32 - set a property to a 32-bit integer
14371484 * @fdt: pointer to the device tree blob
scripts/dtc/livetree.c+30−1
@@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) · 215 unmodified lines
216216 return old_node;
217217 }
218218
219+void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
220+{
221+ static unsigned int next_orphan_fragment = 0;
222+ struct node *node;
223+ struct property *p;
224+ struct data d = empty_data;
225+ char *name;
226+
227+ d = data_add_marker(d, REF_PHANDLE, ref);
228+ d = data_append_integer(d, 0xffffffff, 32);
229+
230+ p = build_property("target", d);
231+
232+ xasprintf(&name, "fragment@%u",
233+ next_orphan_fragment++);
234+ name_node(new_node, "__overlay__");
235+ node = build_node(p, new_node);
236+ name_node(node, name);
237+
238+ add_child(dt, node);
239+}
240+
219241 struct node *chain_node(struct node *first, struct node *list)
220242 {
221243 assert(first->next_sibling == NULL);
@@ -396,6 +418,12 @@ cell_t propval_cell(struct property *prop) · 174 unmodified lines
396418 return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
397419 }
398420
421+cell_t propval_cell_n(struct property *prop, int n)
422+{
423+ assert(prop->val.len / sizeof(cell_t) >= n);
424+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
425+}
426+
399427 struct property *get_property_by_label(struct node *tree, const char *label,
400428 struct node **node)
401429 {
@@ -478,7 +506,8 @@ struct node *get_node_by_path(struct node *tree, const char *path) · 76 unmodified lines
478506 p = strchr(path, '/');
479507
480508 for_each_child(tree, child) {
481− if (p && strneq(path, child->name, p-path))
509+ if (p && (strlen(child->name) == p-path) &&
510+ strneq(path, child->name, p-path))
482511 return get_node_by_path(child, p+1);
483512 else if (!p && streq(path, child->name))
484513 return child;
scripts/dtc/version_gen.h+1−1
@@ -1 +1 @@
1−#define DTC_VERSION "DTC 1.4.4-g756ffc4f"
1+#define DTC_VERSION "DTC 1.4.5-gb1a60033"