Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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/

Signed-off-by: Rob Herring <robh@kernel.org>

+1640 -267
+281 -1
scripts/dtc/checks.c
··· 873 873 while (size--) 874 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 877 if (!streq(unitname, unit_addr)) 878 878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", 879 879 node->fullpath, unit_addr); ··· 956 956 WARNING(obsolete_chosen_interrupt_controller, 957 957 check_obsolete_chosen_interrupt_controller, NULL); 958 958 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 + 959 1218 static struct check *check_table[] = { 960 1219 &duplicate_node_names, &duplicate_property_names, 961 1220 &node_name_chars, &node_name_format, &property_name_chars, ··· 1245 986 1246 987 &avoid_default_addr_size, 1247 988 &obsolete_chosen_interrupt_controller, 989 + 990 + &clocks_property, 991 + &cooling_device_property, 992 + &dmas_property, 993 + &hwlocks_property, 994 + &interrupts_extended_property, 995 + &io_channels_property, 996 + &iommus_property, 997 + &mboxes_property, 998 + &msi_parent_property, 999 + &mux_controls_property, 1000 + &phys_property, 1001 + &power_domains_property, 1002 + &pwms_property, 1003 + &resets_property, 1004 + &sound_dais_property, 1005 + &thermal_sensors_property, 1006 + 1007 + &deprecated_gpio_property, 1008 + &gpios_property, 1009 + &interrupts_property, 1248 1010 1249 1011 &always_fail, 1250 1012 };
+5 -5
scripts/dtc/dtc-lexer.lex.c_shipped
··· 1397 1397 { 1398 1398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; 1399 1399 char *source = (yytext_ptr); 1400 - yy_size_t number_to_move, i; 1400 + int number_to_move, i; 1401 1401 int ret_val; 1402 1402 1403 1403 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) ··· 1426 1426 /* Try to read more data. */ 1427 1427 1428 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 1431 for ( i = 0; i < number_to_move; ++i ) 1432 1432 *(dest++) = *(source++); ··· 1508 1508 else 1509 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 1512 /* Extend the array by 50%, plus the number we really need. */ 1513 1513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); 1514 1514 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); ··· 1987 1987 YY_BUFFER_STATE b; 1988 1988 char *buf; 1989 1989 yy_size_t n; 1990 - yy_size_t i; 1990 + int i; 1991 1991 1992 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 1994 buf = (char *) yyalloc(n ); 1995 1995 if ( ! buf ) 1996 1996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+261 -243
scripts/dtc/dtc-parser.tab.c_shipped
··· 448 448 /* YYNNTS -- Number of nonterminals. */ 449 449 #define YYNNTS 30 450 450 /* YYNRULES -- Number of rules. */ 451 - #define YYNRULES 84 451 + #define YYNRULES 85 452 452 /* YYNSTATES -- Number of states. */ 453 453 #define YYNSTATES 149 454 454 ··· 499 499 static const yytype_uint16 yyrline[] = 500 500 { 501 501 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 510 510 }; 511 511 #endif 512 512 ··· 582 582 static const yytype_uint8 yydefact[] = 583 583 { 584 584 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, 589 589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 590 590 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 599 599 }; 600 600 601 601 /* YYPGOTO[NTERM-NUM]. */ ··· 678 678 static const yytype_uint8 yyr1[] = 679 679 { 680 680 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 689 689 }; 690 690 691 691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ 692 692 static const yytype_uint8 yyr2[] = 693 693 { 694 694 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 703 703 }; 704 704 705 705 ··· 1572 1572 { 1573 1573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); 1574 1574 1575 - if (target) 1575 + if (target) { 1576 1576 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 + } 1579 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 1591 break; 1583 1592 1584 1593 case 15: 1585 - #line 192 "dtc-parser.y" /* yacc.c:1646 */ 1594 + #line 201 "dtc-parser.y" /* yacc.c:1646 */ 1586 1595 { 1587 1596 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); 1588 1597 ··· 1603 1594 1604 1595 (yyval.node) = (yyvsp[-3].node); 1605 1596 } 1606 - #line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ 1597 + #line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */ 1607 1598 break; 1608 1599 1609 1600 case 16: 1610 - #line 207 "dtc-parser.y" /* yacc.c:1646 */ 1601 + #line 213 "dtc-parser.y" /* yacc.c:1646 */ 1611 1602 { 1612 - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); 1603 + /* build empty node */ 1604 + (yyval.node) = name_node(build_node(NULL, NULL), ""); 1613 1605 } 1614 - #line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ 1606 + #line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */ 1615 1607 break; 1616 1608 1617 1609 case 17: 1618 - #line 214 "dtc-parser.y" /* yacc.c:1646 */ 1610 + #line 221 "dtc-parser.y" /* yacc.c:1646 */ 1619 1611 { 1620 - (yyval.proplist) = NULL; 1612 + (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); 1621 1613 } 1622 - #line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ 1614 + #line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */ 1623 1615 break; 1624 1616 1625 1617 case 18: 1626 - #line 218 "dtc-parser.y" /* yacc.c:1646 */ 1618 + #line 228 "dtc-parser.y" /* yacc.c:1646 */ 1627 1619 { 1628 - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); 1620 + (yyval.proplist) = NULL; 1629 1621 } 1630 - #line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */ 1622 + #line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */ 1631 1623 break; 1632 1624 1633 1625 case 19: 1634 - #line 225 "dtc-parser.y" /* yacc.c:1646 */ 1626 + #line 232 "dtc-parser.y" /* yacc.c:1646 */ 1635 1627 { 1636 - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); 1628 + (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); 1637 1629 } 1638 - #line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */ 1630 + #line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */ 1639 1631 break; 1640 1632 1641 1633 case 20: 1642 - #line 229 "dtc-parser.y" /* yacc.c:1646 */ 1634 + #line 239 "dtc-parser.y" /* yacc.c:1646 */ 1643 1635 { 1644 - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); 1636 + (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); 1645 1637 } 1646 - #line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */ 1638 + #line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */ 1647 1639 break; 1648 1640 1649 1641 case 21: 1650 - #line 233 "dtc-parser.y" /* yacc.c:1646 */ 1642 + #line 243 "dtc-parser.y" /* yacc.c:1646 */ 1651 1643 { 1652 - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); 1644 + (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); 1653 1645 } 1654 - #line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */ 1646 + #line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */ 1655 1647 break; 1656 1648 1657 1649 case 22: 1658 - #line 237 "dtc-parser.y" /* yacc.c:1646 */ 1650 + #line 247 "dtc-parser.y" /* yacc.c:1646 */ 1651 + { 1652 + (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); 1653 + } 1654 + #line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */ 1655 + break; 1656 + 1657 + case 23: 1658 + #line 251 "dtc-parser.y" /* yacc.c:1646 */ 1659 1659 { 1660 1660 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); 1661 1661 (yyval.prop) = (yyvsp[0].prop); 1662 1662 } 1663 - #line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ 1664 - break; 1665 - 1666 - case 23: 1667 - #line 245 "dtc-parser.y" /* yacc.c:1646 */ 1668 - { 1669 - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); 1670 - } 1671 - #line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */ 1663 + #line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */ 1672 1664 break; 1673 1665 1674 1666 case 24: 1675 - #line 249 "dtc-parser.y" /* yacc.c:1646 */ 1667 + #line 259 "dtc-parser.y" /* yacc.c:1646 */ 1676 1668 { 1677 - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); 1669 + (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); 1678 1670 } 1679 - #line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ 1671 + #line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ 1680 1672 break; 1681 1673 1682 1674 case 25: 1683 - #line 253 "dtc-parser.y" /* yacc.c:1646 */ 1675 + #line 263 "dtc-parser.y" /* yacc.c:1646 */ 1684 1676 { 1685 - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); 1677 + (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); 1686 1678 } 1687 - #line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ 1679 + #line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ 1688 1680 break; 1689 1681 1690 1682 case 26: 1691 - #line 257 "dtc-parser.y" /* yacc.c:1646 */ 1683 + #line 267 "dtc-parser.y" /* yacc.c:1646 */ 1692 1684 { 1693 - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); 1685 + (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); 1694 1686 } 1695 - #line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ 1687 + #line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ 1696 1688 break; 1697 1689 1698 1690 case 27: 1699 - #line 261 "dtc-parser.y" /* yacc.c:1646 */ 1691 + #line 271 "dtc-parser.y" /* yacc.c:1646 */ 1692 + { 1693 + (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); 1694 + } 1695 + #line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ 1696 + break; 1697 + 1698 + case 28: 1699 + #line 275 "dtc-parser.y" /* yacc.c:1646 */ 1700 1700 { 1701 1701 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); 1702 1702 struct data d; ··· 1721 1703 (yyval.data) = data_merge((yyvsp[-8].data), d); 1722 1704 fclose(f); 1723 1705 } 1724 - #line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */ 1706 + #line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */ 1725 1707 break; 1726 1708 1727 - case 28: 1728 - #line 277 "dtc-parser.y" /* yacc.c:1646 */ 1709 + case 29: 1710 + #line 291 "dtc-parser.y" /* yacc.c:1646 */ 1729 1711 { 1730 1712 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); 1731 1713 struct data d = empty_data; ··· 1735 1717 (yyval.data) = data_merge((yyvsp[-4].data), d); 1736 1718 fclose(f); 1737 1719 } 1738 - #line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ 1739 - break; 1740 - 1741 - case 29: 1742 - #line 287 "dtc-parser.y" /* yacc.c:1646 */ 1743 - { 1744 - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1745 - } 1746 - #line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */ 1720 + #line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */ 1747 1721 break; 1748 1722 1749 1723 case 30: 1750 - #line 294 "dtc-parser.y" /* yacc.c:1646 */ 1751 - { 1752 - (yyval.data) = empty_data; 1753 - } 1754 - #line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */ 1755 - break; 1756 - 1757 - case 31: 1758 - #line 298 "dtc-parser.y" /* yacc.c:1646 */ 1759 - { 1760 - (yyval.data) = (yyvsp[-1].data); 1761 - } 1762 - #line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */ 1763 - break; 1764 - 1765 - case 32: 1766 - #line 302 "dtc-parser.y" /* yacc.c:1646 */ 1724 + #line 301 "dtc-parser.y" /* yacc.c:1646 */ 1767 1725 { 1768 1726 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1769 1727 } 1770 - #line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */ 1728 + #line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ 1729 + break; 1730 + 1731 + case 31: 1732 + #line 308 "dtc-parser.y" /* yacc.c:1646 */ 1733 + { 1734 + (yyval.data) = empty_data; 1735 + } 1736 + #line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */ 1737 + break; 1738 + 1739 + case 32: 1740 + #line 312 "dtc-parser.y" /* yacc.c:1646 */ 1741 + { 1742 + (yyval.data) = (yyvsp[-1].data); 1743 + } 1744 + #line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */ 1771 1745 break; 1772 1746 1773 1747 case 33: 1774 - #line 309 "dtc-parser.y" /* yacc.c:1646 */ 1748 + #line 316 "dtc-parser.y" /* yacc.c:1646 */ 1749 + { 1750 + (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1751 + } 1752 + #line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */ 1753 + break; 1754 + 1755 + case 34: 1756 + #line 323 "dtc-parser.y" /* yacc.c:1646 */ 1775 1757 { 1776 1758 unsigned long long bits; 1777 1759 ··· 1787 1769 (yyval.array).data = empty_data; 1788 1770 (yyval.array).bits = bits; 1789 1771 } 1790 - #line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ 1772 + #line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ 1791 1773 break; 1792 1774 1793 - case 34: 1794 - #line 325 "dtc-parser.y" /* yacc.c:1646 */ 1775 + case 35: 1776 + #line 339 "dtc-parser.y" /* yacc.c:1646 */ 1795 1777 { 1796 1778 (yyval.array).data = empty_data; 1797 1779 (yyval.array).bits = 32; 1798 1780 } 1799 - #line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ 1781 + #line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */ 1800 1782 break; 1801 1783 1802 - case 35: 1803 - #line 330 "dtc-parser.y" /* yacc.c:1646 */ 1784 + case 36: 1785 + #line 344 "dtc-parser.y" /* yacc.c:1646 */ 1804 1786 { 1805 1787 if ((yyvsp[-1].array).bits < 64) { 1806 1788 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; ··· 1819 1801 1820 1802 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); 1821 1803 } 1822 - #line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ 1804 + #line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ 1823 1805 break; 1824 1806 1825 - case 36: 1826 - #line 349 "dtc-parser.y" /* yacc.c:1646 */ 1807 + case 37: 1808 + #line 363 "dtc-parser.y" /* yacc.c:1646 */ 1827 1809 { 1828 1810 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); 1829 1811 ··· 1837 1819 1838 1820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); 1839 1821 } 1840 - #line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ 1822 + #line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */ 1841 1823 break; 1842 1824 1843 - case 37: 1844 - #line 363 "dtc-parser.y" /* yacc.c:1646 */ 1825 + case 38: 1826 + #line 377 "dtc-parser.y" /* yacc.c:1646 */ 1845 1827 { 1846 1828 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); 1847 1829 } 1848 - #line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ 1830 + #line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ 1849 1831 break; 1850 1832 1851 - case 40: 1852 - #line 372 "dtc-parser.y" /* yacc.c:1646 */ 1833 + case 41: 1834 + #line 386 "dtc-parser.y" /* yacc.c:1646 */ 1853 1835 { 1854 1836 (yyval.integer) = (yyvsp[-1].integer); 1855 1837 } 1856 - #line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */ 1857 - break; 1858 - 1859 - case 43: 1860 - #line 383 "dtc-parser.y" /* yacc.c:1646 */ 1861 - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } 1862 - #line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */ 1863 - break; 1864 - 1865 - case 45: 1866 - #line 388 "dtc-parser.y" /* yacc.c:1646 */ 1867 - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } 1868 - #line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */ 1869 - break; 1870 - 1871 - case 47: 1872 - #line 393 "dtc-parser.y" /* yacc.c:1646 */ 1873 - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } 1874 1838 #line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */ 1875 1839 break; 1876 1840 1877 - case 49: 1878 - #line 398 "dtc-parser.y" /* yacc.c:1646 */ 1879 - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } 1841 + case 44: 1842 + #line 397 "dtc-parser.y" /* yacc.c:1646 */ 1843 + { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } 1880 1844 #line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */ 1881 1845 break; 1882 1846 1883 - case 51: 1884 - #line 403 "dtc-parser.y" /* yacc.c:1646 */ 1885 - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } 1847 + case 46: 1848 + #line 402 "dtc-parser.y" /* yacc.c:1646 */ 1849 + { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } 1886 1850 #line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */ 1887 1851 break; 1888 1852 1889 - case 53: 1890 - #line 408 "dtc-parser.y" /* yacc.c:1646 */ 1891 - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } 1853 + case 48: 1854 + #line 407 "dtc-parser.y" /* yacc.c:1646 */ 1855 + { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } 1892 1856 #line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */ 1893 1857 break; 1894 1858 1895 - case 55: 1896 - #line 413 "dtc-parser.y" /* yacc.c:1646 */ 1897 - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } 1859 + case 50: 1860 + #line 412 "dtc-parser.y" /* yacc.c:1646 */ 1861 + { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } 1898 1862 #line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */ 1899 1863 break; 1900 1864 1901 - case 56: 1902 - #line 414 "dtc-parser.y" /* yacc.c:1646 */ 1903 - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } 1865 + case 52: 1866 + #line 417 "dtc-parser.y" /* yacc.c:1646 */ 1867 + { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } 1904 1868 #line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */ 1905 1869 break; 1906 1870 1907 - case 58: 1908 - #line 419 "dtc-parser.y" /* yacc.c:1646 */ 1909 - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } 1871 + case 54: 1872 + #line 422 "dtc-parser.y" /* yacc.c:1646 */ 1873 + { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } 1910 1874 #line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */ 1911 1875 break; 1912 1876 1913 - case 59: 1914 - #line 420 "dtc-parser.y" /* yacc.c:1646 */ 1915 - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } 1877 + case 56: 1878 + #line 427 "dtc-parser.y" /* yacc.c:1646 */ 1879 + { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } 1916 1880 #line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */ 1917 1881 break; 1918 1882 1919 - case 60: 1920 - #line 421 "dtc-parser.y" /* yacc.c:1646 */ 1921 - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } 1883 + case 57: 1884 + #line 428 "dtc-parser.y" /* yacc.c:1646 */ 1885 + { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } 1922 1886 #line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */ 1923 1887 break; 1924 1888 1925 - case 61: 1926 - #line 422 "dtc-parser.y" /* yacc.c:1646 */ 1927 - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } 1889 + case 59: 1890 + #line 433 "dtc-parser.y" /* yacc.c:1646 */ 1891 + { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } 1928 1892 #line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */ 1929 1893 break; 1930 1894 1931 - case 62: 1932 - #line 426 "dtc-parser.y" /* yacc.c:1646 */ 1933 - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } 1895 + case 60: 1896 + #line 434 "dtc-parser.y" /* yacc.c:1646 */ 1897 + { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } 1934 1898 #line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */ 1935 1899 break; 1936 1900 1937 - case 63: 1938 - #line 427 "dtc-parser.y" /* yacc.c:1646 */ 1939 - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } 1901 + case 61: 1902 + #line 435 "dtc-parser.y" /* yacc.c:1646 */ 1903 + { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } 1940 1904 #line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */ 1941 1905 break; 1942 1906 1943 - case 65: 1944 - #line 432 "dtc-parser.y" /* yacc.c:1646 */ 1945 - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } 1907 + case 62: 1908 + #line 436 "dtc-parser.y" /* yacc.c:1646 */ 1909 + { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } 1946 1910 #line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ 1947 1911 break; 1948 1912 1949 - case 66: 1950 - #line 433 "dtc-parser.y" /* yacc.c:1646 */ 1951 - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } 1913 + case 63: 1914 + #line 440 "dtc-parser.y" /* yacc.c:1646 */ 1915 + { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } 1952 1916 #line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ 1953 1917 break; 1954 1918 1955 - case 68: 1956 - #line 438 "dtc-parser.y" /* yacc.c:1646 */ 1957 - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } 1919 + case 64: 1920 + #line 441 "dtc-parser.y" /* yacc.c:1646 */ 1921 + { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } 1958 1922 #line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ 1959 1923 break; 1960 1924 1925 + case 66: 1926 + #line 446 "dtc-parser.y" /* yacc.c:1646 */ 1927 + { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } 1928 + #line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ 1929 + break; 1930 + 1931 + case 67: 1932 + #line 447 "dtc-parser.y" /* yacc.c:1646 */ 1933 + { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } 1934 + #line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ 1935 + break; 1936 + 1961 1937 case 69: 1962 - #line 440 "dtc-parser.y" /* yacc.c:1646 */ 1938 + #line 452 "dtc-parser.y" /* yacc.c:1646 */ 1939 + { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } 1940 + #line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */ 1941 + break; 1942 + 1943 + case 70: 1944 + #line 454 "dtc-parser.y" /* yacc.c:1646 */ 1963 1945 { 1964 1946 if ((yyvsp[0].integer) != 0) { 1965 1947 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); ··· 1968 1950 (yyval.integer) = 0; 1969 1951 } 1970 1952 } 1971 - #line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */ 1953 + #line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */ 1972 1954 break; 1973 1955 1974 - case 70: 1975 - #line 449 "dtc-parser.y" /* yacc.c:1646 */ 1956 + case 71: 1957 + #line 463 "dtc-parser.y" /* yacc.c:1646 */ 1976 1958 { 1977 1959 if ((yyvsp[0].integer) != 0) { 1978 1960 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); ··· 1981 1963 (yyval.integer) = 0; 1982 1964 } 1983 1965 } 1984 - #line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ 1985 - break; 1986 - 1987 - case 73: 1988 - #line 462 "dtc-parser.y" /* yacc.c:1646 */ 1989 - { (yyval.integer) = -(yyvsp[0].integer); } 1990 - #line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */ 1991 - break; 1992 - 1993 - case 74: 1994 - #line 463 "dtc-parser.y" /* yacc.c:1646 */ 1995 - { (yyval.integer) = ~(yyvsp[0].integer); } 1996 - #line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ 1997 - break; 1998 - 1999 - case 75: 2000 - #line 464 "dtc-parser.y" /* yacc.c:1646 */ 2001 - { (yyval.integer) = !(yyvsp[0].integer); } 2002 1966 #line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ 2003 1967 break; 2004 1968 1969 + case 74: 1970 + #line 476 "dtc-parser.y" /* yacc.c:1646 */ 1971 + { (yyval.integer) = -(yyvsp[0].integer); } 1972 + #line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ 1973 + break; 1974 + 1975 + case 75: 1976 + #line 477 "dtc-parser.y" /* yacc.c:1646 */ 1977 + { (yyval.integer) = ~(yyvsp[0].integer); } 1978 + #line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */ 1979 + break; 1980 + 2005 1981 case 76: 2006 - #line 469 "dtc-parser.y" /* yacc.c:1646 */ 2007 - { 2008 - (yyval.data) = empty_data; 2009 - } 2010 - #line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ 1982 + #line 478 "dtc-parser.y" /* yacc.c:1646 */ 1983 + { (yyval.integer) = !(yyvsp[0].integer); } 1984 + #line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */ 2011 1985 break; 2012 1986 2013 1987 case 77: 2014 - #line 473 "dtc-parser.y" /* yacc.c:1646 */ 1988 + #line 483 "dtc-parser.y" /* yacc.c:1646 */ 2015 1989 { 2016 - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); 1990 + (yyval.data) = empty_data; 2017 1991 } 2018 - #line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */ 1992 + #line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */ 2019 1993 break; 2020 1994 2021 1995 case 78: 2022 - #line 477 "dtc-parser.y" /* yacc.c:1646 */ 1996 + #line 487 "dtc-parser.y" /* yacc.c:1646 */ 2023 1997 { 2024 - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1998 + (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); 2025 1999 } 2026 - #line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */ 2000 + #line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ 2027 2001 break; 2028 2002 2029 2003 case 79: 2030 - #line 484 "dtc-parser.y" /* yacc.c:1646 */ 2004 + #line 491 "dtc-parser.y" /* yacc.c:1646 */ 2031 2005 { 2032 - (yyval.nodelist) = NULL; 2006 + (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 2033 2007 } 2034 - #line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ 2008 + #line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ 2035 2009 break; 2036 2010 2037 2011 case 80: 2038 - #line 488 "dtc-parser.y" /* yacc.c:1646 */ 2012 + #line 498 "dtc-parser.y" /* yacc.c:1646 */ 2039 2013 { 2040 - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); 2014 + (yyval.nodelist) = NULL; 2041 2015 } 2042 - #line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */ 2016 + #line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */ 2043 2017 break; 2044 2018 2045 2019 case 81: 2046 - #line 492 "dtc-parser.y" /* yacc.c:1646 */ 2020 + #line 502 "dtc-parser.y" /* yacc.c:1646 */ 2021 + { 2022 + (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); 2023 + } 2024 + #line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */ 2025 + break; 2026 + 2027 + case 82: 2028 + #line 506 "dtc-parser.y" /* yacc.c:1646 */ 2047 2029 { 2048 2030 ERROR(&(yylsp[0]), "Properties must precede subnodes"); 2049 2031 YYERROR; 2050 2032 } 2051 - #line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */ 2052 - break; 2053 - 2054 - case 82: 2055 - #line 500 "dtc-parser.y" /* yacc.c:1646 */ 2056 - { 2057 - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); 2058 - } 2059 - #line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */ 2033 + #line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */ 2060 2034 break; 2061 2035 2062 2036 case 83: 2063 - #line 504 "dtc-parser.y" /* yacc.c:1646 */ 2037 + #line 514 "dtc-parser.y" /* yacc.c:1646 */ 2064 2038 { 2065 - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); 2039 + (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); 2066 2040 } 2067 - #line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */ 2041 + #line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */ 2068 2042 break; 2069 2043 2070 2044 case 84: 2071 - #line 508 "dtc-parser.y" /* yacc.c:1646 */ 2045 + #line 518 "dtc-parser.y" /* yacc.c:1646 */ 2046 + { 2047 + (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); 2048 + } 2049 + #line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */ 2050 + break; 2051 + 2052 + case 85: 2053 + #line 522 "dtc-parser.y" /* yacc.c:1646 */ 2072 2054 { 2073 2055 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); 2074 2056 (yyval.node) = (yyvsp[0].node); 2075 2057 } 2076 - #line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */ 2058 + #line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */ 2077 2059 break; 2078 2060 2079 2061 2080 - #line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ 2062 + #line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */ 2081 2063 default: break; 2082 2064 } 2083 2065 /* User semantic actions sometimes alter yychar, and that requires ··· 2312 2294 #endif 2313 2295 return yyresult; 2314 2296 } 2315 - #line 514 "dtc-parser.y" /* yacc.c:1906 */ 2297 + #line 528 "dtc-parser.y" /* yacc.c:1906 */ 2316 2298 2317 2299 2318 2300 void yyerror(char const *s)
+17 -3
scripts/dtc/dtc-parser.y
··· 182 182 { 183 183 struct node *target = get_node_by_ref($1, $2); 184 184 185 - if (target) 185 + if (target) { 186 186 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 + } 189 198 $$ = $1; 190 199 } 191 200 | devicetree DT_DEL_NODE DT_REF ';' ··· 208 199 209 200 210 201 $$ = $1; 202 + } 203 + | /* empty */ 204 + { 205 + /* build empty node */ 206 + $$ = name_node(build_node(NULL, NULL), ""); 211 207 } 212 208 ; 213 209
+1 -1
scripts/dtc/dtc.c
··· 31 31 int minsize; /* Minimum blob size */ 32 32 int padsize; /* Additional padding to blob */ 33 33 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 */ 35 35 int generate_symbols; /* enable symbols & fixup support */ 36 36 int generate_fixups; /* suppress generation of fixups on symbol support */ 37 37 int auto_label_aliases; /* auto generate labels -> aliases */
+3
scripts/dtc/dtc.h
··· 31 31 #include <ctype.h> 32 32 #include <errno.h> 33 33 #include <unistd.h> 34 + #include <inttypes.h> 34 35 35 36 #include <libfdt_env.h> 36 37 #include <fdt.h> ··· 203 202 struct node *name_node(struct node *node, char *name); 204 203 struct node *chain_node(struct node *first, struct node *list); 205 204 struct node *merge_nodes(struct node *old_node, struct node *new_node); 205 + void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); 206 206 207 207 void add_property(struct node *node, struct property *prop); 208 208 void delete_property_by_name(struct node *node, char *name); ··· 217 215 const char *get_unitname(struct node *node); 218 216 struct property *get_property(struct node *node, const char *propname); 219 217 cell_t propval_cell(struct property *prop); 218 + cell_t propval_cell_n(struct property *prop, int n); 220 219 struct property *get_property_by_label(struct node *tree, const char *label, 221 220 struct node **node); 222 221 struct marker *get_marker_label(struct node *tree, const char *label,
+96
scripts/dtc/libfdt/fdt_addresses.c
··· 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 + }
-1
scripts/dtc/libfdt/fdt_empty_tree.c
··· 81 81 82 82 return fdt_open_into(buf, buf, bufsize); 83 83 } 84 -
+861
scripts/dtc/libfdt/fdt_overlay.c
··· 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 + }
+2 -2
scripts/dtc/libfdt/fdt_ro.c
··· 60 60 { 61 61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); 62 62 63 - if (! p) 63 + if (!p) 64 64 /* short match */ 65 65 return 0; 66 66 ··· 327 327 const struct fdt_property *prop; 328 328 329 329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); 330 - if (! prop) 330 + if (!prop) 331 331 return NULL; 332 332 333 333 return prop->data;
+19 -5
scripts/dtc/libfdt/fdt_rw.c
··· 207 207 int err; 208 208 209 209 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); 210 - if (! (*prop)) 210 + if (!*prop) 211 211 return oldlen; 212 212 213 213 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), ··· 269 269 return 0; 270 270 } 271 271 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) 274 274 { 275 275 struct fdt_property *prop; 276 276 int err; ··· 283 283 if (err) 284 284 return err; 285 285 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 + 286 300 if (len) 287 - memcpy(prop->data, val, len); 301 + memcpy(prop_data, val, len); 288 302 return 0; 289 303 } 290 304 ··· 337 323 FDT_RW_CHECK_HEADER(fdt); 338 324 339 325 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 340 - if (! prop) 326 + if (!prop) 341 327 return len; 342 328 343 329 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+14 -2
scripts/dtc/libfdt/fdt_sw.c
··· 220 220 return offset; 221 221 } 222 222 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) 224 224 { 225 225 struct fdt_property *prop; 226 226 int nameoff; ··· 238 238 prop->tag = cpu_to_fdt32(FDT_PROP); 239 239 prop->nameoff = cpu_to_fdt32(nameoff); 240 240 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); 242 254 return 0; 243 255 } 244 256
+2 -2
scripts/dtc/libfdt/fdt_wip.c
··· 82 82 int proplen; 83 83 84 84 propval = fdt_getprop(fdt, nodeoffset, name, &proplen); 85 - if (! propval) 85 + if (!propval) 86 86 return proplen; 87 87 88 88 if (proplen != len) ··· 107 107 int len; 108 108 109 109 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 110 - if (! prop) 110 + if (!prop) 111 111 return len; 112 112 113 113 _fdt_nop_region(prop, len + sizeof(*prop));
+47
scripts/dtc/libfdt/libfdt.h
··· 1314 1314 { 1315 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 + */ 1331 + int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); 1332 + 1317 1333 #define fdt_property_string(fdt, name, str) \ 1318 1334 fdt_property(fdt, name, str, strlen(str)+1) 1319 1335 int fdt_end_node(void *fdt); ··· 1447 1431 */ 1448 1432 int fdt_setprop(void *fdt, int nodeoffset, const char *name, 1449 1433 const void *val, int len); 1434 + 1435 + /** 1436 + * fdt_setprop _placeholder - allocate space for a property 1437 + * @fdt: pointer to the device tree blob 1438 + * @nodeoffset: offset of the node whose property to change 1439 + * @name: name of the property to change 1440 + * @len: length of the property value 1441 + * @prop_data: return pointer to property data 1442 + * 1443 + * fdt_setprop_placeholer() allocates the named property in the given node. 1444 + * If the property exists it is resized. In either case a pointer to the 1445 + * property data is returned. 1446 + * 1447 + * This function may insert or delete data from the blob, and will 1448 + * therefore change the offsets of some existing nodes. 1449 + * 1450 + * returns: 1451 + * 0, on success 1452 + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1453 + * contain the new property value 1454 + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1455 + * -FDT_ERR_BADLAYOUT, 1456 + * -FDT_ERR_BADMAGIC, 1457 + * -FDT_ERR_BADVERSION, 1458 + * -FDT_ERR_BADSTATE, 1459 + * -FDT_ERR_BADSTRUCTURE, 1460 + * -FDT_ERR_BADLAYOUT, 1461 + * -FDT_ERR_TRUNCATED, standard meanings 1462 + */ 1463 + int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, 1464 + int len, void **prop_data); 1450 1465 1451 1466 /** 1452 1467 * fdt_setprop_u32 - set a property to a 32-bit integer
+30 -1
scripts/dtc/livetree.c
··· 216 216 return old_node; 217 217 } 218 218 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 + 219 241 struct node *chain_node(struct node *first, struct node *list) 220 242 { 221 243 assert(first->next_sibling == NULL); ··· 418 396 return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); 419 397 } 420 398 399 + cell_t propval_cell_n(struct property *prop, int n) 400 + { 401 + assert(prop->val.len / sizeof(cell_t) >= n); 402 + return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); 403 + } 404 + 421 405 struct property *get_property_by_label(struct node *tree, const char *label, 422 406 struct node **node) 423 407 { ··· 506 478 p = strchr(path, '/'); 507 479 508 480 for_each_child(tree, child) { 509 - if (p && strneq(path, child->name, p-path)) 481 + if (p && (strlen(child->name) == p-path) && 482 + strneq(path, child->name, p-path)) 510 483 return get_node_by_path(child, p+1); 511 484 else if (!p && streq(path, child->name)) 512 485 return child;
+1 -1
scripts/dtc/version_gen.h
··· 1 - #define DTC_VERSION "DTC 1.4.4-g756ffc4f" 1 + #define DTC_VERSION "DTC 1.4.5-gb1a60033"