diff --git a/buildroot-external/patches/barebox/0003-drivers-of-bugfix-local-fixups-resolving.patch b/buildroot-external/patches/barebox/0003-drivers-of-bugfix-local-fixups-resolving.patch index f81832565..f17099243 100644 --- a/buildroot-external/patches/barebox/0003-drivers-of-bugfix-local-fixups-resolving.patch +++ b/buildroot-external/patches/barebox/0003-drivers-of-bugfix-local-fixups-resolving.patch @@ -1,18 +1,18 @@ -From 4232fb9cd5303696ed8487763702fbe84421db57 Mon Sep 17 00:00:00 2001 +From 6c7c35474f066f53b6f63cc0cc5eaefac2bc69dd Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sat, 2 Jun 2018 20:53:51 +0000 Subject: [PATCH 3/3] drivers: of: bugfix local fixups resolving Signed-off-by: Pascal Vizeli --- - drivers/of/resolver.c | 144 +++++++++++++++++------------------------- - 1 file changed, 58 insertions(+), 86 deletions(-) + drivers/of/resolver.c | 147 +++++++++++++++++------------------------- + 1 file changed, 60 insertions(+), 87 deletions(-) diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c -index 62476093c..03c61e959 100644 +index 62476093c..fbab565c5 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c -@@ -66,108 +66,72 @@ static void of_adjust_tree_phandles(struct device_node *node, +@@ -66,108 +66,73 @@ static void of_adjust_tree_phandles(struct device_node *node, * of the tree. Does not take any devtree locks so make sure you * call this on a tree which is at the detached state. */ @@ -27,13 +27,13 @@ index 62476093c..03c61e959 100644 - char *propval, *propcur, *propend, *nodestr, *propstr, *s; - int offset, propcurlen; - int err; -- bool found = false; + struct device_node *child, *overlay_child; + struct property *fixprop, *prop; + int i, count, err; + unsigned int off; + bool found = false; - /* locate the symbols & fixups nodes on resolve */ +- /* locate the symbols & fixups nodes on resolve */ - for_each_child_of_node(node, child) - if (of_node_cmp(child->name, "__local_fixups__") == 0) { - found = true; @@ -42,17 +42,16 @@ index 62476093c..03c61e959 100644 - - /* no local fixups */ - if (!found) -+ if (!local_fixups) - return 0; - +- return 0; +- - /* find the local fixups property */ - for_each_property_of_node(child, rprop) { + for_each_property_of_node(local_fixups, fixprop) { /* skip properties added automatically */ - if (of_prop_cmp(rprop->name, "name") == 0) -+ if (of_prop_cmp(fixprop->name, "name") == 0 || -+ of_prop_cmp(fixprop->name, "phandle") == 0 || -+ of_prop_cmp(fixprop->name, "linux,phandle") == 0) ++ if (!of_prop_cmp(fixprop->name, "name") || ++ !of_prop_cmp(fixprop->name, "phandle") || ++ !of_prop_cmp(fixprop->name, "linux,phandle")) continue; - /* make a copy */ @@ -67,7 +66,10 @@ index 62476093c..03c61e959 100644 - propend = propval + rprop->length; - for (propcur = propval; propcur < propend; - propcur += propcurlen + 1) { -- ++ if ((fixprop->length % 4) != 0 || fixprop->length == 0) ++ return -EINVAL; ++ count = fixprop->length / sizeof(uint32_t); + - propcurlen = strlen(propcur); - - nodestr = propcur; @@ -79,10 +81,7 @@ index 62476093c..03c61e959 100644 - goto err_fail; - } - *s++ = '\0'; -+ if ((fixprop->length % 4) != 0 || fixprop->length == 0) -+ return -EINVAL; -+ count = fixprop->length / sizeof(uint32_t); - +- - propstr = s; - s = strchr(s, ':'); - if (s == NULL) { @@ -90,14 +89,17 @@ index 62476093c..03c61e959 100644 - __func__, (char *)rprop->value); - err = -EINVAL; - goto err_fail; -- } -- ++ for_each_property_of_node(overlay, prop) { ++ if (!of_prop_cmp(fixprop->name, prop->name)) { ++ found = true; ++ break; + } ++ } + - *s++ = '\0'; - offset = simple_strtoul(s, NULL, 10); -+ for_each_property_of_node(overlay, prop) { -+ if (!of_prop_cmp(fixprop->name, prop->name)) -+ break; -+ } ++ if (!found) ++ return -EINVAL; - /* look into the resolve node for the full path */ - refnode = of_find_node_by_path_from(node, nodestr); @@ -106,8 +108,10 @@ index 62476093c..03c61e959 100644 - __func__, (char *)rprop->value); - continue; - } -+ if (!prop) -+ return -EINVAL; ++ for (i=0; i < count; i++) { ++ off = be32_to_cpu(((uint32_t *)fixprop->value)[i]); ++ if ((off + 4) > prop->length) ++ return -EINVAL; - /* now find the property */ - found = false; @@ -116,29 +120,17 @@ index 62476093c..03c61e959 100644 - found = true; - break; - } -+ for (i=0; i < count; i++) { -+ off = be32_to_cpu(((uint32_t *)fixprop->value)[i]); -+ if ((off + 4) > prop->length) -+ return -EINVAL; ++ phandle = be32_to_cpu(*(uint32_t *)(prop->value + off)); ++ phandle += phandle_delta; ++ *(uint32_t *)(prop->value + off) = cpu_to_be32(phandle); ++ } ++ } - if (!found) { - pr_err("%s: Could not find property '%s'\n", - __func__, (char *)rprop->value); - err = -ENOENT; - goto err_fail; -- } -- -- phandle = be32_to_cpu(*(uint32_t *) -- (sprop->value + offset)); -- *(uint32_t *)(sprop->value + offset) = -- cpu_to_be32(phandle + phandle_delta); -+ phandle = be32_to_cpu(*(uint32_t *)(prop->value + off)); -+ phandle += phandle_delta; -+ *(uint32_t *)(prop->value + off) = cpu_to_be32(phandle); - } -+ } - -- kfree(propval); + /* + * These nested loops recurse down two subtrees in parallel, where the + * node names in the two subtrees match. @@ -149,12 +141,20 @@ index 62476093c..03c61e959 100644 + for_each_child_of_node(local_fixups, child) { + + for_each_child_of_node(overlay, overlay_child) -+ if (!of_node_cmp(child->name, overlay_child->name)) ++ if (!of_node_cmp(child->name, overlay_child->name)) { ++ found = true; + break; -+ -+ if (!overlay_child) + } + +- phandle = be32_to_cpu(*(uint32_t *) +- (sprop->value + offset)); +- *(uint32_t *)(sprop->value + offset) = +- cpu_to_be32(phandle + phandle_delta); +- } ++ if (!found) + return -EINVAL; -+ + +- kfree(propval); + err = of_adjust_tree_phandle_references(child, overlay_child, + phandle_delta); + if (err) @@ -169,7 +169,7 @@ index 62476093c..03c61e959 100644 } /** -@@ -185,7 +149,7 @@ err_fail: +@@ -185,7 +150,7 @@ err_fail: */ int of_resolve(struct device_node *resolve) { @@ -178,23 +178,27 @@ index 62476093c..03c61e959 100644 struct device_node *root_sym, *resolve_sym, *resolve_fix; struct property *rprop, *sprop; const char *refpath; -@@ -203,7 +167,15 @@ int of_resolve(struct device_node *resolve) +@@ -203,9 +168,17 @@ int of_resolve(struct device_node *resolve) /* first we need to adjust the phandles */ phandle_delta = of_get_tree_max_phandle(NULL) + 1; of_adjust_tree_phandles(resolve, phandle_delta); - err = of_adjust_tree_phandle_references(resolve, phandle_delta); +- if (err != 0) +- return err; + + /* second we need lookup local fixups of phandles */ + for_each_child_of_node(resolve, local_fixups) { -+ if (!of_node_cmp(local_fixups->name, "__local_fixups__")) ++ if (!of_node_cmp(local_fixups->name, "__local_fixups__")) { ++ err = of_adjust_tree_phandle_references(local_fixups, ++ resolve, phandle_delta); ++ if (err != 0) ++ return err; + break; ++ } + } -+ -+ err = of_adjust_tree_phandle_references(local_fixups, resolve, -+ phandle_delta); - if (err != 0) - return err; + root_sym = NULL; + resolve_sym = NULL; -- 2.17.0