aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/dtc/checks.c282
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped10
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped430
-rw-r--r--scripts/dtc/dtc-parser.y20
-rw-r--r--scripts/dtc/dtc.c2
-rw-r--r--scripts/dtc/dtc.h3
-rw-r--r--scripts/dtc/libfdt/fdt_addresses.c96
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c1
-rw-r--r--scripts/dtc/libfdt/fdt_overlay.c861
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c4
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c24
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c16
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c4
-rw-r--r--scripts/dtc/libfdt/libfdt.h47
-rw-r--r--scripts/dtc/livetree.c31
-rw-r--r--scripts/dtc/version_gen.h2
16 files changed, 1603 insertions, 230 deletions
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 62ea8f83d4a0..08a3a29edae3 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
873 while (size--) 873 while (size--)
874 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 874 reg = (reg << 32) | fdt32_to_cpu(*(cells++));
875 875
876 snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg); 876 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
877 if (!streq(unitname, unit_addr)) 877 if (!streq(unitname, unit_addr))
878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", 878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
879 node->fullpath, unit_addr); 879 node->fullpath, unit_addr);
@@ -956,6 +956,265 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
956WARNING(obsolete_chosen_interrupt_controller, 956WARNING(obsolete_chosen_interrupt_controller,
957 check_obsolete_chosen_interrupt_controller, NULL); 957 check_obsolete_chosen_interrupt_controller, NULL);
958 958
959struct provider {
960 const char *prop_name;
961 const char *cell_name;
962 bool optional;
963};
964
965static 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
1034static 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
1051WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
1052WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
1053WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
1054WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
1055WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
1056WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
1057WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
1058WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
1059WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
1060WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
1061WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
1062WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
1063WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
1064WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
1065WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
1066WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
1067
1068static 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
1090static 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}
1113WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
1114
1115static 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}
1136CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
1137
1138static 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}
1152static 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}
1216WARNING(interrupts_property, check_interrupts_property, &phandle_references);
1217
959static struct check *check_table[] = { 1218static struct check *check_table[] = {
960 &duplicate_node_names, &duplicate_property_names, 1219 &duplicate_node_names, &duplicate_property_names,
961 &node_name_chars, &node_name_format, &property_name_chars, 1220 &node_name_chars, &node_name_format, &property_name_chars,
@@ -987,6 +1246,27 @@ static struct check *check_table[] = {
987 &avoid_default_addr_size, 1246 &avoid_default_addr_size,
988 &obsolete_chosen_interrupt_controller, 1247 &obsolete_chosen_interrupt_controller,
989 1248
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
990 &always_fail, 1270 &always_fail,
991}; 1271};
992 1272
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 64c243772398..011bb9632ff2 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -1397,7 +1397,7 @@ static int yy_get_next_buffer (void)
1397{ 1397{
1398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; 1398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1399 char *source = (yytext_ptr); 1399 char *source = (yytext_ptr);
1400 yy_size_t number_to_move, i; 1400 int number_to_move, i;
1401 int ret_val; 1401 int ret_val;
1402 1402
1403 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) 1403 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)
1426 /* Try to read more data. */ 1426 /* Try to read more data. */
1427 1427
1428 /* First move last chars to start of buffer. */ 1428 /* 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);
1430 1430
1431 for ( i = 0; i < number_to_move; ++i ) 1431 for ( i = 0; i < number_to_move; ++i )
1432 *(dest++) = *(source++); 1432 *(dest++) = *(source++);
@@ -1508,7 +1508,7 @@ static int yy_get_next_buffer (void)
1508 else 1508 else
1509 ret_val = EOB_ACT_CONTINUE_SCAN; 1509 ret_val = EOB_ACT_CONTINUE_SCAN;
1510 1510
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) {
1512 /* Extend the array by 50%, plus the number we really need. */ 1512 /* Extend the array by 50%, plus the number we really need. */
1513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); 1513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1514 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); 1514 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 )
1987 YY_BUFFER_STATE b; 1987 YY_BUFFER_STATE b;
1988 char *buf; 1988 char *buf;
1989 yy_size_t n; 1989 yy_size_t n;
1990 yy_size_t i; 1990 int i;
1991 1991
1992 /* Get memory for full buffer, including space for trailing EOB's. */ 1992 /* 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);
1994 buf = (char *) yyalloc(n ); 1994 buf = (char *) yyalloc(n );
1995 if ( ! buf ) 1995 if ( ! buf )
1996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); 1996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index 0a7a5ed86f04..aea514fa6928 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -448,7 +448,7 @@ union yyalloc
448/* YYNNTS -- Number of nonterminals. */ 448/* YYNNTS -- Number of nonterminals. */
449#define YYNNTS 30 449#define YYNNTS 30
450/* YYNRULES -- Number of rules. */ 450/* YYNRULES -- Number of rules. */
451#define YYNRULES 84 451#define YYNRULES 85
452/* YYNSTATES -- Number of states. */ 452/* YYNSTATES -- Number of states. */
453#define YYNSTATES 149 453#define YYNSTATES 149
454 454
@@ -499,14 +499,14 @@ static const yytype_uint8 yytranslate[] =
499static const yytype_uint16 yyrline[] = 499static const yytype_uint16 yyrline[] =
500{ 500{
501 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, 501 0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
502 153, 161, 165, 170, 181, 191, 206, 214, 217, 224, 502 153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
503 228, 232, 236, 244, 248, 252, 256, 260, 276, 286, 503 238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
504 294, 297, 301, 308, 324, 329, 348, 362, 369, 370, 504 300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
505 371, 378, 382, 383, 387, 388, 392, 393, 397, 398, 505 384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
506 402, 403, 407, 408, 412, 413, 414, 418, 419, 420, 506 412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
507 421, 422, 426, 427, 428, 432, 433, 434, 438, 439, 507 434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
508 448, 457, 461, 462, 463, 464, 469, 472, 476, 484, 508 453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
509 487, 491, 499, 503, 507 509 498, 501, 505, 513, 517, 521
510}; 510};
511#endif 511#endif
512 512
@@ -582,20 +582,20 @@ static const yytype_int8 yypact[] =
582static const yytype_uint8 yydefact[] = 582static const yytype_uint8 yydefact[] =
583{ 583{
584 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, 584 0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
585 0, 7, 0, 38, 39, 0, 0, 10, 0, 2, 585 16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
586 8, 4, 0, 0, 0, 72, 0, 41, 42, 44, 586 8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
587 46, 48, 50, 52, 54, 57, 64, 67, 71, 0, 587 47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
588 17, 11, 0, 0, 0, 0, 73, 74, 75, 40, 588 18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 590 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
591 79, 0, 0, 14, 12, 45, 0, 47, 49, 51, 591 80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
592 53, 55, 56, 60, 61, 59, 58, 62, 63, 65, 592 54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
593 66, 69, 68, 70, 0, 0, 0, 0, 18, 0, 593 67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
594 79, 15, 13, 0, 0, 0, 20, 30, 82, 22, 594 80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
595 84, 0, 81, 80, 43, 21, 83, 0, 0, 16, 595 85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
596 29, 19, 31, 0, 23, 32, 26, 0, 76, 34, 596 30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
597 0, 0, 0, 0, 37, 36, 24, 35, 33, 0, 597 0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
598 77, 78, 25, 0, 28, 0, 0, 0, 27 598 78, 79, 26, 0, 29, 0, 0, 0, 28
599}; 599};
600 600
601 /* YYPGOTO[NTERM-NUM]. */ 601 /* YYPGOTO[NTERM-NUM]. */
@@ -678,28 +678,28 @@ static const yytype_uint8 yystos[] =
678static const yytype_uint8 yyr1[] = 678static const yytype_uint8 yyr1[] =
679{ 679{
680 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, 680 0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
681 53, 54, 54, 54, 54, 54, 55, 56, 56, 57, 681 53, 54, 54, 54, 54, 54, 54, 55, 56, 56,
682 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 682 57, 57, 57, 57, 58, 58, 58, 58, 58, 58,
683 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 683 58, 59, 59, 59, 60, 60, 60, 60, 60, 61,
684 61, 62, 63, 63, 64, 64, 65, 65, 66, 66, 684 61, 61, 62, 63, 63, 64, 64, 65, 65, 66,
685 67, 67, 68, 68, 69, 69, 69, 70, 70, 70, 685 66, 67, 67, 68, 68, 69, 69, 69, 70, 70,
686 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 686 70, 70, 70, 71, 71, 71, 72, 72, 72, 73,
687 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 687 73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
688 76, 76, 77, 77, 77 688 76, 76, 76, 77, 77, 77
689}; 689};
690 690
691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ 691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
692static const yytype_uint8 yyr2[] = 692static const yytype_uint8 yyr2[] =
693{ 693{
694 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, 694 0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
695 2, 2, 3, 4, 3, 4, 5, 0, 2, 4, 695 2, 2, 3, 4, 3, 4, 0, 5, 0, 2,
696 2, 3, 2, 2, 3, 4, 2, 9, 5, 2, 696 4, 2, 3, 2, 2, 3, 4, 2, 9, 5,
697 0, 2, 2, 3, 1, 2, 2, 2, 1, 1, 697 2, 0, 2, 2, 3, 1, 2, 2, 2, 1,
698 3, 1, 1, 5, 1, 3, 1, 3, 1, 3, 698 1, 3, 1, 1, 5, 1, 3, 1, 3, 1,
699 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, 699 3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
700 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 700 3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
701 3, 1, 1, 2, 2, 2, 0, 2, 2, 0, 701 3, 3, 1, 1, 2, 2, 2, 0, 2, 2,
702 2, 2, 2, 3, 2 702 0, 2, 2, 2, 3, 2
703}; 703};
704 704
705 705
@@ -1572,17 +1572,26 @@ yyreduce:
1572 { 1572 {
1573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); 1573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
1574 1574
1575 if (target) 1575 if (target) {
1576 merge_nodes(target, (yyvsp[0].node)); 1576 merge_nodes(target, (yyvsp[0].node));
1577 else 1577 } else {
1578 ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); 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 }
1579 (yyval.node) = (yyvsp[-2].node); 1588 (yyval.node) = (yyvsp[-2].node);
1580 } 1589 }
1581#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ 1590#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
1582 break; 1591 break;
1583 1592
1584 case 15: 1593 case 15:
1585#line 192 "dtc-parser.y" /* yacc.c:1646 */ 1594#line 201 "dtc-parser.y" /* yacc.c:1646 */
1586 { 1595 {
1587 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); 1596 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
1588 1597
@@ -1594,100 +1603,109 @@ yyreduce:
1594 1603
1595 (yyval.node) = (yyvsp[-3].node); 1604 (yyval.node) = (yyvsp[-3].node);
1596 } 1605 }
1597#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ 1606#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
1598 break; 1607 break;
1599 1608
1600 case 16: 1609 case 16:
1601#line 207 "dtc-parser.y" /* yacc.c:1646 */ 1610#line 213 "dtc-parser.y" /* yacc.c:1646 */
1602 { 1611 {
1603 (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); 1612 /* build empty node */
1613 (yyval.node) = name_node(build_node(NULL, NULL), "");
1604 } 1614 }
1605#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ 1615#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
1606 break; 1616 break;
1607 1617
1608 case 17: 1618 case 17:
1609#line 214 "dtc-parser.y" /* yacc.c:1646 */ 1619#line 221 "dtc-parser.y" /* yacc.c:1646 */
1610 { 1620 {
1611 (yyval.proplist) = NULL; 1621 (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
1612 } 1622 }
1613#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ 1623#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
1614 break; 1624 break;
1615 1625
1616 case 18: 1626 case 18:
1617#line 218 "dtc-parser.y" /* yacc.c:1646 */ 1627#line 228 "dtc-parser.y" /* yacc.c:1646 */
1618 { 1628 {
1619 (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); 1629 (yyval.proplist) = NULL;
1620 } 1630 }
1621#line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */ 1631#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
1622 break; 1632 break;
1623 1633
1624 case 19: 1634 case 19:
1625#line 225 "dtc-parser.y" /* yacc.c:1646 */ 1635#line 232 "dtc-parser.y" /* yacc.c:1646 */
1626 { 1636 {
1627 (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); 1637 (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
1628 } 1638 }
1629#line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */ 1639#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
1630 break; 1640 break;
1631 1641
1632 case 20: 1642 case 20:
1633#line 229 "dtc-parser.y" /* yacc.c:1646 */ 1643#line 239 "dtc-parser.y" /* yacc.c:1646 */
1634 { 1644 {
1635 (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); 1645 (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
1636 } 1646 }
1637#line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */ 1647#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
1638 break; 1648 break;
1639 1649
1640 case 21: 1650 case 21:
1641#line 233 "dtc-parser.y" /* yacc.c:1646 */ 1651#line 243 "dtc-parser.y" /* yacc.c:1646 */
1642 { 1652 {
1643 (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); 1653 (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
1644 } 1654 }
1645#line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */ 1655#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
1646 break; 1656 break;
1647 1657
1648 case 22: 1658 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 */
1650 { 1668 {
1651 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); 1669 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
1652 (yyval.prop) = (yyvsp[0].prop); 1670 (yyval.prop) = (yyvsp[0].prop);
1653 } 1671 }
1654#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ 1672#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
1655 break; 1673 break;
1656 1674
1657 case 23: 1675 case 24:
1658#line 245 "dtc-parser.y" /* yacc.c:1646 */ 1676#line 259 "dtc-parser.y" /* yacc.c:1646 */
1659 { 1677 {
1660 (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); 1678 (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
1661 } 1679 }
1662#line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */ 1680#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
1663 break; 1681 break;
1664 1682
1665 case 24: 1683 case 25:
1666#line 249 "dtc-parser.y" /* yacc.c:1646 */ 1684#line 263 "dtc-parser.y" /* yacc.c:1646 */
1667 { 1685 {
1668 (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); 1686 (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
1669 } 1687 }
1670#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ 1688#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
1671 break; 1689 break;
1672 1690
1673 case 25: 1691 case 26:
1674#line 253 "dtc-parser.y" /* yacc.c:1646 */ 1692#line 267 "dtc-parser.y" /* yacc.c:1646 */
1675 { 1693 {
1676 (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); 1694 (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
1677 } 1695 }
1678#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ 1696#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
1679 break; 1697 break;
1680 1698
1681 case 26: 1699 case 27:
1682#line 257 "dtc-parser.y" /* yacc.c:1646 */ 1700#line 271 "dtc-parser.y" /* yacc.c:1646 */
1683 { 1701 {
1684 (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); 1702 (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
1685 } 1703 }
1686#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ 1704#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
1687 break; 1705 break;
1688 1706
1689 case 27: 1707 case 28:
1690#line 261 "dtc-parser.y" /* yacc.c:1646 */ 1708#line 275 "dtc-parser.y" /* yacc.c:1646 */
1691 { 1709 {
1692 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); 1710 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
1693 struct data d; 1711 struct data d;
@@ -1703,11 +1721,11 @@ yyreduce:
1703 (yyval.data) = data_merge((yyvsp[-8].data), d); 1721 (yyval.data) = data_merge((yyvsp[-8].data), d);
1704 fclose(f); 1722 fclose(f);
1705 } 1723 }
1706#line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */ 1724#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
1707 break; 1725 break;
1708 1726
1709 case 28: 1727 case 29:
1710#line 277 "dtc-parser.y" /* yacc.c:1646 */ 1728#line 291 "dtc-parser.y" /* yacc.c:1646 */
1711 { 1729 {
1712 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); 1730 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
1713 struct data d = empty_data; 1731 struct data d = empty_data;
@@ -1717,43 +1735,43 @@ yyreduce:
1717 (yyval.data) = data_merge((yyvsp[-4].data), d); 1735 (yyval.data) = data_merge((yyvsp[-4].data), d);
1718 fclose(f); 1736 fclose(f);
1719 } 1737 }
1720#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ 1738#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
1721 break; 1739 break;
1722 1740
1723 case 29: 1741 case 30:
1724#line 287 "dtc-parser.y" /* yacc.c:1646 */ 1742#line 301 "dtc-parser.y" /* yacc.c:1646 */
1725 { 1743 {
1726 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1744 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
1727 } 1745 }
1728#line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */ 1746#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
1729 break; 1747 break;
1730 1748
1731 case 30: 1749 case 31:
1732#line 294 "dtc-parser.y" /* yacc.c:1646 */ 1750#line 308 "dtc-parser.y" /* yacc.c:1646 */
1733 { 1751 {
1734 (yyval.data) = empty_data; 1752 (yyval.data) = empty_data;
1735 } 1753 }
1736#line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */ 1754#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
1737 break; 1755 break;
1738 1756
1739 case 31: 1757 case 32:
1740#line 298 "dtc-parser.y" /* yacc.c:1646 */ 1758#line 312 "dtc-parser.y" /* yacc.c:1646 */
1741 { 1759 {
1742 (yyval.data) = (yyvsp[-1].data); 1760 (yyval.data) = (yyvsp[-1].data);
1743 } 1761 }
1744#line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */ 1762#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
1745 break; 1763 break;
1746 1764
1747 case 32: 1765 case 33:
1748#line 302 "dtc-parser.y" /* yacc.c:1646 */ 1766#line 316 "dtc-parser.y" /* yacc.c:1646 */
1749 { 1767 {
1750 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1768 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
1751 } 1769 }
1752#line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */ 1770#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
1753 break; 1771 break;
1754 1772
1755 case 33: 1773 case 34:
1756#line 309 "dtc-parser.y" /* yacc.c:1646 */ 1774#line 323 "dtc-parser.y" /* yacc.c:1646 */
1757 { 1775 {
1758 unsigned long long bits; 1776 unsigned long long bits;
1759 1777
@@ -1769,20 +1787,20 @@ yyreduce:
1769 (yyval.array).data = empty_data; 1787 (yyval.array).data = empty_data;
1770 (yyval.array).bits = bits; 1788 (yyval.array).bits = bits;
1771 } 1789 }
1772#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ 1790#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
1773 break; 1791 break;
1774 1792
1775 case 34: 1793 case 35:
1776#line 325 "dtc-parser.y" /* yacc.c:1646 */ 1794#line 339 "dtc-parser.y" /* yacc.c:1646 */
1777 { 1795 {
1778 (yyval.array).data = empty_data; 1796 (yyval.array).data = empty_data;
1779 (yyval.array).bits = 32; 1797 (yyval.array).bits = 32;
1780 } 1798 }
1781#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ 1799#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
1782 break; 1800 break;
1783 1801
1784 case 35: 1802 case 36:
1785#line 330 "dtc-parser.y" /* yacc.c:1646 */ 1803#line 344 "dtc-parser.y" /* yacc.c:1646 */
1786 { 1804 {
1787 if ((yyvsp[-1].array).bits < 64) { 1805 if ((yyvsp[-1].array).bits < 64) {
1788 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; 1806 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1801,11 +1819,11 @@ yyreduce:
1801 1819
1802 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); 1820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
1803 } 1821 }
1804#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ 1822#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
1805 break; 1823 break;
1806 1824
1807 case 36: 1825 case 37:
1808#line 349 "dtc-parser.y" /* yacc.c:1646 */ 1826#line 363 "dtc-parser.y" /* yacc.c:1646 */
1809 { 1827 {
1810 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); 1828 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
1811 1829
@@ -1819,129 +1837,129 @@ yyreduce:
1819 1837
1820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); 1838 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
1821 } 1839 }
1822#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ 1840#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
1823 break; 1841 break;
1824 1842
1825 case 37: 1843 case 38:
1826#line 363 "dtc-parser.y" /* yacc.c:1646 */ 1844#line 377 "dtc-parser.y" /* yacc.c:1646 */
1827 { 1845 {
1828 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); 1846 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
1829 } 1847 }
1830#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ 1848#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
1831 break; 1849 break;
1832 1850
1833 case 40: 1851 case 41:
1834#line 372 "dtc-parser.y" /* yacc.c:1646 */ 1852#line 386 "dtc-parser.y" /* yacc.c:1646 */
1835 { 1853 {
1836 (yyval.integer) = (yyvsp[-1].integer); 1854 (yyval.integer) = (yyvsp[-1].integer);
1837 } 1855 }
1838#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */ 1856#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
1839 break; 1857 break;
1840 1858
1841 case 43: 1859 case 44:
1842#line 383 "dtc-parser.y" /* yacc.c:1646 */ 1860#line 397 "dtc-parser.y" /* yacc.c:1646 */
1843 { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } 1861 { (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 */
1845 break; 1863 break;
1846 1864
1847 case 45: 1865 case 46:
1848#line 388 "dtc-parser.y" /* yacc.c:1646 */ 1866#line 402 "dtc-parser.y" /* yacc.c:1646 */
1849 { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } 1867 { (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 */
1851 break; 1869 break;
1852 1870
1853 case 47: 1871 case 48:
1854#line 393 "dtc-parser.y" /* yacc.c:1646 */ 1872#line 407 "dtc-parser.y" /* yacc.c:1646 */
1855 { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } 1873 { (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 */
1857 break; 1875 break;
1858 1876
1859 case 49: 1877 case 50:
1860#line 398 "dtc-parser.y" /* yacc.c:1646 */ 1878#line 412 "dtc-parser.y" /* yacc.c:1646 */
1861 { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } 1879 { (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 */
1863 break; 1881 break;
1864 1882
1865 case 51: 1883 case 52:
1866#line 403 "dtc-parser.y" /* yacc.c:1646 */ 1884#line 417 "dtc-parser.y" /* yacc.c:1646 */
1867 { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } 1885 { (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 */
1869 break; 1887 break;
1870 1888
1871 case 53: 1889 case 54:
1872#line 408 "dtc-parser.y" /* yacc.c:1646 */ 1890#line 422 "dtc-parser.y" /* yacc.c:1646 */
1873 { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } 1891 { (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 */
1875 break; 1893 break;
1876 1894
1877 case 55: 1895 case 56:
1878#line 413 "dtc-parser.y" /* yacc.c:1646 */ 1896#line 427 "dtc-parser.y" /* yacc.c:1646 */
1879 { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } 1897 { (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 */
1881 break; 1899 break;
1882 1900
1883 case 56: 1901 case 57:
1884#line 414 "dtc-parser.y" /* yacc.c:1646 */ 1902#line 428 "dtc-parser.y" /* yacc.c:1646 */
1885 { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } 1903 { (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 */
1887 break; 1905 break;
1888 1906
1889 case 58: 1907 case 59:
1890#line 419 "dtc-parser.y" /* yacc.c:1646 */ 1908#line 433 "dtc-parser.y" /* yacc.c:1646 */
1891 { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } 1909 { (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 */
1893 break; 1911 break;
1894 1912
1895 case 59: 1913 case 60:
1896#line 420 "dtc-parser.y" /* yacc.c:1646 */ 1914#line 434 "dtc-parser.y" /* yacc.c:1646 */
1897 { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } 1915 { (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 */
1899 break; 1917 break;
1900 1918
1901 case 60: 1919 case 61:
1902#line 421 "dtc-parser.y" /* yacc.c:1646 */ 1920#line 435 "dtc-parser.y" /* yacc.c:1646 */
1903 { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } 1921 { (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 */
1905 break; 1923 break;
1906 1924
1907 case 61: 1925 case 62:
1908#line 422 "dtc-parser.y" /* yacc.c:1646 */ 1926#line 436 "dtc-parser.y" /* yacc.c:1646 */
1909 { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } 1927 { (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 */
1911 break; 1929 break;
1912 1930
1913 case 62: 1931 case 63:
1914#line 426 "dtc-parser.y" /* yacc.c:1646 */ 1932#line 440 "dtc-parser.y" /* yacc.c:1646 */
1915 { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } 1933 { (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 */
1917 break; 1935 break;
1918 1936
1919 case 63: 1937 case 64:
1920#line 427 "dtc-parser.y" /* yacc.c:1646 */ 1938#line 441 "dtc-parser.y" /* yacc.c:1646 */
1921 { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } 1939 { (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 */
1923 break; 1941 break;
1924 1942
1925 case 65: 1943 case 66:
1926#line 432 "dtc-parser.y" /* yacc.c:1646 */ 1944#line 446 "dtc-parser.y" /* yacc.c:1646 */
1927 { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } 1945 { (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 */
1929 break; 1947 break;
1930 1948
1931 case 66: 1949 case 67:
1932#line 433 "dtc-parser.y" /* yacc.c:1646 */ 1950#line 447 "dtc-parser.y" /* yacc.c:1646 */
1933 { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } 1951 { (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 */
1935 break; 1953 break;
1936 1954
1937 case 68: 1955 case 69:
1938#line 438 "dtc-parser.y" /* yacc.c:1646 */ 1956#line 452 "dtc-parser.y" /* yacc.c:1646 */
1939 { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } 1957 { (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 */
1941 break; 1959 break;
1942 1960
1943 case 69: 1961 case 70:
1944#line 440 "dtc-parser.y" /* yacc.c:1646 */ 1962#line 454 "dtc-parser.y" /* yacc.c:1646 */
1945 { 1963 {
1946 if ((yyvsp[0].integer) != 0) { 1964 if ((yyvsp[0].integer) != 0) {
1947 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); 1965 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1950,11 +1968,11 @@ yyreduce:
1950 (yyval.integer) = 0; 1968 (yyval.integer) = 0;
1951 } 1969 }
1952 } 1970 }
1953#line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */ 1971#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
1954 break; 1972 break;
1955 1973
1956 case 70: 1974 case 71:
1957#line 449 "dtc-parser.y" /* yacc.c:1646 */ 1975#line 463 "dtc-parser.y" /* yacc.c:1646 */
1958 { 1976 {
1959 if ((yyvsp[0].integer) != 0) { 1977 if ((yyvsp[0].integer) != 0) {
1960 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); 1978 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1963,103 +1981,103 @@ yyreduce:
1963 (yyval.integer) = 0; 1981 (yyval.integer) = 0;
1964 } 1982 }
1965 } 1983 }
1966#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ 1984#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
1967 break; 1985 break;
1968 1986
1969 case 73: 1987 case 74:
1970#line 462 "dtc-parser.y" /* yacc.c:1646 */ 1988#line 476 "dtc-parser.y" /* yacc.c:1646 */
1971 { (yyval.integer) = -(yyvsp[0].integer); } 1989 { (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 */
1973 break; 1991 break;
1974 1992
1975 case 74: 1993 case 75:
1976#line 463 "dtc-parser.y" /* yacc.c:1646 */ 1994#line 477 "dtc-parser.y" /* yacc.c:1646 */
1977 { (yyval.integer) = ~(yyvsp[0].integer); } 1995 { (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 */
1979 break; 1997 break;
1980 1998
1981 case 75: 1999 case 76:
1982#line 464 "dtc-parser.y" /* yacc.c:1646 */ 2000#line 478 "dtc-parser.y" /* yacc.c:1646 */
1983 { (yyval.integer) = !(yyvsp[0].integer); } 2001 { (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 */
1985 break; 2003 break;
1986 2004
1987 case 76: 2005 case 77:
1988#line 469 "dtc-parser.y" /* yacc.c:1646 */ 2006#line 483 "dtc-parser.y" /* yacc.c:1646 */
1989 { 2007 {
1990 (yyval.data) = empty_data; 2008 (yyval.data) = empty_data;
1991 } 2009 }
1992#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ 2010#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
1993 break; 2011 break;
1994 2012
1995 case 77: 2013 case 78:
1996#line 473 "dtc-parser.y" /* yacc.c:1646 */ 2014#line 487 "dtc-parser.y" /* yacc.c:1646 */
1997 { 2015 {
1998 (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); 2016 (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
1999 } 2017 }
2000#line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */ 2018#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
2001 break; 2019 break;
2002 2020
2003 case 78: 2021 case 79:
2004#line 477 "dtc-parser.y" /* yacc.c:1646 */ 2022#line 491 "dtc-parser.y" /* yacc.c:1646 */
2005 { 2023 {
2006 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 2024 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
2007 } 2025 }
2008#line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */ 2026#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
2009 break; 2027 break;
2010 2028
2011 case 79: 2029 case 80:
2012#line 484 "dtc-parser.y" /* yacc.c:1646 */ 2030#line 498 "dtc-parser.y" /* yacc.c:1646 */
2013 { 2031 {
2014 (yyval.nodelist) = NULL; 2032 (yyval.nodelist) = NULL;
2015 } 2033 }
2016#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ 2034#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
2017 break; 2035 break;
2018 2036
2019 case 80: 2037 case 81:
2020#line 488 "dtc-parser.y" /* yacc.c:1646 */ 2038#line 502 "dtc-parser.y" /* yacc.c:1646 */
2021 { 2039 {
2022 (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); 2040 (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
2023 } 2041 }
2024#line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */ 2042#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
2025 break; 2043 break;
2026 2044
2027 case 81: 2045 case 82:
2028#line 492 "dtc-parser.y" /* yacc.c:1646 */ 2046#line 506 "dtc-parser.y" /* yacc.c:1646 */
2029 { 2047 {
2030 ERROR(&(yylsp[0]), "Properties must precede subnodes"); 2048 ERROR(&(yylsp[0]), "Properties must precede subnodes");
2031 YYERROR; 2049 YYERROR;
2032 } 2050 }
2033#line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */ 2051#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
2034 break; 2052 break;
2035 2053
2036 case 82: 2054 case 83:
2037#line 500 "dtc-parser.y" /* yacc.c:1646 */ 2055#line 514 "dtc-parser.y" /* yacc.c:1646 */
2038 { 2056 {
2039 (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); 2057 (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
2040 } 2058 }
2041#line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */ 2059#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
2042 break; 2060 break;
2043 2061
2044 case 83: 2062 case 84:
2045#line 504 "dtc-parser.y" /* yacc.c:1646 */ 2063#line 518 "dtc-parser.y" /* yacc.c:1646 */
2046 { 2064 {
2047 (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); 2065 (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
2048 } 2066 }
2049#line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */ 2067#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
2050 break; 2068 break;
2051 2069
2052 case 84: 2070 case 85:
2053#line 508 "dtc-parser.y" /* yacc.c:1646 */ 2071#line 522 "dtc-parser.y" /* yacc.c:1646 */
2054 { 2072 {
2055 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); 2073 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
2056 (yyval.node) = (yyvsp[0].node); 2074 (yyval.node) = (yyvsp[0].node);
2057 } 2075 }
2058#line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */ 2076#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
2059 break; 2077 break;
2060 2078
2061 2079
2062#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ 2080#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
2063 default: break; 2081 default: break;
2064 } 2082 }
2065 /* User semantic actions sometimes alter yychar, and that requires 2083 /* User semantic actions sometimes alter yychar, and that requires
@@ -2294,7 +2312,7 @@ yyreturn:
2294#endif 2312#endif
2295 return yyresult; 2313 return yyresult;
2296} 2314}
2297#line 514 "dtc-parser.y" /* yacc.c:1906 */ 2315#line 528 "dtc-parser.y" /* yacc.c:1906 */
2298 2316
2299 2317
2300void yyerror(char const *s) 2318void yyerror(char const *s)
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index ca3f5003427c..affc81a8f9ab 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -182,10 +182,19 @@ devicetree:
182 { 182 {
183 struct node *target = get_node_by_ref($1, $2); 183 struct node *target = get_node_by_ref($1, $2);
184 184
185 if (target) 185 if (target) {
186 merge_nodes(target, $3); 186 merge_nodes(target, $3);
187 else 187 } else {
188 ERROR(&@2, "Label or path %s not found", $2); 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 }
189 $$ = $1; 198 $$ = $1;
190 } 199 }
191 | devicetree DT_DEL_NODE DT_REF ';' 200 | devicetree DT_DEL_NODE DT_REF ';'
@@ -200,6 +209,11 @@ devicetree:
200 209
201 $$ = $1; 210 $$ = $1;
202 } 211 }
212 | /* empty */
213 {
214 /* build empty node */
215 $$ = name_node(build_node(NULL, NULL), "");
216 }
203 ; 217 ;
204 218
205nodedef: 219nodedef:
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index f5eed9d72c02..5ed873c72ad1 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -31,7 +31,7 @@ int reservenum; /* Number of memory reservation slots */
31int minsize; /* Minimum blob size */ 31int minsize; /* Minimum blob size */
32int padsize; /* Additional padding to blob */ 32int padsize; /* Additional padding to blob */
33int alignsize; /* Additional padding to blob accroding to the alignsize */ 33int alignsize; /* Additional padding to blob accroding to the alignsize */
34int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ 34int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
35int generate_symbols; /* enable symbols & fixup support */ 35int generate_symbols; /* enable symbols & fixup support */
36int generate_fixups; /* suppress generation of fixups on symbol support */ 36int generate_fixups; /* suppress generation of fixups on symbol support */
37int auto_label_aliases; /* auto generate labels -> aliases */ 37int auto_label_aliases; /* auto generate labels -> aliases */
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index fc24e17510fd..35cf926cc14a 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -31,6 +31,7 @@
31#include <ctype.h> 31#include <ctype.h>
32#include <errno.h> 32#include <errno.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <inttypes.h>
34 35
35#include <libfdt_env.h> 36#include <libfdt_env.h>
36#include <fdt.h> 37#include <fdt.h>
@@ -202,6 +203,7 @@ struct node *build_node_delete(void);
202struct node *name_node(struct node *node, char *name); 203struct node *name_node(struct node *node, char *name);
203struct node *chain_node(struct node *first, struct node *list); 204struct node *chain_node(struct node *first, struct node *list);
204struct node *merge_nodes(struct node *old_node, struct node *new_node); 205struct node *merge_nodes(struct node *old_node, struct node *new_node);
206void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
205 207
206void add_property(struct node *node, struct property *prop); 208void add_property(struct node *node, struct property *prop);
207void delete_property_by_name(struct node *node, char *name); 209void delete_property_by_name(struct node *node, char *name);
@@ -215,6 +217,7 @@ void append_to_property(struct node *node,
215const char *get_unitname(struct node *node); 217const char *get_unitname(struct node *node);
216struct property *get_property(struct node *node, const char *propname); 218struct property *get_property(struct node *node, const char *propname);
217cell_t propval_cell(struct property *prop); 219cell_t propval_cell(struct property *prop);
220cell_t propval_cell_n(struct property *prop, int n);
218struct property *get_property_by_label(struct node *tree, const char *label, 221struct property *get_property_by_label(struct node *tree, const char *label,
219 struct node **node); 222 struct node **node);
220struct marker *get_marker_label(struct node *tree, const char *label, 223struct marker *get_marker_label(struct node *tree, const char *label,
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
new file mode 100644
index 000000000000..eff4dbcc729d
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -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
58int 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
78int 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}
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
index f72d13b1d19c..f2ae9b77c285 100644
--- a/scripts/dtc/libfdt/fdt_empty_tree.c
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize)
81 81
82 return fdt_open_into(buf, buf, bufsize); 82 return fdt_open_into(buf, buf, bufsize);
83} 83}
84
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
new file mode 100644
index 000000000000..bd81241e6658
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -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 */
22static 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 */
52static 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 */
110static 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 */
150static 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 */
187static 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 */
214static 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 */
318static 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 */
361static 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 */
421static 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 */
503static 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 */
550static 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 */
612static 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
644static 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 */
688static 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
813int 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
848err:
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}
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 3d00d2eee0e3..08de2cce674d 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset,
60{ 60{
61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); 61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
62 62
63 if (! p) 63 if (!p)
64 /* short match */ 64 /* short match */
65 return 0; 65 return 0;
66 66
@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
327 const struct fdt_property *prop; 327 const struct fdt_property *prop;
328 328
329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); 329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
330 if (! prop) 330 if (!prop)
331 return NULL; 331 return NULL;
332 332
333 return prop->data; 333 return prop->data;
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 3fd5847377c9..5c3a2bb0bc6b 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
207 int err; 207 int err;
208 208
209 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); 209 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
210 if (! (*prop)) 210 if (!*prop)
211 return oldlen; 211 return oldlen;
212 212
213 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), 213 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)
269 return 0; 269 return 0;
270} 270}
271 271
272int fdt_setprop(void *fdt, int nodeoffset, const char *name, 272int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
273 const void *val, int len) 273 int len, void **prop_data)
274{ 274{
275 struct fdt_property *prop; 275 struct fdt_property *prop;
276 int err; 276 int err;
@@ -283,8 +283,22 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
283 if (err) 283 if (err)
284 return err; 284 return err;
285 285
286 *prop_data = prop->data;
287 return 0;
288}
289
290int 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
286 if (len) 300 if (len)
287 memcpy(prop->data, val, len); 301 memcpy(prop_data, val, len);
288 return 0; 302 return 0;
289} 303}
290 304
@@ -323,7 +337,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
323 FDT_RW_CHECK_HEADER(fdt); 337 FDT_RW_CHECK_HEADER(fdt);
324 338
325 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
326 if (! prop) 340 if (!prop)
327 return len; 341 return len;
328 342
329 proplen = sizeof(*prop) + FDT_TAGALIGN(len); 343 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 6a804859fd0c..2bd15e7aef87 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
220 return offset; 220 return offset;
221} 221}
222 222
223int fdt_property(void *fdt, const char *name, const void *val, int len) 223int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
224{ 224{
225 struct fdt_property *prop; 225 struct fdt_property *prop;
226 int nameoff; 226 int nameoff;
@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
238 prop->tag = cpu_to_fdt32(FDT_PROP); 238 prop->tag = cpu_to_fdt32(FDT_PROP);
239 prop->nameoff = cpu_to_fdt32(nameoff); 239 prop->nameoff = cpu_to_fdt32(nameoff);
240 prop->len = cpu_to_fdt32(len); 240 prop->len = cpu_to_fdt32(len);
241 memcpy(prop->data, val, len); 241 *valp = prop->data;
242 return 0;
243}
244
245int 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);
242 return 0; 254 return 0;
243} 255}
244 256
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 6aaab399929c..5e859198622b 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
82 int proplen; 82 int proplen;
83 83
84 propval = fdt_getprop(fdt, nodeoffset, name, &proplen); 84 propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
85 if (! propval) 85 if (!propval)
86 return proplen; 86 return proplen;
87 87
88 if (proplen != len) 88 if (proplen != len)
@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
107 int len; 107 int len;
108 108
109 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 109 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
110 if (! prop) 110 if (!prop)
111 return len; 111 return len;
112 112
113 _fdt_nop_region(prop, len + sizeof(*prop)); 113 _fdt_nop_region(prop, len + sizeof(*prop));
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index ba86caa73d01..7f83023ee109 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1314,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1314{ 1314{
1315 return fdt_property_u32(fdt, name, val); 1315 return fdt_property_u32(fdt, name, val);
1316} 1316}
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 */
1331int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1332
1317#define fdt_property_string(fdt, name, str) \ 1333#define fdt_property_string(fdt, name, str) \
1318 fdt_property(fdt, name, str, strlen(str)+1) 1334 fdt_property(fdt, name, str, strlen(str)+1)
1319int fdt_end_node(void *fdt); 1335int fdt_end_node(void *fdt);
@@ -1433,6 +1449,37 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1433 const void *val, int len); 1449 const void *val, int len);
1434 1450
1435/** 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 */
1479int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1480 int len, void **prop_data);
1481
1482/**
1436 * fdt_setprop_u32 - set a property to a 32-bit integer 1483 * fdt_setprop_u32 - set a property to a 32-bit integer
1437 * @fdt: pointer to the device tree blob 1484 * @fdt: pointer to the device tree blob
1438 * @nodeoffset: offset of the node whose property to change 1485 * @nodeoffset: offset of the node whose property to change
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 3673de07e4e5..6846ad2fd6d2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
216 return old_node; 216 return old_node;
217} 217}
218 218
219void 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
219struct node *chain_node(struct node *first, struct node *list) 241struct node *chain_node(struct node *first, struct node *list)
220{ 242{
221 assert(first->next_sibling == NULL); 243 assert(first->next_sibling == NULL);
@@ -396,6 +418,12 @@ cell_t propval_cell(struct property *prop)
396 return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); 418 return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
397} 419}
398 420
421cell_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
399struct property *get_property_by_label(struct node *tree, const char *label, 427struct property *get_property_by_label(struct node *tree, const char *label,
400 struct node **node) 428 struct node **node)
401{ 429{
@@ -478,7 +506,8 @@ struct node *get_node_by_path(struct node *tree, const char *path)
478 p = strchr(path, '/'); 506 p = strchr(path, '/');
479 507
480 for_each_child(tree, child) { 508 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))
482 return get_node_by_path(child, p+1); 511 return get_node_by_path(child, p+1);
483 else if (!p && streq(path, child->name)) 512 else if (!p && streq(path, child->name))
484 return child; 513 return child;
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 1229e07b4912..d88393cab14a 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
#define DTC_VERSION "DTC 1.4.4-g756ffc4f" #define DTC_VERSION "DTC 1.4.5-gb1a60033"