generic: 5.15: move dtc drop interrupt check from pending to backport
authorChristian Marangi <ansuelsmth@gmail.com>
Fri, 21 Oct 2022 20:37:06 +0000 (22:37 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Mon, 24 Oct 2022 19:10:46 +0000 (21:10 +0200)
Move dtc drop interrupto check from pending to backport as it got merged
upstream.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/050-dtc-checks-Drop-interrupt-provider-address-cells-check.patch [deleted file]

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 (file)
index 0000000..d1bef74
--- /dev/null
@@ -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;
+               }
+       }
diff --git a/target/linux/generic/pending-5.15/050-dtc-checks-Drop-interrupt-provider-address-cells-check.patch b/target/linux/generic/pending-5.15/050-dtc-checks-Drop-interrupt-provider-address-cells-check.patch
deleted file mode 100644 (file)
index 75f6372..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From d8d1a9a77863a8c7031ae82a1d461aa78eb72a7b Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Mon, 11 Oct 2021 14:12:43 -0500
-Subject: [PATCH] checks: Drop interrupt provider '#address-cells' check
-
-'#address-cells' is only needed when parsing 'interrupt-map' properties, so
-remove it from the common interrupt-provider test.
-
-Cc: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
-Signed-off-by: Rob Herring <robh@kernel.org>
-Message-Id: <20211011191245.1009682-3-robh@kernel.org>
-Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
----
---- a/scripts/dtc/checks.c
-+++ b/scripts/dtc/checks.c
-@@ -1569,11 +1569,6 @@ static void check_interrupt_provider(str
-       if (!prop)
-               FAIL(c, dti, node,
-                    "Missing #interrupt-cells in interrupt provider");
--
--      prop = get_property(node, "#address-cells");
--      if (!prop)
--              FAIL(c, dti, node,
--                   "Missing #address-cells in interrupt provider");
- }
- WARNING(interrupt_provider, check_interrupt_provider, NULL);