diff options
author | Christian Marangi <ansuelsmth@gmail.com> | 2022-10-21 22:37:06 +0200 |
---|---|---|
committer | Christian Marangi <ansuelsmth@gmail.com> | 2022-10-24 21:10:46 +0200 |
commit | f846945bd2adfcb60e2a4f24cb8fc08c0e495b48 (patch) | |
tree | 65608dde5f289bbe9ec86bbf07117643c67ad539 /target/linux/generic/backport-5.15 | |
parent | b1826346890fae87a2ed2f6242c5f074f3736c0a (diff) | |
download | upstream-f846945bd2adfcb60e2a4f24cb8fc08c0e495b48.tar.gz upstream-f846945bd2adfcb60e2a4f24cb8fc08c0e495b48.tar.bz2 upstream-f846945bd2adfcb60e2a4f24cb8fc08c0e495b48.zip |
generic: 5.15: move dtc drop interrupt check from pending to backport
Move dtc drop interrupto check from pending to backport as it got merged
upstream.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Diffstat (limited to 'target/linux/generic/backport-5.15')
-rw-r--r-- | target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch | 997 |
1 files changed, 997 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch b/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch new file mode 100644 index 0000000000..d1bef74f32 --- /dev/null +++ b/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch @@ -0,0 +1,997 @@ +From a77725a9a3c5924e2fd4cd5b3557dd92a8e46f87 Mon Sep 17 00:00:00 2001 +From: Rob Herring <robh@kernel.org> +Date: Mon, 25 Oct 2021 11:05:45 -0500 +Subject: [PATCH 1/1] scripts/dtc: Update to upstream version + v1.6.1-19-g0a3a9d3449c8 + +This adds the following commits from upstream: + +0a3a9d3449c8 checks: Add an interrupt-map check +8fd24744e361 checks: Ensure '#interrupt-cells' only exists in interrupt providers +d8d1a9a77863 checks: Drop interrupt provider '#address-cells' check +52a16fd72824 checks: Make interrupt_provider check dependent on interrupts_extended_is_cell +37fd700685da treesource: Maintain phandle label/path on output +e33ce1d6a8c7 flattree: Use '\n', not ';' to separate asm pseudo-ops +d24cc189dca6 asm: Use assembler macros instead of cpp macros +ff3a30c115ad asm: Use .asciz and .ascii instead of .string +5eb5927d81ee fdtdump: fix -Werror=int-to-pointer-cast +0869f8269161 libfdt: Add ALIGNMENT error string +69595a167f06 checks: Fix bus-range check +72d09e2682a4 Makefile: add -Wsign-compare to warning options +b587787ef388 checks: Fix signedness comparisons warnings +69bed6c2418f dtc: Wrap phandle validity check +910221185560 fdtget: Fix signedness comparisons warnings +d966f08fcd21 tests: Fix signedness comparisons warnings +ecfb438c07fa dtc: Fix signedness comparisons warnings: pointer diff +5bec74a6d135 dtc: Fix signedness comparisons warnings: reservednum +24e7f511fd4a fdtdump: Fix signedness comparisons warnings +b6910bec1161 Bump version to v1.6.1 +21d61d18f968 Fix CID 1461557 +4c2ef8f4d14c checks: Introduce is_multiple_of() +e59ca36fb70e Make handling of cpp line information more tolerant +0c3fd9b6aceb checks: Drop interrupt_cells_is_cell check +6b3081abc4ac checks: Add check_is_cell() for all phandle+arg properties +2dffc192a77f yamltree: Remove marker ordering dependency +61e513439e40 pylibfdt: Rework "avoid unused variable warning" lines +c8bddd106095 tests: add a positive gpio test case +ad4abfadb687 checks: replace strstr and strrchr with strends +09c6a6e88718 dtc.h: add strends for suffix matching +9bb9b8d0b4a0 checks: tigthen up nr-gpios prop exception +b07b62ee3342 libfdt: Add FDT alignment check to fdt_check_header() +a2def5479950 libfdt: Check that the root-node name is empty +4ca61f84dc21 libfdt: Check that there is only one root node +34d708249a91 dtc: Remove -O dtbo support +8e7ff260f755 libfdt: Fix a possible "unchecked return value" warning +88875268c05c checks: Warn on node-name and property name being the same +9d2279e7e6ee checks: Change node-name check to match devicetree spec +f527c867a8c6 util: limit gnu_printf format attribute to gcc >= 4.4.0 + +Reviewed-by: Frank Rowand <frank.rowand@sony.com> +Tested-by: Frank Rowand <frank.rowand@sony.com> +Signed-off-by: Rob Herring <robh@kernel.org> +--- + scripts/dtc/checks.c | 222 ++++++++++++++++++++++-------- + scripts/dtc/dtc-lexer.l | 2 +- + scripts/dtc/dtc.c | 6 +- + scripts/dtc/dtc.h | 40 +++++- + scripts/dtc/flattree.c | 11 +- + scripts/dtc/libfdt/fdt.c | 4 + + scripts/dtc/libfdt/fdt_rw.c | 18 ++- + scripts/dtc/libfdt/fdt_strerror.c | 1 + + scripts/dtc/libfdt/libfdt.h | 7 + + scripts/dtc/livetree.c | 6 +- + scripts/dtc/treesource.c | 48 +++---- + scripts/dtc/util.h | 6 +- + scripts/dtc/version_gen.h | 2 +- + scripts/dtc/yamltree.c | 16 ++- + 14 files changed, 275 insertions(+), 114 deletions(-) + +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -143,6 +143,14 @@ static void check_nodes_props(struct che + check_nodes_props(c, dti, child); + } + ++static bool is_multiple_of(int multiple, int divisor) ++{ ++ if (divisor == 0) ++ return multiple == 0; ++ else ++ return (multiple % divisor) == 0; ++} ++ + static bool run_check(struct check *c, struct dt_info *dti) + { + struct node *dt = dti->dt; +@@ -297,19 +305,20 @@ ERROR(duplicate_property_names, check_du + #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" + #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + #define DIGITS "0123456789" +-#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" ++#define NODECHARS LOWERCASE UPPERCASE DIGITS ",._+-@" ++#define PROPCHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" + #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" + + static void check_node_name_chars(struct check *c, struct dt_info *dti, + struct node *node) + { +- int n = strspn(node->name, c->data); ++ size_t n = strspn(node->name, c->data); + + if (n < strlen(node->name)) + FAIL(c, dti, node, "Bad character '%c' in node name", + node->name[n]); + } +-ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); ++ERROR(node_name_chars, check_node_name_chars, NODECHARS); + + static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, + struct node *node) +@@ -330,6 +339,20 @@ static void check_node_name_format(struc + } + ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); + ++static void check_node_name_vs_property_name(struct check *c, ++ struct dt_info *dti, ++ struct node *node) ++{ ++ if (!node->parent) ++ return; ++ ++ if (get_property(node->parent, node->name)) { ++ FAIL(c, dti, node, "node name and property name conflict"); ++ } ++} ++WARNING(node_name_vs_property_name, check_node_name_vs_property_name, ++ NULL, &node_name_chars); ++ + static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, + struct node *node) + { +@@ -363,14 +386,14 @@ static void check_property_name_chars(st + struct property *prop; + + for_each_property(node, prop) { +- int n = strspn(prop->name, c->data); ++ size_t n = strspn(prop->name, c->data); + + if (n < strlen(prop->name)) + FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", + prop->name[n]); + } + } +-ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); ++ERROR(property_name_chars, check_property_name_chars, PROPCHARS); + + static void check_property_name_chars_strict(struct check *c, + struct dt_info *dti, +@@ -380,7 +403,7 @@ static void check_property_name_chars_st + + for_each_property(node, prop) { + const char *name = prop->name; +- int n = strspn(name, c->data); ++ size_t n = strspn(name, c->data); + + if (n == strlen(prop->name)) + continue; +@@ -497,7 +520,7 @@ static cell_t check_phandle_prop(struct + + phandle = propval_cell(prop); + +- if ((phandle == 0) || (phandle == -1)) { ++ if (!phandle_is_valid(phandle)) { + FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", + phandle, prop->name); + return 0; +@@ -556,7 +579,7 @@ static void check_name_properties(struct + if (!prop) + return; /* No name property, that's fine */ + +- if ((prop->val.len != node->basenamelen+1) ++ if ((prop->val.len != node->basenamelen + 1U) + || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { + FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" + " of base node name)", prop->val.val); +@@ -657,7 +680,6 @@ ERROR(omit_unused_nodes, fixup_omit_unus + */ + WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); + WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); +-WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); + + WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); + WARNING_IF_NOT_STRING(model_is_string, "model"); +@@ -672,8 +694,7 @@ static void check_names_is_string_list(s + struct property *prop; + + for_each_property(node, prop) { +- const char *s = strrchr(prop->name, '-'); +- if (!s || !streq(s, "-names")) ++ if (!strends(prop->name, "-names")) + continue; + + c->data = prop->name; +@@ -753,7 +774,7 @@ static void check_reg_format(struct chec + size_cells = node_size_cells(node->parent); + entrylen = (addr_cells + size_cells) * sizeof(cell_t); + +- if (!entrylen || (prop->val.len % entrylen) != 0) ++ if (!is_multiple_of(prop->val.len, entrylen)) + FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " + "(#address-cells == %d, #size-cells == %d)", + prop->val.len, addr_cells, size_cells); +@@ -794,7 +815,7 @@ static void check_ranges_format(struct c + "#size-cells (%d) differs from %s (%d)", + ranges, c_size_cells, node->parent->fullpath, + p_size_cells); +- } else if ((prop->val.len % entrylen) != 0) { ++ } else if (!is_multiple_of(prop->val.len, entrylen)) { + FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) " + "(parent #address-cells == %d, child #address-cells == %d, " + "#size-cells == %d)", ranges, prop->val.len, +@@ -871,7 +892,7 @@ static void check_pci_device_bus_num(str + } else { + cells = (cell_t *)prop->val.val; + min_bus = fdt32_to_cpu(cells[0]); +- max_bus = fdt32_to_cpu(cells[0]); ++ max_bus = fdt32_to_cpu(cells[1]); + } + if ((bus_num < min_bus) || (bus_num > max_bus)) + FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", +@@ -1367,9 +1388,9 @@ static void check_property_phandle_args( + const struct provider *provider) + { + struct node *root = dti->dt; +- int cell, cellsize = 0; ++ unsigned int cell, cellsize = 0; + +- if (prop->val.len % sizeof(cell_t)) { ++ if (!is_multiple_of(prop->val.len, sizeof(cell_t))) { + FAIL_PROP(c, dti, node, prop, + "property size (%d) is invalid, expected multiple of %zu", + prop->val.len, sizeof(cell_t)); +@@ -1379,14 +1400,14 @@ static void check_property_phandle_args( + for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { + struct node *provider_node; + struct property *cellprop; +- int phandle; ++ cell_t phandle; + + phandle = propval_cell_n(prop, cell); + /* + * Some bindings use a cell value 0 or -1 to skip over optional + * entries when each index position has a specific definition. + */ +- if (phandle == 0 || phandle == -1) { ++ if (!phandle_is_valid(phandle)) { + /* Give up if this is an overlay with external references */ + if (dti->dtsflags & DTSF_PLUGIN) + break; +@@ -1452,7 +1473,8 @@ static void check_provider_cells_propert + } + #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ + static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ +- WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); ++ WARNING_IF_NOT_CELL(nm##_is_cell, cells_name); \ ++ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &nm##_is_cell, &phandle_references); + + WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); + WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); +@@ -1473,24 +1495,17 @@ WARNING_PROPERTY_PHANDLE_CELLS(thermal_s + + static bool prop_is_gpio(struct property *prop) + { +- char *str; +- + /* + * *-gpios and *-gpio can appear in property names, + * so skip over any false matches (only one known ATM) + */ +- if (strstr(prop->name, "nr-gpio")) ++ if (strends(prop->name, ",nr-gpios")) + return false; + +- str = strrchr(prop->name, '-'); +- if (str) +- str++; +- else +- str = prop->name; +- if (!(streq(str, "gpios") || streq(str, "gpio"))) +- return false; +- +- return true; ++ return strends(prop->name, "-gpios") || ++ streq(prop->name, "gpios") || ++ strends(prop->name, "-gpio") || ++ streq(prop->name, "gpio"); + } + + static void check_gpios_property(struct check *c, +@@ -1525,13 +1540,10 @@ static void check_deprecated_gpio_proper + struct property *prop; + + for_each_property(node, prop) { +- char *str; +- + if (!prop_is_gpio(prop)) + continue; + +- str = strstr(prop->name, "gpio"); +- if (!streq(str, "gpio")) ++ if (!strends(prop->name, "gpio")) + continue; + + FAIL_PROP(c, dti, node, prop, +@@ -1561,21 +1573,106 @@ static void check_interrupt_provider(str + struct node *node) + { + struct property *prop; ++ bool irq_provider = node_is_interrupt_provider(node); + +- if (!node_is_interrupt_provider(node)) ++ prop = get_property(node, "#interrupt-cells"); ++ if (irq_provider && !prop) { ++ FAIL(c, dti, node, ++ "Missing '#interrupt-cells' in interrupt provider"); + return; ++ } + +- prop = get_property(node, "#interrupt-cells"); +- if (!prop) ++ if (!irq_provider && prop) { + FAIL(c, dti, node, +- "Missing #interrupt-cells in interrupt provider"); ++ "'#interrupt-cells' found, but node is not an interrupt provider"); ++ return; ++ } ++} ++WARNING(interrupt_provider, check_interrupt_provider, NULL, &interrupts_extended_is_cell); + +- prop = get_property(node, "#address-cells"); +- if (!prop) ++static void check_interrupt_map(struct check *c, ++ struct dt_info *dti, ++ struct node *node) ++{ ++ struct node *root = dti->dt; ++ struct property *prop, *irq_map_prop; ++ size_t cellsize, cell, map_cells; ++ ++ irq_map_prop = get_property(node, "interrupt-map"); ++ if (!irq_map_prop) ++ return; ++ ++ if (node->addr_cells < 0) { + FAIL(c, dti, node, +- "Missing #address-cells in interrupt provider"); ++ "Missing '#address-cells' in interrupt-map provider"); ++ return; ++ } ++ cellsize = node_addr_cells(node); ++ cellsize += propval_cell(get_property(node, "#interrupt-cells")); ++ ++ prop = get_property(node, "interrupt-map-mask"); ++ if (prop && (prop->val.len != (cellsize * sizeof(cell_t)))) ++ FAIL_PROP(c, dti, node, prop, ++ "property size (%d) is invalid, expected %zu", ++ prop->val.len, cellsize * sizeof(cell_t)); ++ ++ if (!is_multiple_of(irq_map_prop->val.len, sizeof(cell_t))) { ++ FAIL_PROP(c, dti, node, irq_map_prop, ++ "property size (%d) is invalid, expected multiple of %zu", ++ irq_map_prop->val.len, sizeof(cell_t)); ++ return; ++ } ++ ++ map_cells = irq_map_prop->val.len / sizeof(cell_t); ++ for (cell = 0; cell < map_cells; ) { ++ struct node *provider_node; ++ struct property *cellprop; ++ int phandle; ++ size_t parent_cellsize; ++ ++ if ((cell + cellsize) >= map_cells) { ++ FAIL_PROP(c, dti, node, irq_map_prop, ++ "property size (%d) too small, expected > %zu", ++ irq_map_prop->val.len, (cell + cellsize) * sizeof(cell_t)); ++ break; ++ } ++ cell += cellsize; ++ ++ phandle = propval_cell_n(irq_map_prop, cell); ++ if (!phandle_is_valid(phandle)) { ++ /* Give up if this is an overlay with external references */ ++ if (!(dti->dtsflags & DTSF_PLUGIN)) ++ FAIL_PROP(c, dti, node, irq_map_prop, ++ "Cell %zu is not a phandle(%d)", ++ cell, phandle); ++ break; ++ } ++ ++ provider_node = get_node_by_phandle(root, phandle); ++ if (!provider_node) { ++ FAIL_PROP(c, dti, node, irq_map_prop, ++ "Could not get phandle(%d) node for (cell %zu)", ++ phandle, cell); ++ break; ++ } ++ ++ cellprop = get_property(provider_node, "#interrupt-cells"); ++ if (cellprop) { ++ parent_cellsize = propval_cell(cellprop); ++ } else { ++ FAIL(c, dti, node, "Missing property '#interrupt-cells' in node %s or bad phandle (referred from interrupt-map[%zu])", ++ provider_node->fullpath, cell); ++ break; ++ } ++ ++ cellprop = get_property(provider_node, "#address-cells"); ++ if (cellprop) ++ parent_cellsize += propval_cell(cellprop); ++ ++ cell += 1 + parent_cellsize; ++ } + } +-WARNING(interrupt_provider, check_interrupt_provider, NULL); ++WARNING(interrupt_map, check_interrupt_map, NULL, &phandle_references, &addr_size_cells, &interrupt_provider); + + static void check_interrupts_property(struct check *c, + struct dt_info *dti, +@@ -1584,13 +1681,13 @@ static void check_interrupts_property(st + struct node *root = dti->dt; + struct node *irq_node = NULL, *parent = node; + struct property *irq_prop, *prop = NULL; +- int irq_cells, phandle; ++ cell_t irq_cells, phandle; + + irq_prop = get_property(node, "interrupts"); + if (!irq_prop) + return; + +- if (irq_prop->val.len % sizeof(cell_t)) ++ if (!is_multiple_of(irq_prop->val.len, sizeof(cell_t))) + FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", + irq_prop->val.len, sizeof(cell_t)); + +@@ -1603,7 +1700,7 @@ static void check_interrupts_property(st + prop = get_property(parent, "interrupt-parent"); + if (prop) { + phandle = propval_cell(prop); +- if ((phandle == 0) || (phandle == -1)) { ++ if (!phandle_is_valid(phandle)) { + /* Give up if this is an overlay with + * external references */ + if (dti->dtsflags & DTSF_PLUGIN) +@@ -1639,7 +1736,7 @@ static void check_interrupts_property(st + } + + irq_cells = propval_cell(prop); +- if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { ++ if (!is_multiple_of(irq_prop->val.len, irq_cells * sizeof(cell_t))) { + FAIL_PROP(c, dti, node, prop, + "size is (%d), expected multiple of %d", + irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); +@@ -1750,7 +1847,7 @@ WARNING(graph_port, check_graph_port, NU + static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, + struct node *endpoint) + { +- int phandle; ++ cell_t phandle; + struct node *node; + struct property *prop; + +@@ -1760,7 +1857,7 @@ static struct node *get_remote_endpoint( + + phandle = propval_cell(prop); + /* Give up if this is an overlay with external references */ +- if (phandle == 0 || phandle == -1) ++ if (!phandle_is_valid(phandle)) + return NULL; + + node = get_node_by_phandle(dti->dt, phandle); +@@ -1796,7 +1893,7 @@ WARNING(graph_endpoint, check_graph_endp + static struct check *check_table[] = { + &duplicate_node_names, &duplicate_property_names, + &node_name_chars, &node_name_format, &property_name_chars, +- &name_is_string, &name_properties, ++ &name_is_string, &name_properties, &node_name_vs_property_name, + + &duplicate_label, + +@@ -1804,7 +1901,7 @@ static struct check *check_table[] = { + &phandle_references, &path_references, + &omit_unused_nodes, + +- &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, ++ &address_cells_is_cell, &size_cells_is_cell, + &device_type_is_string, &model_is_string, &status_is_string, + &label_is_string, + +@@ -1839,26 +1936,43 @@ static struct check *check_table[] = { + &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, + + &clocks_property, ++ &clocks_is_cell, + &cooling_device_property, ++ &cooling_device_is_cell, + &dmas_property, ++ &dmas_is_cell, + &hwlocks_property, ++ &hwlocks_is_cell, + &interrupts_extended_property, ++ &interrupts_extended_is_cell, + &io_channels_property, ++ &io_channels_is_cell, + &iommus_property, ++ &iommus_is_cell, + &mboxes_property, ++ &mboxes_is_cell, + &msi_parent_property, ++ &msi_parent_is_cell, + &mux_controls_property, ++ &mux_controls_is_cell, + &phys_property, ++ &phys_is_cell, + &power_domains_property, ++ &power_domains_is_cell, + &pwms_property, ++ &pwms_is_cell, + &resets_property, ++ &resets_is_cell, + &sound_dai_property, ++ &sound_dai_is_cell, + &thermal_sensors_property, ++ &thermal_sensors_is_cell, + + &deprecated_gpio_property, + &gpios_property, + &interrupts_property, + &interrupt_provider, ++ &interrupt_map, + + &alias_paths, + +@@ -1882,7 +1996,7 @@ static void enable_warning_error(struct + + static void disable_warning_error(struct check *c, bool warn, bool error) + { +- int i; ++ unsigned int i; + + /* Lowering level, also lower it for things this is the prereq + * for */ +@@ -1903,7 +2017,7 @@ static void disable_warning_error(struct + + void parse_checks_option(bool warn, bool error, const char *arg) + { +- int i; ++ unsigned int i; + const char *name = arg; + bool enable = true; + +@@ -1930,7 +2044,7 @@ void parse_checks_option(bool warn, bool + + void process_checks(bool force, struct dt_info *dti) + { +- int i; ++ unsigned int i; + int error = 0; + + for (i = 0; i < ARRAY_SIZE(check_table); i++) { +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -57,7 +57,7 @@ static void PRINTF(1, 2) lexical_error(c + push_input_file(name); + } + +-<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { ++<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)* { + char *line, *fnstart, *fnend; + struct data fn; + /* skip text before line # */ +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -12,7 +12,7 @@ + * Command line options + */ + int quiet; /* Level of quietness */ +-int reservenum; /* Number of memory reservation slots */ ++unsigned int reservenum;/* Number of memory reservation slots */ + int minsize; /* Minimum blob size */ + int padsize; /* Additional padding to blob */ + int alignsize; /* Additional padding to blob accroding to the alignsize */ +@@ -197,7 +197,7 @@ int main(int argc, char *argv[]) + depname = optarg; + break; + case 'R': +- reservenum = strtol(optarg, NULL, 0); ++ reservenum = strtoul(optarg, NULL, 0); + break; + case 'S': + minsize = strtol(optarg, NULL, 0); +@@ -359,8 +359,6 @@ int main(int argc, char *argv[]) + #endif + } else if (streq(outform, "dtb")) { + dt_to_blob(outf, dti, outversion); +- } else if (streq(outform, "dtbo")) { +- dt_to_blob(outf, dti, outversion); + } else if (streq(outform, "asm")) { + dt_to_asm(outf, dti, outversion); + } else if (streq(outform, "null")) { +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -35,7 +35,7 @@ + * Command line options + */ + extern int quiet; /* Level of quietness */ +-extern int reservenum; /* Number of memory reservation slots */ ++extern unsigned int reservenum; /* Number of memory reservation slots */ + extern int minsize; /* Minimum blob size */ + extern int padsize; /* Additional padding to blob */ + extern int alignsize; /* Additional padding to blob accroding to the alignsize */ +@@ -51,6 +51,11 @@ extern int annotate; /* annotate .dts w + + typedef uint32_t cell_t; + ++static inline bool phandle_is_valid(cell_t phandle) ++{ ++ return phandle != 0 && phandle != ~0U; ++} ++ + static inline uint16_t dtb_ld16(const void *p) + { + const uint8_t *bp = (const uint8_t *)p; +@@ -86,6 +91,16 @@ static inline uint64_t dtb_ld64(const vo + #define streq(a, b) (strcmp((a), (b)) == 0) + #define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) + #define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0)) ++static inline bool strends(const char *str, const char *suffix) ++{ ++ unsigned int len, suffix_len; ++ ++ len = strlen(str); ++ suffix_len = strlen(suffix); ++ if (len < suffix_len) ++ return false; ++ return streq(str + len - suffix_len, suffix); ++} + + #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +@@ -101,6 +116,12 @@ enum markertype { + TYPE_UINT64, + TYPE_STRING, + }; ++ ++static inline bool is_type_marker(enum markertype type) ++{ ++ return type >= TYPE_UINT8; ++} ++ + extern const char *markername(enum markertype markertype); + + struct marker { +@@ -125,7 +146,22 @@ struct data { + for_each_marker(m) \ + if ((m)->type == (t)) + +-size_t type_marker_length(struct marker *m); ++static inline struct marker *next_type_marker(struct marker *m) ++{ ++ for_each_marker(m) ++ if (is_type_marker(m->type)) ++ break; ++ return m; ++} ++ ++static inline size_t type_marker_length(struct marker *m) ++{ ++ struct marker *next = next_type_marker(m->next); ++ ++ if (next) ++ return next->offset - m->offset; ++ return 0; ++} + + void data_free(struct data d); + +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -124,7 +124,8 @@ static void asm_emit_cell(void *e, cell_ + { + FILE *f = e; + +- fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n", ++ fprintf(f, "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n" ++ "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n", + (val >> 24) & 0xff, (val >> 16) & 0xff, + (val >> 8) & 0xff, val & 0xff); + } +@@ -134,9 +135,9 @@ static void asm_emit_string(void *e, con + FILE *f = e; + + if (len != 0) +- fprintf(f, "\t.string\t\"%.*s\"\n", len, str); ++ fprintf(f, "\t.asciz\t\"%.*s\"\n", len, str); + else +- fprintf(f, "\t.string\t\"%s\"\n", str); ++ fprintf(f, "\t.asciz\t\"%s\"\n", str); + } + + static void asm_emit_align(void *e, int a) +@@ -295,7 +296,7 @@ static struct data flatten_reserve_list( + { + struct reserve_info *re; + struct data d = empty_data; +- int j; ++ unsigned int j; + + for (re = reservelist; re; re = re->next) { + d = data_append_re(d, re->address, re->size); +@@ -438,7 +439,7 @@ static void dump_stringtable_asm(FILE *f + + while (p < (strbuf.val + strbuf.len)) { + len = strlen(p); +- fprintf(f, "\t.string \"%s\"\n", p); ++ fprintf(f, "\t.asciz \"%s\"\n", p); + p += len+1; + } + } +--- a/scripts/dtc/libfdt/fdt.c ++++ b/scripts/dtc/libfdt/fdt.c +@@ -90,6 +90,10 @@ int fdt_check_header(const void *fdt) + { + size_t hdrsize; + ++ /* The device tree must be at an 8-byte aligned address */ ++ if ((uintptr_t)fdt & 7) ++ return -FDT_ERR_ALIGNMENT; ++ + if (fdt_magic(fdt) != FDT_MAGIC) + return -FDT_ERR_BADMAGIC; + if (!can_assume(LATEST)) { +--- a/scripts/dtc/libfdt/fdt_rw.c ++++ b/scripts/dtc/libfdt/fdt_rw.c +@@ -349,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, i + return offset; + + /* Try to place the new node after the parent's properties */ +- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ ++ tag = fdt_next_tag(fdt, parentoffset, &nextoffset); ++ /* the fdt_subnode_offset_namelen() should ensure this never hits */ ++ if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE)) ++ return -FDT_ERR_INTERNAL; + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); +@@ -391,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffs + } + + static void fdt_packblocks_(const char *old, char *new, +- int mem_rsv_size, int struct_size) ++ int mem_rsv_size, ++ int struct_size, ++ int strings_size) + { + int mem_rsv_off, struct_off, strings_off; + +@@ -406,8 +411,7 @@ static void fdt_packblocks_(const char * + fdt_set_off_dt_struct(new, struct_off); + fdt_set_size_dt_struct(new, struct_size); + +- memmove(new + strings_off, old + fdt_off_dt_strings(old), +- fdt_size_dt_strings(old)); ++ memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size); + fdt_set_off_dt_strings(new, strings_off); + fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); + } +@@ -467,7 +471,8 @@ int fdt_open_into(const void *fdt, void + return -FDT_ERR_NOSPACE; + } + +- fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); ++ fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size, ++ fdt_size_dt_strings(fdt)); + memmove(buf, tmp, newsize); + + fdt_set_magic(buf, FDT_MAGIC); +@@ -487,7 +492,8 @@ int fdt_pack(void *fdt) + + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) + * sizeof(struct fdt_reserve_entry); +- fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); ++ fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt), ++ fdt_size_dt_strings(fdt)); + fdt_set_totalsize(fdt, fdt_data_size_(fdt)); + + return 0; +--- a/scripts/dtc/libfdt/fdt_strerror.c ++++ b/scripts/dtc/libfdt/fdt_strerror.c +@@ -39,6 +39,7 @@ static struct fdt_errtabent fdt_errtable + FDT_ERRTABENT(FDT_ERR_BADOVERLAY), + FDT_ERRTABENT(FDT_ERR_NOPHANDLES), + FDT_ERRTABENT(FDT_ERR_BADFLAGS), ++ FDT_ERRTABENT(FDT_ERR_ALIGNMENT), + }; + #define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) + +--- a/scripts/dtc/libfdt/libfdt.h ++++ b/scripts/dtc/libfdt/libfdt.h +@@ -131,6 +131,13 @@ uint32_t fdt_next_tag(const void *fdt, i + * to work even with unaligned pointers on platforms (such as ARMv5) that don't + * like unaligned loads and stores. + */ ++static inline uint16_t fdt16_ld(const fdt16_t *p) ++{ ++ const uint8_t *bp = (const uint8_t *)p; ++ ++ return ((uint16_t)bp[0] << 8) | bp[1]; ++} ++ + static inline uint32_t fdt32_ld(const fdt32_t *p) + { + const uint8_t *bp = (const uint8_t *)p; +--- a/scripts/dtc/livetree.c ++++ b/scripts/dtc/livetree.c +@@ -526,7 +526,7 @@ struct node *get_node_by_path(struct nod + p = strchr(path, '/'); + + for_each_child(tree, child) { +- if (p && strprefixeq(path, p - path, child->name)) ++ if (p && strprefixeq(path, (size_t)(p - path), child->name)) + return get_node_by_path(child, p+1); + else if (!p && streq(path, child->name)) + return child; +@@ -559,7 +559,7 @@ struct node *get_node_by_phandle(struct + { + struct node *child, *node; + +- if ((phandle == 0) || (phandle == -1)) { ++ if (!phandle_is_valid(phandle)) { + assert(generate_fixups); + return NULL; + } +@@ -594,7 +594,7 @@ cell_t get_node_phandle(struct node *roo + static cell_t phandle = 1; /* FIXME: ick, static local */ + struct data d = empty_data; + +- if ((node->phandle != 0) && (node->phandle != -1)) ++ if (phandle_is_valid(node->phandle)) + return node->phandle; + + while (get_node_by_phandle(root, phandle)) +--- a/scripts/dtc/treesource.c ++++ b/scripts/dtc/treesource.c +@@ -124,27 +124,6 @@ static void write_propval_int(FILE *f, c + } + } + +-static bool has_data_type_information(struct marker *m) +-{ +- return m->type >= TYPE_UINT8; +-} +- +-static struct marker *next_type_marker(struct marker *m) +-{ +- while (m && !has_data_type_information(m)) +- m = m->next; +- return m; +-} +- +-size_t type_marker_length(struct marker *m) +-{ +- struct marker *next = next_type_marker(m->next); +- +- if (next) +- return next->offset - m->offset; +- return 0; +-} +- + static const char *delim_start[] = { + [TYPE_UINT8] = "[", + [TYPE_UINT16] = "/bits/ 16 <", +@@ -229,26 +208,39 @@ static void write_propval(FILE *f, struc + size_t chunk_len = (m->next ? m->next->offset : len) - m->offset; + size_t data_len = type_marker_length(m) ? : len - m->offset; + const char *p = &prop->val.val[m->offset]; ++ struct marker *m_phandle; + +- if (has_data_type_information(m)) { ++ if (is_type_marker(m->type)) { + emit_type = m->type; + fprintf(f, " %s", delim_start[emit_type]); + } else if (m->type == LABEL) + fprintf(f, " %s:", m->ref); +- else if (m->offset) +- fputc(' ', f); + +- if (emit_type == TYPE_NONE) { +- assert(chunk_len == 0); ++ if (emit_type == TYPE_NONE || chunk_len == 0) + continue; +- } + + switch(emit_type) { + case TYPE_UINT16: + write_propval_int(f, p, chunk_len, 2); + break; + case TYPE_UINT32: +- write_propval_int(f, p, chunk_len, 4); ++ m_phandle = prop->val.markers; ++ for_each_marker_of_type(m_phandle, REF_PHANDLE) ++ if (m->offset == m_phandle->offset) ++ break; ++ ++ if (m_phandle) { ++ if (m_phandle->ref[0] == '/') ++ fprintf(f, "&{%s}", m_phandle->ref); ++ else ++ fprintf(f, "&%s", m_phandle->ref); ++ if (chunk_len > 4) { ++ fputc(' ', f); ++ write_propval_int(f, p + 4, chunk_len - 4, 4); ++ } ++ } else { ++ write_propval_int(f, p, chunk_len, 4); ++ } + break; + case TYPE_UINT64: + write_propval_int(f, p, chunk_len, 8); +--- a/scripts/dtc/util.h ++++ b/scripts/dtc/util.h +@@ -13,10 +13,10 @@ + */ + + #ifdef __GNUC__ +-#ifdef __clang__ +-#define PRINTF(i, j) __attribute__((format (printf, i, j))) +-#else ++#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) + #define PRINTF(i, j) __attribute__((format (gnu_printf, i, j))) ++#else ++#define PRINTF(i, j) __attribute__((format (printf, i, j))) + #endif + #define NORETURN __attribute__((noreturn)) + #else +--- a/scripts/dtc/version_gen.h ++++ b/scripts/dtc/version_gen.h +@@ -1 +1 @@ +-#define DTC_VERSION "DTC 1.6.0-g183df9e9" ++#define DTC_VERSION "DTC 1.6.1-g0a3a9d34" +--- a/scripts/dtc/yamltree.c ++++ b/scripts/dtc/yamltree.c +@@ -29,11 +29,12 @@ char *yaml_error_name[] = { + (emitter)->problem, __func__, __LINE__); \ + }) + +-static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, unsigned int len, int width) ++static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, ++ char *data, unsigned int seq_offset, unsigned int len, int width) + { + yaml_event_t event; + void *tag; +- unsigned int off, start_offset = markers->offset; ++ unsigned int off; + + switch(width) { + case 1: tag = "!u8"; break; +@@ -66,7 +67,7 @@ static void yaml_propval_int(yaml_emitte + m = markers; + is_phandle = false; + for_each_marker_of_type(m, REF_PHANDLE) { +- if (m->offset == (start_offset + off)) { ++ if (m->offset == (seq_offset + off)) { + is_phandle = true; + break; + } +@@ -114,6 +115,7 @@ static void yaml_propval(yaml_emitter_t + yaml_event_t event; + unsigned int len = prop->val.len; + struct marker *m = prop->val.markers; ++ struct marker *markers = prop->val.markers; + + /* Emit the property name */ + yaml_scalar_event_initialize(&event, NULL, +@@ -151,19 +153,19 @@ static void yaml_propval(yaml_emitter_t + + switch(m->type) { + case TYPE_UINT16: +- yaml_propval_int(emitter, m, data, chunk_len, 2); ++ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 2); + break; + case TYPE_UINT32: +- yaml_propval_int(emitter, m, data, chunk_len, 4); ++ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 4); + break; + case TYPE_UINT64: +- yaml_propval_int(emitter, m, data, chunk_len, 8); ++ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 8); + break; + case TYPE_STRING: + yaml_propval_string(emitter, data, chunk_len); + break; + default: +- yaml_propval_int(emitter, m, data, chunk_len, 1); ++ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 1); + break; + } + } |