aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/selftest.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-10-03 11:28:27 -0400
committerGrant Likely <grant.likely@linaro.org>2014-11-04 08:29:38 -0500
commit5063e25a302e6a83f6590d9a06bd5f6400b17430 (patch)
treebd6aafd28fb65ea19cd1535fd9a53263b42a68c0 /drivers/of/selftest.c
parente7a00e4210e4cc980e3ba67ec7301af54061d14b (diff)
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)
148 148
149static int __init of_selftest_check_node_linkage(struct device_node *np) 149static int __init of_selftest_check_node_linkage(struct device_node *np)
150{ 150{
151 struct device_node *child, *allnext_index = np; 151 struct device_node *child;
152 int count = 0, rc; 152 int count = 0, rc;
153 153
154 for_each_child_of_node(np, child) { 154 for_each_child_of_node(np, child) {
@@ -158,14 +158,6 @@ static int __init of_selftest_check_node_linkage(struct device_node *np)
158 return -EINVAL; 158 return -EINVAL;
159 } 159 }
160 160
161 while (allnext_index && allnext_index != child)
162 allnext_index = allnext_index->allnext;
163 if (allnext_index != child) {
164 pr_err("Node %s is ordered differently in sibling and allnode lists\n",
165 child->name);
166 return -EINVAL;
167 }
168
169 rc = of_selftest_check_node_linkage(child); 161 rc = of_selftest_check_node_linkage(child);
170 if (rc < 0) 162 if (rc < 0)
171 return rc; 163 return rc;
@@ -180,12 +172,12 @@ static void __init of_selftest_check_tree_linkage(void)
180 struct device_node *np; 172 struct device_node *np;
181 int allnode_count = 0, child_count; 173 int allnode_count = 0, child_count;
182 174
183 if (!of_allnodes) 175 if (!of_root)
184 return; 176 return;
185 177
186 for_each_of_allnodes(np) 178 for_each_of_allnodes(np)
187 allnode_count++; 179 allnode_count++;
188 child_count = of_selftest_check_node_linkage(of_allnodes); 180 child_count = of_selftest_check_node_linkage(of_root);
189 181
190 selftest(child_count > 0, "Device node data structure is corrupted\n"); 182 selftest(child_count > 0, "Device node data structure is corrupted\n");
191 selftest(child_count == allnode_count, "allnodes list size (%i) doesn't match" 183 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,
775 */ 767 */
776static int attach_node_and_children(struct device_node *np) 768static int attach_node_and_children(struct device_node *np)
777{ 769{
778 struct device_node *next, *root = np, *dup; 770 struct device_node *next, *dup, *child;
779 771
780 /* skip root node */ 772 dup = of_find_node_by_path(np->full_name);
781 np = np->child; 773 if (dup) {
782 /* storing a copy in temporary node */ 774 update_node_properties(np, dup);
783 dup = np; 775 return 0;
776 }
784 777
785 while (dup) { 778 /* Children of the root need to be remembered for removal */
779 if (np->parent == of_root) {
786 if (WARN_ON(last_node_index >= NO_OF_NODES)) 780 if (WARN_ON(last_node_index >= NO_OF_NODES))
787 return -EINVAL; 781 return -EINVAL;
788 nodes[last_node_index++] = dup; 782 nodes[last_node_index++] = np;
789 dup = dup->sibling;
790 } 783 }
791 dup = NULL;
792 784
793 while (np) { 785 child = np->child;
794 next = np->allnext; 786 np->child = NULL;
795 dup = of_find_node_by_path(np->full_name); 787 np->sibling = NULL;
796 if (dup) 788 of_attach_node(np);
797 update_node_properties(np, dup); 789 while (child) {
798 else { 790 next = child->sibling;
799 np->child = NULL; 791 attach_node_and_children(child);
800 if (np->parent == root) 792 child = next;
801 np->parent = of_allnodes;
802 of_attach_node(np);
803 }
804 np = next;
805 } 793 }
806 794
807 return 0; 795 return 0;
@@ -846,10 +834,10 @@ static int __init selftest_data_add(void)
846 return -EINVAL; 834 return -EINVAL;
847 } 835 }
848 836
849 if (!of_allnodes) { 837 if (!of_root) {
850 /* enabling flag for removing nodes */ 838 /* enabling flag for removing nodes */
851 selftest_live_tree = true; 839 selftest_live_tree = true;
852 of_allnodes = selftest_data_node; 840 of_root = selftest_data_node;
853 841
854 for_each_of_allnodes(np) 842 for_each_of_allnodes(np)
855 __of_attach_node_sysfs(np); 843 __of_attach_node_sysfs(np);
@@ -859,7 +847,14 @@ static int __init selftest_data_add(void)
859 } 847 }
860 848
861 /* attach the sub-tree to live tree */ 849 /* attach the sub-tree to live tree */
862 return attach_node_and_children(selftest_data_node); 850 np = selftest_data_node->child;
851 while (np) {
852 struct device_node *next = np->sibling;
853 np->parent = of_root;
854 attach_node_and_children(np);
855 np = next;
856 }
857 return 0;
863} 858}
864 859
865/** 860/**
@@ -889,10 +884,10 @@ static void selftest_data_remove(void)
889 of_node_put(of_chosen); 884 of_node_put(of_chosen);
890 of_aliases = NULL; 885 of_aliases = NULL;
891 of_chosen = NULL; 886 of_chosen = NULL;
892 for_each_child_of_node(of_allnodes, np) 887 for_each_child_of_node(of_root, np)
893 detach_node_and_children(np); 888 detach_node_and_children(np);
894 __of_detach_node_sysfs(of_allnodes); 889 __of_detach_node_sysfs(of_root);
895 of_allnodes = NULL; 890 of_root = NULL;
896 return; 891 return;
897 } 892 }
898 893