Message ID | 20150122161446.101EBC40A80@trevor.secretlab.ca |
---|---|
State | New |
Headers | show |
On Thu, Jan 22, 2015 at 4:14 PM, Grant Likely <grant.likely@linaro.org> wrote: > On Wed, 14 Jan 2015 16:45:56 +0100 > , Geert Uytterhoeven <geert+renesas@glider.be> > wrote: >> When traversing all nodes and moving to a new path component, the old >> one must be released by calling of_node_put(). Else the refcounts of the >> parent node(s) will not be decremented. >> >> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> >> --- [...] >> Feel free to (ab)use the code below and derive a unittest from it... BTW, can you do this please? They are pretty important for core changes now, and I'm stuck with doing them if the person supplying a patch does not (and I'm already too much of a bottleneck on the DT code). g. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
diff --git a/drivers/of/base.c b/drivers/of/base.c index 36536b6a8834..0357b51a7440 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -626,9 +626,8 @@ static struct device_node *__of_get_next_child(const struct device_node *node, next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) - if (of_node_get(next)) + if (next) break; - of_node_put(prev); return next; } #define __for_each_child_of_node(parent, child) \ @@ -650,7 +649,8 @@ struct device_node *of_get_next_child(const struct device_node *node, unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - next = __of_get_next_child(node, prev); + next = of_node_get(__of_get_next_child(node, prev)); + of_node_put(prev); raw_spin_unlock_irqrestore(&devtree_lock, flags); return next; } @@ -789,12 +789,13 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt /* Step down the tree matching path components */ raw_spin_lock_irqsave(&devtree_lock, flags); if (!np) - np = of_node_get(of_root); + np = of_root; while (np && *path == '/') { path++; /* Increment past '/' delimiter */ np = __of_find_node_by_path(np, path); path = strchrnul(path, '/'); } + of_node_get(np); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; }