aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/selftest.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-10-03 16:28:27 +0100
committerGrant Likely <grant.likely@linaro.org>2014-11-04 13:29:38 +0000
commit5063e25a302e6a83f6590d9a06bd5f6400b17430 (patch)
treebd6aafd28fb65ea19cd1535fd9a53263b42a68c0 /drivers/of/selftest.c
parentof: introduce of_property_read_s32 (diff)
downloadlinux-dev-5063e25a302e6a83f6590d9a06bd5f6400b17430.tar.xz
linux-dev-5063e25a302e6a83f6590d9a06bd5f6400b17430.zip
of: Eliminate of_allnodes list
The device tree structure is composed of two lists; the 'allnodes' list which is a singly linked list containing every node in the tree, and the child->parent structure where each parent node has a singly linked list of children. All of the data in the allnodes list can be easily reproduced with the parent-child lists, so of_allnodes is actually unnecessary. Remove it entirely which saves a bit of memory and simplifies the data structure quite a lot. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <robh@kernel.org> Cc: Gaurav Minocha <gaurav.minocha.os@gmail.com> Cc: Pantelis Antoniou <pantelis@pantelis.antoniou@konsulko.com>
Diffstat (limited to 'drivers/of/selftest.c')
-rw-r--r--drivers/of/selftest.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 11b873c54a77..bf7d99317a94 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -148,7 +148,7 @@ static void __init of_selftest_dynamic(void)
static int __init of_selftest_check_node_linkage(struct device_node *np)
{
- struct device_node *child, *allnext_index = np;
+ struct device_node *child;
int count = 0, rc;
for_each_child_of_node(np, child) {
@@ -158,14 +158,6 @@ static int __init of_selftest_check_node_linkage(struct device_node *np)
return -EINVAL;
}
- while (allnext_index && allnext_index != child)
- allnext_index = allnext_index->allnext;
- if (allnext_index != child) {
- pr_err("Node %s is ordered differently in sibling and allnode lists\n",
- child->name);
- return -EINVAL;
- }
-
rc = of_selftest_check_node_linkage(child);
if (rc < 0)
return rc;
@@ -180,12 +172,12 @@ static void __init of_selftest_check_tree_linkage(void)
struct device_node *np;
int allnode_count = 0, child_count;
- if (!of_allnodes)
+ if (!of_root)
return;
for_each_of_allnodes(np)
allnode_count++;
- child_count = of_selftest_check_node_linkage(of_allnodes);
+ child_count = of_selftest_check_node_linkage(of_root);
selftest(child_count > 0, "Device node data structure is corrupted\n");
selftest(child_count == allnode_count, "allnodes list size (%i) doesn't match"
@@ -775,33 +767,29 @@ static void update_node_properties(struct device_node *np,
*/
static int attach_node_and_children(struct device_node *np)
{
- struct device_node *next, *root = np, *dup;
+ struct device_node *next, *dup, *child;
- /* skip root node */
- np = np->child;
- /* storing a copy in temporary node */
- dup = np;
+ dup = of_find_node_by_path(np->full_name);
+ if (dup) {
+ update_node_properties(np, dup);
+ return 0;
+ }
- while (dup) {
+ /* Children of the root need to be remembered for removal */
+ if (np->parent == of_root) {
if (WARN_ON(last_node_index >= NO_OF_NODES))
return -EINVAL;
- nodes[last_node_index++] = dup;
- dup = dup->sibling;
+ nodes[last_node_index++] = np;
}
- dup = NULL;
- while (np) {
- next = np->allnext;
- dup = of_find_node_by_path(np->full_name);
- if (dup)
- update_node_properties(np, dup);
- else {
- np->child = NULL;
- if (np->parent == root)
- np->parent = of_allnodes;
- of_attach_node(np);
- }
- np = next;
+ child = np->child;
+ np->child = NULL;
+ np->sibling = NULL;
+ of_attach_node(np);
+ while (child) {
+ next = child->sibling;
+ attach_node_and_children(child);
+ child = next;
}
return 0;
@@ -846,10 +834,10 @@ static int __init selftest_data_add(void)
return -EINVAL;
}
- if (!of_allnodes) {
+ if (!of_root) {
/* enabling flag for removing nodes */
selftest_live_tree = true;
- of_allnodes = selftest_data_node;
+ of_root = selftest_data_node;
for_each_of_allnodes(np)
__of_attach_node_sysfs(np);
@@ -859,7 +847,14 @@ static int __init selftest_data_add(void)
}
/* attach the sub-tree to live tree */
- return attach_node_and_children(selftest_data_node);
+ np = selftest_data_node->child;
+ while (np) {
+ struct device_node *next = np->sibling;
+ np->parent = of_root;
+ attach_node_and_children(np);
+ np = next;
+ }
+ return 0;
}
/**
@@ -889,10 +884,10 @@ static void selftest_data_remove(void)
of_node_put(of_chosen);
of_aliases = NULL;
of_chosen = NULL;
- for_each_child_of_node(of_allnodes, np)
+ for_each_child_of_node(of_root, np)
detach_node_and_children(np);
- __of_detach_node_sysfs(of_allnodes);
- of_allnodes = NULL;
+ __of_detach_node_sysfs(of_root);
+ of_root = NULL;
return;
}