From b6cc9474e2dd9f0c19b694b40961d81117f1e918 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 28 Oct 2016 14:15:02 -0700 Subject: of, numa: Return NUMA_NO_NODE from disable of_node_to_nid() if nid not possible. On arm64 NUMA kernels we can pass "numa=off" on the command line to disable NUMA. A side effect of this is that kmalloc_node() calls to non-zero nodes will crash the system with an OOPS: [ 0.000000] ITS@0x0000901000020000: allocated 2097152 Devices @10002000000 (flat, esz 8, psz 64K, shr 1) [ 0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00001680 [ 0.000000] pgd = fffffc0009470000 [ 0.000000] [00001680] *pgd=0000010ffff90003, *pud=0000010ffff90003, *pmd=0000010ffff90003, *pte=0000000000000000 [ 0.000000] Internal error: Oops: 96000006 [#1] SMP . . . [ 0.000000] [] __alloc_pages_nodemask+0xa4/0xe68 [ 0.000000] [] new_slab+0xd0/0x564 [ 0.000000] [] ___slab_alloc+0x2e4/0x514 [ 0.000000] [] __slab_alloc+0x48/0x58 [ 0.000000] [] __kmalloc_node+0xd0/0x2dc [ 0.000000] [] __irq_domain_add+0x7c/0x164 [ 0.000000] [] its_probe+0x784/0x81c [ 0.000000] [] its_init+0x48/0x1b0 [ 0.000000] [] gic_init_bases+0x228/0x360 [ 0.000000] [] gic_of_init+0x148/0x1cc [ 0.000000] [] of_irq_init+0x184/0x298 [ 0.000000] [] irqchip_init+0x14/0x38 [ 0.000000] [] init_IRQ+0xc/0x30 [ 0.000000] [] start_kernel+0x240/0x3b8 [ 0.000000] [] __primary_switched+0x30/0x6c [ 0.000000] Code: 912ec2a0 b9403809 0a0902fb 37b007db (f9400300) . . . This is caused by code like this in kernel/irq/irqdomain.c domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size), GFP_KERNEL, of_node_to_nid(of_node)); When NUMA is disabled, the concept of a node is really undefined, so of_node_to_nid() should unconditionally return NUMA_NO_NODE. Fix by returning NUMA_NO_NODE when the nid is not in the set of possible nodes. Reported-by: Gilbert Netzer Signed-off-by: David Daney Cc: stable@vger.kernel.org # 4.7+ Signed-off-by: Rob Herring --- drivers/of/of_numa.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index f63d4b0deff0..a53982a330ea 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -176,7 +176,12 @@ int of_node_to_nid(struct device_node *device) np->name); of_node_put(np); - if (!r) + /* + * If numa=off passed on command line, or with a defective + * device tree, the nid may not be in the set of possible + * nodes. Check for this case and return NUMA_NO_NODE. + */ + if (!r && nid < MAX_NUMNODES && node_possible(nid)) return nid; return NUMA_NO_NODE; -- cgit v1.2.3 From a67976ecc81bfcaef74151ee7fb3117ca2189eff Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:21 -0700 Subject: of: Remove comments that state the obvious, to reduce clutter Remove comments that report what is obvious from the code. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 46325d6394cf..4ff0220d7aa2 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -36,7 +36,6 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node, if (node == NULL) return NULL; - /* check */ if (of_node_cmp(node->full_name, full_name) == 0) return of_node_get(node); @@ -60,7 +59,6 @@ static phandle of_get_tree_max_phandle(void) phandle phandle; unsigned long flags; - /* now search recursively */ raw_spin_lock_irqsave(&devtree_lock, flags); phandle = 0; for_each_of_allnodes(node) { @@ -75,8 +73,6 @@ static phandle of_get_tree_max_phandle(void) /* * Adjust a subtree's phandle values by a given delta. - * Makes sure not to just adjust the device node's phandle value, - * but modify the phandle properties values as well. */ static void __of_adjust_tree_phandles(struct device_node *node, int phandle_delta) @@ -85,32 +81,25 @@ static void __of_adjust_tree_phandles(struct device_node *node, struct property *prop; phandle phandle; - /* first adjust the node's phandle direct value */ if (node->phandle != 0 && node->phandle != OF_PHANDLE_ILLEGAL) node->phandle += phandle_delta; - /* now adjust phandle & linux,phandle values */ for_each_property_of_node(node, prop) { - /* only look for these two */ if (of_prop_cmp(prop->name, "phandle") != 0 && of_prop_cmp(prop->name, "linux,phandle") != 0) continue; - /* must be big enough */ if (prop->length < 4) continue; - /* read phandle value */ phandle = be32_to_cpup(prop->value); - if (phandle == OF_PHANDLE_ILLEGAL) /* unresolved */ + if (phandle == OF_PHANDLE_ILLEGAL) continue; - /* adjust */ *(uint32_t *)prop->value = cpu_to_be32(node->phandle); } - /* now do the children recursively */ for_each_child_of_node(node, child) __of_adjust_tree_phandles(child, phandle_delta); } @@ -125,7 +114,6 @@ static int __of_adjust_phandle_ref(struct device_node *node, int offset, propcurlen; int err = 0; - /* make a copy */ propval = kmalloc(rprop->length, GFP_KERNEL); if (!propval) { pr_err("%s: Could not copy value of '%s'\n", @@ -165,7 +153,6 @@ static int __of_adjust_phandle_ref(struct device_node *node, goto err_fail; } - /* look into the resolve node for the full path */ refnode = __of_find_node_by_full_name(node, nodestr); if (!refnode) { pr_warn("%s: Could not find refnode '%s'\n", @@ -173,7 +160,6 @@ static int __of_adjust_phandle_ref(struct device_node *node, continue; } - /* now find the property */ for_each_property_of_node(refnode, sprop) { if (of_prop_cmp(sprop->name, propstr) == 0) break; @@ -240,7 +226,6 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, } count = rprop->length / sizeof(__be32); - /* now find the target property */ for_each_property_of_node(target, sprop) { if (of_prop_cmp(sprop->name, rprop->name) == 0) break; @@ -254,7 +239,6 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, for (i = 0; i < count; i++) { off = be32_to_cpu(((__be32 *)rprop->value)[i]); - /* make sure the offset doesn't overstep (even wrap) */ if (off >= sprop->length || (off + 4) > sprop->length) { pr_err("%s: Illegal property '%s' @%s\n", @@ -264,7 +248,6 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, } if (phandle_delta) { - /* adjust */ phandle = be32_to_cpu(*(__be32 *)(sprop->value + off)); phandle += phandle_delta; *(__be32 *)(sprop->value + off) = cpu_to_be32(phandle); @@ -320,22 +303,18 @@ int of_resolve_phandles(struct device_node *resolve) if (resolve && !of_node_check_flag(resolve, OF_DETACHED)) pr_err("%s: node %s not detached\n", __func__, resolve->full_name); - /* the resolve node must exist, and be detached */ if (!resolve || !of_node_check_flag(resolve, OF_DETACHED)) return -EINVAL; - /* first we need to adjust the phandles */ phandle_delta = of_get_tree_max_phandle() + 1; __of_adjust_tree_phandles(resolve, phandle_delta); - /* locate the local fixups */ childroot = NULL; for_each_child_of_node(resolve, childroot) if (of_node_cmp(childroot->name, "__local_fixups__") == 0) break; if (childroot != NULL) { - /* resolve root is guaranteed to be the '/' */ err = __of_adjust_tree_phandle_references(childroot, resolve, 0); if (err != 0) @@ -349,10 +328,8 @@ int of_resolve_phandles(struct device_node *resolve) resolve_sym = NULL; resolve_fix = NULL; - /* this may fail (if no fixups are required) */ root_sym = of_find_node_by_path("/__symbols__"); - /* locate the symbols & fixups nodes on resolve */ for_each_child_of_node(resolve, child) { if (!resolve_sym && @@ -363,18 +340,15 @@ int of_resolve_phandles(struct device_node *resolve) of_node_cmp(child->name, "__fixups__") == 0) resolve_fix = child; - /* both found, don't bother anymore */ if (resolve_sym && resolve_fix) break; } - /* we do allow for the case where no fixups are needed */ if (!resolve_fix) { - err = 0; /* no error */ + err = 0; goto out; } - /* we need to fixup, but no root symbols... */ if (!root_sym) { pr_err("%s: no symbols in root of device tree.\n", __func__); err = -EINVAL; @@ -415,7 +389,6 @@ int of_resolve_phandles(struct device_node *resolve) } out: - /* NULL is handled by of_node_put as NOP */ of_node_put(root_sym); return err; -- cgit v1.2.3 From 96d1c8e8e38f264fa65c74545fbb913df3af10d3 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:22 -0700 Subject: of: Remove excessive printks to reduce clutter. Remove extra debug and error printks. A single pr_err() will be added at the end of this series to replace many of these error messages. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 53 ++++++++------------------------------------------- 1 file changed, 8 insertions(+), 45 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 4ff0220d7aa2..c61ba99a1792 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -115,11 +115,8 @@ static int __of_adjust_phandle_ref(struct device_node *node, int err = 0; propval = kmalloc(rprop->length, GFP_KERNEL); - if (!propval) { - pr_err("%s: Could not copy value of '%s'\n", - __func__, rprop->name); + if (!propval) return -ENOMEM; - } memcpy(propval, rprop->value, rprop->length); propend = propval + rprop->length; @@ -129,8 +126,6 @@ static int __of_adjust_phandle_ref(struct device_node *node, nodestr = propcur; s = strchr(propcur, ':'); if (!s) { - pr_err("%s: Illegal symbol entry '%s' (1)\n", - __func__, propcur); err = -EINVAL; goto err_fail; } @@ -139,26 +134,18 @@ static int __of_adjust_phandle_ref(struct device_node *node, propstr = s; s = strchr(s, ':'); if (!s) { - pr_err("%s: Illegal symbol entry '%s' (2)\n", - __func__, (char *)rprop->value); err = -EINVAL; goto err_fail; } *s++ = '\0'; err = kstrtoint(s, 10, &offset); - if (err != 0) { - pr_err("%s: Could get offset '%s'\n", - __func__, (char *)rprop->value); + if (err != 0) goto err_fail; - } refnode = __of_find_node_by_full_name(node, nodestr); - if (!refnode) { - pr_warn("%s: Could not find refnode '%s'\n", - __func__, (char *)rprop->value); + if (!refnode) continue; - } for_each_property_of_node(refnode, sprop) { if (of_prop_cmp(sprop->name, propstr) == 0) @@ -167,8 +154,6 @@ static int __of_adjust_phandle_ref(struct device_node *node, of_node_put(refnode); if (!sprop) { - pr_err("%s: Could not find property '%s'\n", - __func__, (char *)rprop->value); err = -ENOENT; goto err_fail; } @@ -219,11 +204,8 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, of_prop_cmp(rprop->name, "linux,phandle") == 0) continue; - if ((rprop->length % 4) != 0 || rprop->length == 0) { - pr_err("%s: Illegal property (size) '%s' @%s\n", - __func__, rprop->name, node->full_name); + if ((rprop->length % 4) != 0 || rprop->length == 0) return -EINVAL; - } count = rprop->length / sizeof(__be32); for_each_property_of_node(target, sprop) { @@ -231,21 +213,13 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, break; } - if (sprop == NULL) { - pr_err("%s: Could not find target property '%s' @%s\n", - __func__, rprop->name, node->full_name); + if (sprop == NULL) return -EINVAL; - } for (i = 0; i < count; i++) { off = be32_to_cpu(((__be32 *)rprop->value)[i]); - if (off >= sprop->length || - (off + 4) > sprop->length) { - pr_err("%s: Illegal property '%s' @%s\n", - __func__, rprop->name, - node->full_name); + if (off >= sprop->length || (off + 4) > sprop->length) return -EINVAL; - } if (phandle_delta) { phandle = be32_to_cpu(*(__be32 *)(sprop->value + off)); @@ -261,11 +235,8 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, if (__of_node_name_cmp(child, childtarget) == 0) break; - if (!childtarget) { - pr_err("%s: Could not find target child '%s' @%s\n", - __func__, child->name, node->full_name); + if (!childtarget) return -EINVAL; - } err = __of_adjust_tree_phandle_references(child, childtarget, phandle_delta); @@ -363,16 +334,11 @@ int of_resolve_phandles(struct device_node *resolve) err = of_property_read_string(root_sym, rprop->name, &refpath); - if (err != 0) { - pr_err("%s: Could not find symbol '%s'\n", - __func__, rprop->name); + if (err != 0) goto out; - } refnode = of_find_node_by_path(refpath); if (!refnode) { - pr_err("%s: Could not find node by path '%s'\n", - __func__, refpath); err = -ENOENT; goto out; } @@ -380,9 +346,6 @@ int of_resolve_phandles(struct device_node *resolve) phandle = refnode->phandle; of_node_put(refnode); - pr_debug("%s: %s phandle is 0x%08x\n", - __func__, rprop->name, phandle); - err = __of_adjust_phandle_ref(resolve, rprop, phandle); if (err) break; -- cgit v1.2.3 From 9f27ede49dc481a35244c03193236ac2fddd10a1 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:23 -0700 Subject: of: Convert comparisons to zero or NULL to logical expressions Convert comparisons to zero or NULL to logical expressions. A small number of such comparisons remain where they provide more clarity of the numeric nature of a variable. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index c61ba99a1792..31fd3800787a 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -33,10 +33,10 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node, { struct device_node *child, *found; - if (node == NULL) + if (!node) return NULL; - if (of_node_cmp(node->full_name, full_name) == 0) + if (!of_node_cmp(node->full_name, full_name)) return of_node_get(node); for_each_child_of_node(node, child) { @@ -86,8 +86,8 @@ static void __of_adjust_tree_phandles(struct device_node *node, for_each_property_of_node(node, prop) { - if (of_prop_cmp(prop->name, "phandle") != 0 && - of_prop_cmp(prop->name, "linux,phandle") != 0) + if (of_prop_cmp(prop->name, "phandle") && + of_prop_cmp(prop->name, "linux,phandle")) continue; if (prop->length < 4) @@ -140,7 +140,7 @@ static int __of_adjust_phandle_ref(struct device_node *node, *s++ = '\0'; err = kstrtoint(s, 10, &offset); - if (err != 0) + if (err) goto err_fail; refnode = __of_find_node_by_full_name(node, nodestr); @@ -148,7 +148,7 @@ static int __of_adjust_phandle_ref(struct device_node *node, continue; for_each_property_of_node(refnode, sprop) { - if (of_prop_cmp(sprop->name, propstr) == 0) + if (!of_prop_cmp(sprop->name, propstr)) break; } of_node_put(refnode); @@ -193,15 +193,15 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, unsigned int off; phandle phandle; - if (node == NULL) + if (!node) return 0; for_each_property_of_node(node, rprop) { /* skip properties added automatically */ - if (of_prop_cmp(rprop->name, "name") == 0 || - of_prop_cmp(rprop->name, "phandle") == 0 || - of_prop_cmp(rprop->name, "linux,phandle") == 0) + if (!of_prop_cmp(rprop->name, "name") || + !of_prop_cmp(rprop->name, "phandle") || + !of_prop_cmp(rprop->name, "linux,phandle")) continue; if ((rprop->length % 4) != 0 || rprop->length == 0) @@ -209,11 +209,11 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, count = rprop->length / sizeof(__be32); for_each_property_of_node(target, sprop) { - if (of_prop_cmp(sprop->name, rprop->name) == 0) + if (!of_prop_cmp(sprop->name, rprop->name)) break; } - if (sprop == NULL) + if (!sprop) return -EINVAL; for (i = 0; i < count; i++) { @@ -232,7 +232,7 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, for_each_child_of_node(node, child) { for_each_child_of_node(target, childtarget) - if (__of_node_name_cmp(child, childtarget) == 0) + if (!__of_node_name_cmp(child, childtarget)) break; if (!childtarget) @@ -240,7 +240,7 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, err = __of_adjust_tree_phandle_references(child, childtarget, phandle_delta); - if (err != 0) + if (err) return err; } @@ -282,13 +282,13 @@ int of_resolve_phandles(struct device_node *resolve) childroot = NULL; for_each_child_of_node(resolve, childroot) - if (of_node_cmp(childroot->name, "__local_fixups__") == 0) + if (!of_node_cmp(childroot->name, "__local_fixups__")) break; if (childroot != NULL) { err = __of_adjust_tree_phandle_references(childroot, resolve, 0); - if (err != 0) + if (err) return err; BUG_ON(__of_adjust_tree_phandle_references(childroot, @@ -303,12 +303,10 @@ int of_resolve_phandles(struct device_node *resolve) for_each_child_of_node(resolve, child) { - if (!resolve_sym && - of_node_cmp(child->name, "__symbols__") == 0) + if (!resolve_sym && !of_node_cmp(child->name, "__symbols__")) resolve_sym = child; - if (!resolve_fix && - of_node_cmp(child->name, "__fixups__") == 0) + if (!resolve_fix && !of_node_cmp(child->name, "__fixups__")) resolve_fix = child; if (resolve_sym && resolve_fix) @@ -329,12 +327,12 @@ int of_resolve_phandles(struct device_node *resolve) for_each_property_of_node(resolve_fix, rprop) { /* skip properties added automatically */ - if (of_prop_cmp(rprop->name, "name") == 0) + if (!of_prop_cmp(rprop->name, "name")) continue; err = of_property_read_string(root_sym, rprop->name, &refpath); - if (err != 0) + if (err) goto out; refnode = of_find_node_by_path(refpath); -- cgit v1.2.3 From f94823f2ebd5436d4377d20b762fd2c1bc3263f6 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:24 -0700 Subject: of: Rename functions to more accurately reflect what they do Some function names are misleading or do not provide a good sense of what they do. Rename the functions to ne more informative. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 31fd3800787a..3d123b612789 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -53,7 +53,7 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node, /* * Find live tree's maximum phandle value. */ -static phandle of_get_tree_max_phandle(void) +static phandle live_tree_max_phandle(void) { struct device_node *node; phandle phandle; @@ -74,7 +74,7 @@ static phandle of_get_tree_max_phandle(void) /* * Adjust a subtree's phandle values by a given delta. */ -static void __of_adjust_tree_phandles(struct device_node *node, +static void adjust_overlay_phandles(struct device_node *node, int phandle_delta) { struct device_node *child; @@ -101,10 +101,10 @@ static void __of_adjust_tree_phandles(struct device_node *node, } for_each_child_of_node(node, child) - __of_adjust_tree_phandles(child, phandle_delta); + adjust_overlay_phandles(child, phandle_delta); } -static int __of_adjust_phandle_ref(struct device_node *node, +static int update_usages_of_a_phandle_reference(struct device_node *node, struct property *rprop, int value) { phandle phandle; @@ -184,7 +184,7 @@ static int __of_node_name_cmp(const struct device_node *dn1, * Does not take any devtree locks so make sure you call this on a tree * which is at the detached state. */ -static int __of_adjust_tree_phandle_references(struct device_node *node, +static int adjust_local_phandle_references(struct device_node *node, struct device_node *target, int phandle_delta) { struct device_node *child, *childtarget; @@ -238,7 +238,7 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, if (!childtarget) return -EINVAL; - err = __of_adjust_tree_phandle_references(child, childtarget, + err = adjust_local_phandle_references(child, childtarget, phandle_delta); if (err) return err; @@ -277,8 +277,8 @@ int of_resolve_phandles(struct device_node *resolve) if (!resolve || !of_node_check_flag(resolve, OF_DETACHED)) return -EINVAL; - phandle_delta = of_get_tree_max_phandle() + 1; - __of_adjust_tree_phandles(resolve, phandle_delta); + phandle_delta = live_tree_max_phandle() + 1; + adjust_overlay_phandles(resolve, phandle_delta); childroot = NULL; for_each_child_of_node(resolve, childroot) @@ -286,12 +286,12 @@ int of_resolve_phandles(struct device_node *resolve) break; if (childroot != NULL) { - err = __of_adjust_tree_phandle_references(childroot, + err = adjust_local_phandle_references(childroot, resolve, 0); if (err) return err; - BUG_ON(__of_adjust_tree_phandle_references(childroot, + BUG_ON(adjust_local_phandle_references(childroot, resolve, phandle_delta)); } @@ -344,7 +344,7 @@ int of_resolve_phandles(struct device_node *resolve) phandle = refnode->phandle; of_node_put(refnode); - err = __of_adjust_phandle_ref(resolve, rprop, phandle); + err = update_usages_of_a_phandle_reference(resolve, rprop, phandle); if (err) break; } -- cgit v1.2.3 From fad556bf3f5a9182aa8ec9d1a988735dabfd6631 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:25 -0700 Subject: of: Remove prefix "__of_" from local function names Remove "__of_" prefix from local function names. The pattern of a leading "__" is used in drivers/of/ to signify a function that must be called with a lock held. These functions do not fit that pattern. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 3d123b612789..0ce38aa0ed3c 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -28,7 +28,7 @@ * Find a node with the give full name by recursively following any of * the child node links. */ -static struct device_node *__of_find_node_by_full_name(struct device_node *node, +static struct device_node *find_node_by_full_name(struct device_node *node, const char *full_name) { struct device_node *child, *found; @@ -40,7 +40,7 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node, return of_node_get(node); for_each_child_of_node(node, child) { - found = __of_find_node_by_full_name(child, full_name); + found = find_node_by_full_name(child, full_name); if (found != NULL) { of_node_put(child); return found; @@ -143,7 +143,7 @@ static int update_usages_of_a_phandle_reference(struct device_node *node, if (err) goto err_fail; - refnode = __of_find_node_by_full_name(node, nodestr); + refnode = find_node_by_full_name(node, nodestr); if (!refnode) continue; @@ -168,7 +168,7 @@ err_fail: } /* compare nodes taking into account that 'name' strips out the @ part */ -static int __of_node_name_cmp(const struct device_node *dn1, +static int node_name_cmp(const struct device_node *dn1, const struct device_node *dn2) { const char *n1 = strrchr(dn1->full_name, '/') ? : "/"; @@ -232,7 +232,7 @@ static int adjust_local_phandle_references(struct device_node *node, for_each_child_of_node(node, child) { for_each_child_of_node(target, childtarget) - if (!__of_node_name_cmp(child, childtarget)) + if (!node_name_cmp(child, childtarget)) break; if (!childtarget) -- cgit v1.2.3 From 25e1687767612e593c054d5855f6717cf8104c1f Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:26 -0700 Subject: of: Rename variables to better reflect purpose or follow convention Rename variables to better reflect what their purpose is. As a side effect, this reduces the need for some of the comments previously removed in this series. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 172 +++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 87 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 0ce38aa0ed3c..0778747cdd58 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -74,17 +74,17 @@ static phandle live_tree_max_phandle(void) /* * Adjust a subtree's phandle values by a given delta. */ -static void adjust_overlay_phandles(struct device_node *node, +static void adjust_overlay_phandles(struct device_node *overlay, int phandle_delta) { struct device_node *child; struct property *prop; phandle phandle; - if (node->phandle != 0 && node->phandle != OF_PHANDLE_ILLEGAL) - node->phandle += phandle_delta; + if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL) + overlay->phandle += phandle_delta; - for_each_property_of_node(node, prop) { + for_each_property_of_node(overlay, prop) { if (of_prop_cmp(prop->name, "phandle") && of_prop_cmp(prop->name, "linux,phandle")) @@ -97,41 +97,40 @@ static void adjust_overlay_phandles(struct device_node *node, if (phandle == OF_PHANDLE_ILLEGAL) continue; - *(uint32_t *)prop->value = cpu_to_be32(node->phandle); + *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle); } - for_each_child_of_node(node, child) + for_each_child_of_node(overlay, child) adjust_overlay_phandles(child, phandle_delta); } -static int update_usages_of_a_phandle_reference(struct device_node *node, - struct property *rprop, int value) +static int update_usages_of_a_phandle_reference(struct device_node *overlay, + struct property *prop_fixup, phandle phandle) { - phandle phandle; struct device_node *refnode; - struct property *sprop; - char *propval, *propcur, *propend, *nodestr, *propstr, *s; - int offset, propcurlen; + struct property *prop; + char *value, *cur, *end, *node_path, *prop_name, *s; + int offset, len; int err = 0; - propval = kmalloc(rprop->length, GFP_KERNEL); - if (!propval) + value = kmalloc(prop_fixup->length, GFP_KERNEL); + if (!value) return -ENOMEM; - memcpy(propval, rprop->value, rprop->length); + memcpy(value, prop_fixup->value, prop_fixup->length); - propend = propval + rprop->length; - for (propcur = propval; propcur < propend; propcur += propcurlen + 1) { - propcurlen = strlen(propcur); + end = value + prop_fixup->length; + for (cur = value; cur < end; cur += len + 1) { + len = strlen(cur); - nodestr = propcur; - s = strchr(propcur, ':'); + node_path = cur; + s = strchr(cur, ':'); if (!s) { err = -EINVAL; goto err_fail; } *s++ = '\0'; - propstr = s; + prop_name = s; s = strchr(s, ':'); if (!s) { err = -EINVAL; @@ -143,27 +142,26 @@ static int update_usages_of_a_phandle_reference(struct device_node *node, if (err) goto err_fail; - refnode = find_node_by_full_name(node, nodestr); + refnode = find_node_by_full_name(overlay, node_path); if (!refnode) continue; - for_each_property_of_node(refnode, sprop) { - if (!of_prop_cmp(sprop->name, propstr)) + for_each_property_of_node(refnode, prop) { + if (!of_prop_cmp(prop->name, prop_name)) break; } of_node_put(refnode); - if (!sprop) { + if (!prop) { err = -ENOENT; goto err_fail; } - phandle = value; - *(__be32 *)(sprop->value + offset) = cpu_to_be32(phandle); + *(__be32 *)(prop->value + offset) = cpu_to_be32(phandle); } err_fail: - kfree(propval); + kfree(value); return err; } @@ -184,61 +182,61 @@ static int node_name_cmp(const struct device_node *dn1, * Does not take any devtree locks so make sure you call this on a tree * which is at the detached state. */ -static int adjust_local_phandle_references(struct device_node *node, - struct device_node *target, int phandle_delta) +static int adjust_local_phandle_references(struct device_node *local_fixups, + struct device_node *overlay, int phandle_delta) { - struct device_node *child, *childtarget; - struct property *rprop, *sprop; + struct device_node *child, *overlay_child; + struct property *prop_fix, *prop; int err, i, count; unsigned int off; phandle phandle; - if (!node) + if (!local_fixups) return 0; - for_each_property_of_node(node, rprop) { + for_each_property_of_node(local_fixups, prop_fix) { /* skip properties added automatically */ - if (!of_prop_cmp(rprop->name, "name") || - !of_prop_cmp(rprop->name, "phandle") || - !of_prop_cmp(rprop->name, "linux,phandle")) + if (!of_prop_cmp(prop_fix->name, "name") || + !of_prop_cmp(prop_fix->name, "phandle") || + !of_prop_cmp(prop_fix->name, "linux,phandle")) continue; - if ((rprop->length % 4) != 0 || rprop->length == 0) + if ((prop_fix->length % 4) != 0 || prop_fix->length == 0) return -EINVAL; - count = rprop->length / sizeof(__be32); + count = prop_fix->length / sizeof(__be32); - for_each_property_of_node(target, sprop) { - if (!of_prop_cmp(sprop->name, rprop->name)) + for_each_property_of_node(overlay, prop) { + if (!of_prop_cmp(prop->name, prop_fix->name)) break; } - if (!sprop) + if (!prop) return -EINVAL; for (i = 0; i < count; i++) { - off = be32_to_cpu(((__be32 *)rprop->value)[i]); - if (off >= sprop->length || (off + 4) > sprop->length) + off = be32_to_cpu(((__be32 *)prop_fix->value)[i]); + if (off >= prop->length || (off + 4) > prop->length) return -EINVAL; if (phandle_delta) { - phandle = be32_to_cpu(*(__be32 *)(sprop->value + off)); + phandle = be32_to_cpu(*(__be32 *)(prop->value + off)); phandle += phandle_delta; - *(__be32 *)(sprop->value + off) = cpu_to_be32(phandle); + *(__be32 *)(prop->value + off) = cpu_to_be32(phandle); } } } - for_each_child_of_node(node, child) { + for_each_child_of_node(local_fixups, child) { - for_each_child_of_node(target, childtarget) - if (!node_name_cmp(child, childtarget)) + for_each_child_of_node(overlay, overlay_child) + if (!node_name_cmp(child, overlay_child)) break; - if (!childtarget) + if (!overlay_child) return -EINVAL; - err = adjust_local_phandle_references(child, childtarget, + err = adjust_local_phandle_references(child, overlay_child, phandle_delta); if (err) return err; @@ -260,78 +258,78 @@ static int adjust_local_phandle_references(struct device_node *node, * are fit to be inserted or operate upon the live tree. * Returns 0 on success or a negative error value on error. */ -int of_resolve_phandles(struct device_node *resolve) +int of_resolve_phandles(struct device_node *overlay) { - struct device_node *child, *childroot, *refnode; - struct device_node *root_sym, *resolve_sym, *resolve_fix; - struct property *rprop; + struct device_node *child, *local_fixups, *refnode; + struct device_node *tree_symbols, *overlay_symbols, *overlay_fixups; + struct property *prop; const char *refpath; phandle phandle, phandle_delta; int err; - if (!resolve) - pr_err("%s: null node\n", __func__); - if (resolve && !of_node_check_flag(resolve, OF_DETACHED)) + if (!overlay) + pr_err("%s: null overlay\n", __func__); + if (overlay && !of_node_check_flag(overlay, OF_DETACHED)) pr_err("%s: node %s not detached\n", __func__, - resolve->full_name); - if (!resolve || !of_node_check_flag(resolve, OF_DETACHED)) + overlay->full_name); + if (!overlay || !of_node_check_flag(overlay, OF_DETACHED)) return -EINVAL; phandle_delta = live_tree_max_phandle() + 1; - adjust_overlay_phandles(resolve, phandle_delta); + adjust_overlay_phandles(overlay, phandle_delta); - childroot = NULL; - for_each_child_of_node(resolve, childroot) - if (!of_node_cmp(childroot->name, "__local_fixups__")) + local_fixups = NULL; + for_each_child_of_node(overlay, local_fixups) + if (!of_node_cmp(local_fixups->name, "__local_fixups__")) break; - if (childroot != NULL) { - err = adjust_local_phandle_references(childroot, - resolve, 0); + if (local_fixups != NULL) { + err = adjust_local_phandle_references(local_fixups, + overlay, 0); if (err) return err; - BUG_ON(adjust_local_phandle_references(childroot, - resolve, phandle_delta)); + BUG_ON(adjust_local_phandle_references(local_fixups, + overlay, phandle_delta)); } - root_sym = NULL; - resolve_sym = NULL; - resolve_fix = NULL; + tree_symbols = NULL; + overlay_symbols = NULL; + overlay_fixups = NULL; - root_sym = of_find_node_by_path("/__symbols__"); + tree_symbols = of_find_node_by_path("/__symbols__"); - for_each_child_of_node(resolve, child) { + for_each_child_of_node(overlay, child) { - if (!resolve_sym && !of_node_cmp(child->name, "__symbols__")) - resolve_sym = child; + if (!overlay_symbols && !of_node_cmp(child->name, "__symbols__")) + overlay_symbols = child; - if (!resolve_fix && !of_node_cmp(child->name, "__fixups__")) - resolve_fix = child; + if (!overlay_fixups && !of_node_cmp(child->name, "__fixups__")) + overlay_fixups = child; - if (resolve_sym && resolve_fix) + if (overlay_symbols && overlay_fixups) break; } - if (!resolve_fix) { + if (!overlay_fixups) { err = 0; goto out; } - if (!root_sym) { + if (!tree_symbols) { pr_err("%s: no symbols in root of device tree.\n", __func__); err = -EINVAL; goto out; } - for_each_property_of_node(resolve_fix, rprop) { + for_each_property_of_node(overlay_fixups, prop) { /* skip properties added automatically */ - if (!of_prop_cmp(rprop->name, "name")) + if (!of_prop_cmp(prop->name, "name")) continue; - err = of_property_read_string(root_sym, - rprop->name, &refpath); + err = of_property_read_string(tree_symbols, + prop->name, &refpath); if (err) goto out; @@ -344,13 +342,13 @@ int of_resolve_phandles(struct device_node *resolve) phandle = refnode->phandle; of_node_put(refnode); - err = update_usages_of_a_phandle_reference(resolve, rprop, phandle); + err = update_usages_of_a_phandle_reference(overlay, prop, phandle); if (err) break; } out: - of_node_put(root_sym); + of_node_put(tree_symbols); return err; } -- cgit v1.2.3 From 624ab2a49ca30fd61f6c268567d74aaaf949a489 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:27 -0700 Subject: of: Update structure of code to be clearer, also remove BUG_ON() Remove BUG_ON(), which is frowned upon and not needed here. Restructure to remove some excessive complexity. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 0778747cdd58..708daca1d522 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -136,8 +136,8 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay, err = -EINVAL; goto err_fail; } - *s++ = '\0'; + err = kstrtoint(s, 10, &offset); if (err) goto err_fail; @@ -219,11 +219,9 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, if (off >= prop->length || (off + 4) > prop->length) return -EINVAL; - if (phandle_delta) { - phandle = be32_to_cpu(*(__be32 *)(prop->value + off)); - phandle += phandle_delta; - *(__be32 *)(prop->value + off) = cpu_to_be32(phandle); - } + phandle = be32_to_cpu(*(__be32 *)(prop->value + off)); + phandle += phandle_delta; + *(__be32 *)(prop->value + off) = cpu_to_be32(phandle); } } @@ -267,48 +265,36 @@ int of_resolve_phandles(struct device_node *overlay) phandle phandle, phandle_delta; int err; - if (!overlay) - pr_err("%s: null overlay\n", __func__); - if (overlay && !of_node_check_flag(overlay, OF_DETACHED)) - pr_err("%s: node %s not detached\n", __func__, - overlay->full_name); - if (!overlay || !of_node_check_flag(overlay, OF_DETACHED)) + if (!overlay) { + pr_err("null overlay\n"); + return -EINVAL; + } + if (!of_node_check_flag(overlay, OF_DETACHED)) { + pr_err("overlay not detached\n"); return -EINVAL; + } phandle_delta = live_tree_max_phandle() + 1; adjust_overlay_phandles(overlay, phandle_delta); - local_fixups = NULL; for_each_child_of_node(overlay, local_fixups) if (!of_node_cmp(local_fixups->name, "__local_fixups__")) break; - if (local_fixups != NULL) { - err = adjust_local_phandle_references(local_fixups, - overlay, 0); - if (err) - return err; + err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta); + if (err) + return err; - BUG_ON(adjust_local_phandle_references(local_fixups, - overlay, phandle_delta)); - } - - tree_symbols = NULL; overlay_symbols = NULL; overlay_fixups = NULL; tree_symbols = of_find_node_by_path("/__symbols__"); for_each_child_of_node(overlay, child) { - - if (!overlay_symbols && !of_node_cmp(child->name, "__symbols__")) + if (!of_node_cmp(child->name, "__symbols__")) overlay_symbols = child; - - if (!overlay_fixups && !of_node_cmp(child->name, "__fixups__")) + if (!of_node_cmp(child->name, "__fixups__")) overlay_fixups = child; - - if (overlay_symbols && overlay_fixups) - break; } if (!overlay_fixups) { @@ -317,7 +303,7 @@ int of_resolve_phandles(struct device_node *overlay) } if (!tree_symbols) { - pr_err("%s: no symbols in root of device tree.\n", __func__); + pr_err("no symbols in root of device tree.\n"); err = -EINVAL; goto out; } -- cgit v1.2.3 From ea8229b78899bd1edee3051686a4370e5dd56762 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:28 -0700 Subject: of: Remove redundant size check Remove a redundant check of buffer size. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 708daca1d522..76c09cb57eae 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -216,7 +216,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, for (i = 0; i < count; i++) { off = be32_to_cpu(((__be32 *)prop_fix->value)[i]); - if (off >= prop->length || (off + 4) > prop->length) + if ((off + 4) > prop->length) return -EINVAL; phandle = be32_to_cpu(*(__be32 *)(prop->value + off)); -- cgit v1.2.3 From 269f1a67d0978b2fbf26a00fc8e5970272f862fe Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:29 -0700 Subject: of: Update comments to reflect changes and increase clarity Update comments to better explain what functions are doing. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 66 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 76c09cb57eae..f842dbd1585c 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -50,9 +50,6 @@ static struct device_node *find_node_by_full_name(struct device_node *node, return NULL; } -/* - * Find live tree's maximum phandle value. - */ static phandle live_tree_max_phandle(void) { struct device_node *node; @@ -71,9 +68,6 @@ static phandle live_tree_max_phandle(void) return phandle; } -/* - * Adjust a subtree's phandle values by a given delta. - */ static void adjust_overlay_phandles(struct device_node *overlay, int phandle_delta) { @@ -81,9 +75,11 @@ static void adjust_overlay_phandles(struct device_node *overlay, struct property *prop; phandle phandle; + /* adjust node's phandle in node */ if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL) overlay->phandle += phandle_delta; + /* copy adjusted phandle into *phandle properties */ for_each_property_of_node(overlay, prop) { if (of_prop_cmp(prop->name, "phandle") && @@ -118,6 +114,7 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay, return -ENOMEM; memcpy(value, prop_fixup->value, prop_fixup->length); + /* prop_fixup contains a list of tuples of path:property_name:offset */ end = value + prop_fixup->length; for (cur = value; cur < end; cur += len + 1) { len = strlen(cur); @@ -177,10 +174,14 @@ static int node_name_cmp(const struct device_node *dn1, /* * Adjust the local phandle references by the given phandle delta. - * Assumes the existances of a __local_fixups__ node at the root. - * Assumes that __of_verify_tree_phandle_references has been called. - * Does not take any devtree locks so make sure you call this on a tree - * which is at the detached state. + * + * Subtree @local_fixups, which is overlay node __local_fixups__, + * mirrors the fragment node structure at the root of the overlay. + * + * For each property in the fragments that contains a phandle reference, + * @local_fixups has a property of the same name that contains a list + * of offsets of the phandle reference(s) within the respective property + * value(s). The values at these offsets will be fixed up. */ static int adjust_local_phandle_references(struct device_node *local_fixups, struct device_node *overlay, int phandle_delta) @@ -225,6 +226,13 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, } } + /* + * These nested loops recurse down two subtrees in parallel, where the + * node names in the two subtrees match. + * + * The roots of the subtrees are the overlay's __local_fixups__ node + * and the overlay's root node. + */ for_each_child_of_node(local_fixups, child) { for_each_child_of_node(overlay, overlay_child) @@ -244,17 +252,37 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, } /** - * of_resolve - Resolve the given node against the live tree. + * of_resolve_phandles - Relocate and resolve overlay against live tree + * + * @overlay: Pointer to devicetree overlay to relocate and resolve + * + * Modify (relocate) values of local phandles in @overlay to a range that + * does not conflict with the live expanded devicetree. Update references + * to the local phandles in @overlay. Update (resolve) phandle references + * in @overlay that refer to the live expanded devicetree. + * + * Phandle values in the live tree are in the range of + * 1 .. live_tree_max_phandle(). The range of phandle values in the overlay + * also begin with at 1. Adjust the phandle values in the overlay to begin + * at live_tree_max_phandle() + 1. Update references to the phandles to + * the adjusted phandle values. + * + * The name of each property in the "__fixups__" node in the overlay matches + * the name of a symbol (a label) in the live tree. The values of each + * property in the "__fixups__" node is a list of the property values in the + * overlay that need to be updated to contain the phandle reference + * corresponding to that symbol in the live tree. Update the references in + * the overlay with the phandle values in the live tree. + * + * @overlay must be detached. * - * @resolve: Node to resolve + * Resolving and applying @overlay to the live expanded devicetree must be + * protected by a mechanism to ensure that multiple overlays are processed + * in a single threaded manner so that multiple overlays will not relocate + * phandles to overlapping ranges. The mechanism to enforce this is not + * yet implemented. * - * Perform dynamic Device Tree resolution against the live tree - * to the given node to resolve. This depends on the live tree - * having a __symbols__ node, and the resolve node the __fixups__ & - * __local_fixups__ nodes (if needed). - * The result of the operation is a resolve node that it's contents - * are fit to be inserted or operate upon the live tree. - * Returns 0 on success or a negative error value on error. + * Return: %0 on success or a negative error value on error. */ int of_resolve_phandles(struct device_node *overlay) { -- cgit v1.2.3 From d9181b20a83bd8de207e0cb54be499d9880b00e3 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:30 -0700 Subject: of: Add back an error message, restructured Add a single pr_err() to cover a range of errors that were reported by several pr_err() that were removed earlier in this series. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index f842dbd1585c..eb78010c21a3 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -293,13 +293,17 @@ int of_resolve_phandles(struct device_node *overlay) phandle phandle, phandle_delta; int err; + tree_symbols = NULL; + if (!overlay) { pr_err("null overlay\n"); - return -EINVAL; + err = -EINVAL; + goto err_out; } if (!of_node_check_flag(overlay, OF_DETACHED)) { pr_err("overlay not detached\n"); - return -EINVAL; + err = -EINVAL; + goto err_out; } phandle_delta = live_tree_max_phandle() + 1; @@ -311,7 +315,7 @@ int of_resolve_phandles(struct device_node *overlay) err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta); if (err) - return err; + goto err_out; overlay_symbols = NULL; overlay_fixups = NULL; @@ -333,7 +337,7 @@ int of_resolve_phandles(struct device_node *overlay) if (!tree_symbols) { pr_err("no symbols in root of device tree.\n"); err = -EINVAL; - goto out; + goto err_out; } for_each_property_of_node(overlay_fixups, prop) { @@ -345,12 +349,12 @@ int of_resolve_phandles(struct device_node *overlay) err = of_property_read_string(tree_symbols, prop->name, &refpath); if (err) - goto out; + goto err_out; refnode = of_find_node_by_path(refpath); if (!refnode) { err = -ENOENT; - goto out; + goto err_out; } phandle = refnode->phandle; @@ -361,6 +365,8 @@ int of_resolve_phandles(struct device_node *overlay) break; } +err_out: + pr_err("overlay phandle fixup failed: %d\n", err); out: of_node_put(tree_symbols); -- cgit v1.2.3 From 4458db4c9b7363a60d9ad07275fb2eea4ecf3b52 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:31 -0700 Subject: of: Move setting of pointer to beside test for non-null Value of pointer was calculated in an earlier block than where it was used. Move it down into the block where it is used, immediately before where is is checked to be valid. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index eb78010c21a3..53353cc8f2bb 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -320,8 +320,6 @@ int of_resolve_phandles(struct device_node *overlay) overlay_symbols = NULL; overlay_fixups = NULL; - tree_symbols = of_find_node_by_path("/__symbols__"); - for_each_child_of_node(overlay, child) { if (!of_node_cmp(child->name, "__symbols__")) overlay_symbols = child; @@ -334,6 +332,7 @@ int of_resolve_phandles(struct device_node *overlay) goto out; } + tree_symbols = of_find_node_by_path("/__symbols__"); if (!tree_symbols) { pr_err("no symbols in root of device tree.\n"); err = -EINVAL; -- cgit v1.2.3 From 5581a95f2dacb3674827f450ac406e1f8ae3b3e5 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 28 Oct 2016 23:26:32 -0700 Subject: of: Remove unused variable overlay_symbols Remove unused pointer to node "__symbols__". Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 53353cc8f2bb..783bd09463b5 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -287,7 +287,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, int of_resolve_phandles(struct device_node *overlay) { struct device_node *child, *local_fixups, *refnode; - struct device_node *tree_symbols, *overlay_symbols, *overlay_fixups; + struct device_node *tree_symbols, *overlay_fixups; struct property *prop; const char *refpath; phandle phandle, phandle_delta; @@ -317,12 +317,9 @@ int of_resolve_phandles(struct device_node *overlay) if (err) goto err_out; - overlay_symbols = NULL; overlay_fixups = NULL; for_each_child_of_node(overlay, child) { - if (!of_node_cmp(child->name, "__symbols__")) - overlay_symbols = child; if (!of_node_cmp(child->name, "__fixups__")) overlay_fixups = child; } -- cgit v1.2.3 From 71ec6f4f7314d4d3ac44bae038bd748bd7961dc6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 1 Nov 2016 11:53:21 +0100 Subject: of/platform: fix of_platform_device_destroy comment Update the comment to of_platform_device_destroy() to reflect that it no longer returns a status value. Fixes: 75f353b61342 ("of/platform: Fix of_platform_device_destroy...") Signed-off-by: Johan Hovold Signed-off-by: Rob Herring --- drivers/of/platform.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e4bf07d20f9b..cb4c7800f37d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -558,9 +558,6 @@ static int of_platform_device_destroy(struct device *dev, void *data) * of the given device (and, recurrently, their children) that have been * created from their respective device tree nodes (and only those, * leaving others - eg. manually created - unharmed). - * - * Returns 0 when all children devices have been removed or - * -EBUSY when some children remained. */ void of_platform_depopulate(struct device *parent) { -- cgit v1.2.3 From 4fb373dfabee1367b7553003b4d6491ee8bf4c2a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 1 Nov 2016 11:53:22 +0100 Subject: of/platform: clarify of_find_device_by_node refcounting Add comment clarifying that of_find_device_by_node() takes a reference to the embedded struct device which needs to be dropped after use. Note that most current users fail to do so. Signed-off-by: Johan Hovold Signed-off-by: Rob Herring --- drivers/of/platform.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index cb4c7800f37d..b8064bc2b6eb 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -45,6 +45,9 @@ static int of_dev_node_match(struct device *dev, void *data) * of_find_device_by_node - Find the platform_device associated with a node * @np: Pointer to device tree node * + * Takes a reference to the embedded struct device which needs to be dropped + * after use. + * * Returns platform_device pointer, or NULL if not found */ struct platform_device *of_find_device_by_node(struct device_node *np) -- cgit v1.2.3 From e5269794d2e9046dd45be15bdb213a229df46b7e Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 17 Nov 2016 15:32:54 +0000 Subject: of: base: add support to get machine model name Currently platforms/drivers needing to get the machine model name are replicating the same snippet of code. In some case, the OF reference counting is either missing or incorrect. This patch adds support to read the machine model name either using the "model" or the "compatible" property in the device tree root node to the core OF/DT code. This can be used to remove all the duplicate code snippets doing exactly same thing later. Cc: Rob Herring Cc: Frank Rowand Cc: Arnd Bergmann Signed-off-by: Sudeep Holla Signed-off-by: Rob Herring --- drivers/of/base.c | 32 ++++++++++++++++++++++++++++++++ include/linux/of.h | 6 ++++++ 2 files changed, 38 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index d687e6de24a0..128e114f9210 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -545,6 +545,38 @@ int of_machine_is_compatible(const char *compat) } EXPORT_SYMBOL(of_machine_is_compatible); +/** + * of_machine_get_model_name - Find and read the model name or the compatible + * value for the machine. + * @model: pointer to null terminated return string, modified only if + * return value is 0. + * + * Returns a string containing either the model name or the compatible value + * of the machine if found, else return error. + * + * Search for a machine model name or the compatible if model name is missing + * in a device tree node and retrieve a null terminated string value (pointer + * to data, not a copy). Returns 0 on success, -EINVAL if root of the device + * tree is not found and other error returned by of_property_read_string on + * failure. + */ +int of_machine_get_model_name(const char **model) +{ + int error; + + if (!of_node_get(of_root)) + return -EINVAL; + + error = of_property_read_string(of_root, "model", model); + if (error) + error = of_property_read_string_index(of_root, "compatible", + 0, model); + of_node_put(of_root); + + return error; +} +EXPORT_SYMBOL(of_machine_get_model_name); + /** * __of_device_is_available - check if a device is available for use * diff --git a/include/linux/of.h b/include/linux/of.h index 299aeb192727..9eb8eb3c587e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -367,6 +367,7 @@ extern int of_alias_get_id(struct device_node *np, const char *stem); extern int of_alias_get_highest_id(const char *stem); extern int of_machine_is_compatible(const char *compat); +extern int of_machine_get_model_name(const char **model); extern int of_add_property(struct device_node *np, struct property *prop); extern int of_remove_property(struct device_node *np, struct property *prop); @@ -788,6 +789,11 @@ static inline int of_machine_is_compatible(const char *compat) return 0; } +static inline int of_machine_get_model_name(const char **model) +{ + return -EINVAL; +} + static inline bool of_console_check(const struct device_node *dn, const char *name, int index) { return false; -- cgit v1.2.3 From 4aa663444048396799b49b5b782552c1ba15c39d Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Thu, 1 Dec 2016 09:00:55 +0100 Subject: drivers/of: fix missing pr_cont()s in of_print_phandle_args Since the KERN_CONT changes, the current debug printks have a lot of empty lines making the log messages very hard to read. Signed-off-by: Marcin Nowakowski Signed-off-by: Rob Herring --- drivers/of/base.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index 128e114f9210..5e04572e692a 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1566,9 +1566,12 @@ void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) { int i; printk("%s %s", msg, of_node_full_name(args->np)); - for (i = 0; i < args->args_count; i++) - printk(i ? ",%08x" : ":%08x", args->args[i]); - printk("\n"); + for (i = 0; i < args->args_count; i++) { + const char delim = i ? ',' : ':'; + + pr_cont("%c%08x", delim, args->args[i]); + } + pr_cont("\n"); } int of_phandle_iterator_init(struct of_phandle_iterator *it, -- cgit v1.2.3 From 32bed310ad32b1cf66525fae89913d76dde4d797 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Thu, 1 Dec 2016 22:10:25 -0800 Subject: of: Fix issue where code would fall through to error case. No longer fall through into the error case that prints out an error if no error (err = 0) occurred. Fixes d9181b20a83(of: Add back an error message, restructured) Signed-off-by: Moritz Fischer Reviewed-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/resolver.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 783bd09463b5..8bf12e904fd2 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -298,12 +298,12 @@ int of_resolve_phandles(struct device_node *overlay) if (!overlay) { pr_err("null overlay\n"); err = -EINVAL; - goto err_out; + goto out; } if (!of_node_check_flag(overlay, OF_DETACHED)) { pr_err("overlay not detached\n"); err = -EINVAL; - goto err_out; + goto out; } phandle_delta = live_tree_max_phandle() + 1; @@ -315,7 +315,7 @@ int of_resolve_phandles(struct device_node *overlay) err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta); if (err) - goto err_out; + goto out; overlay_fixups = NULL; @@ -333,7 +333,7 @@ int of_resolve_phandles(struct device_node *overlay) if (!tree_symbols) { pr_err("no symbols in root of device tree.\n"); err = -EINVAL; - goto err_out; + goto out; } for_each_property_of_node(overlay_fixups, prop) { @@ -345,12 +345,12 @@ int of_resolve_phandles(struct device_node *overlay) err = of_property_read_string(tree_symbols, prop->name, &refpath); if (err) - goto err_out; + goto out; refnode = of_find_node_by_path(refpath); if (!refnode) { err = -ENOENT; - goto err_out; + goto out; } phandle = refnode->phandle; @@ -361,9 +361,9 @@ int of_resolve_phandles(struct device_node *overlay) break; } -err_out: - pr_err("overlay phandle fixup failed: %d\n", err); out: + if (err) + pr_err("overlay phandle fixup failed: %d\n", err); of_node_put(tree_symbols); return err; -- cgit v1.2.3 From 0a8b13eab1349337db4a4b5755466460bfbbaa1e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 9 Dec 2016 10:33:48 -0600 Subject: Revert "of: base: add support to get machine model name" This reverts commit e5269794d2e9046dd45be15bdb213a229df46b7e. --- drivers/of/base.c | 32 -------------------------------- include/linux/of.h | 6 ------ 2 files changed, 38 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index 5e04572e692a..60b878e88a48 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -545,38 +545,6 @@ int of_machine_is_compatible(const char *compat) } EXPORT_SYMBOL(of_machine_is_compatible); -/** - * of_machine_get_model_name - Find and read the model name or the compatible - * value for the machine. - * @model: pointer to null terminated return string, modified only if - * return value is 0. - * - * Returns a string containing either the model name or the compatible value - * of the machine if found, else return error. - * - * Search for a machine model name or the compatible if model name is missing - * in a device tree node and retrieve a null terminated string value (pointer - * to data, not a copy). Returns 0 on success, -EINVAL if root of the device - * tree is not found and other error returned by of_property_read_string on - * failure. - */ -int of_machine_get_model_name(const char **model) -{ - int error; - - if (!of_node_get(of_root)) - return -EINVAL; - - error = of_property_read_string(of_root, "model", model); - if (error) - error = of_property_read_string_index(of_root, "compatible", - 0, model); - of_node_put(of_root); - - return error; -} -EXPORT_SYMBOL(of_machine_get_model_name); - /** * __of_device_is_available - check if a device is available for use * diff --git a/include/linux/of.h b/include/linux/of.h index 9eb8eb3c587e..299aeb192727 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -367,7 +367,6 @@ extern int of_alias_get_id(struct device_node *np, const char *stem); extern int of_alias_get_highest_id(const char *stem); extern int of_machine_is_compatible(const char *compat); -extern int of_machine_get_model_name(const char **model); extern int of_add_property(struct device_node *np, struct property *prop); extern int of_remove_property(struct device_node *np, struct property *prop); @@ -789,11 +788,6 @@ static inline int of_machine_is_compatible(const char *compat) return 0; } -static inline int of_machine_get_model_name(const char **model) -{ - return -EINVAL; -} - static inline bool of_console_check(const struct device_node *dn, const char *name, int index) { return false; -- cgit v1.2.3