aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-10-02 08:09:15 -0400
committerGrant Likely <grant.likely@linaro.org>2014-10-04 16:20:19 -0400
commit841ec21357eee222416e3b7f1b6ef23cfc6ee43f (patch)
tree2765f4633c7e6e039f6605f620eab3f60a96a966 /drivers/of
parentfc59b4479c172e413df615cea1635247265e07a0 (diff)
of/selftest: Add a test for duplicate phandles
All phandles in the tree should be unique. Add a testcase to make sure that this is so. Note: this testcase fails on the current kernel because the selftest code itself ends up adding duplicate phandles. Before this testcase is merged the selftest code needs to be modified to resolve phandles before adding them. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/selftest.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 252a7eda8d6a..4f83e97f8788 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -7,6 +7,7 @@
7#include <linux/clk.h> 7#include <linux/clk.h>
8#include <linux/err.h> 8#include <linux/err.h>
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/hashtable.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/of.h> 12#include <linux/of.h>
12#include <linux/of_fdt.h> 13#include <linux/of_fdt.h>
@@ -192,6 +193,51 @@ static void __init of_selftest_check_tree_linkage(void)
192 pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count); 193 pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count);
193} 194}
194 195
196struct node_hash {
197 struct hlist_node node;
198 struct device_node *np;
199};
200
201static void __init of_selftest_check_phandles(void)
202{
203 struct device_node *np;
204 struct node_hash *nh;
205 struct hlist_node *tmp;
206 int i, dup_count = 0, phandle_count = 0;
207 DECLARE_HASHTABLE(ht, 8);
208
209 hash_init(ht);
210 for_each_of_allnodes(np) {
211 if (!np->phandle)
212 continue;
213
214 hash_for_each_possible(ht, nh, node, np->phandle) {
215 if (nh->np->phandle == np->phandle) {
216 pr_info("Duplicate phandle! %i used by %s and %s\n",
217 np->phandle, nh->np->full_name, np->full_name);
218 dup_count++;
219 break;
220 }
221 }
222
223 nh = kzalloc(sizeof(*nh), GFP_KERNEL);
224 if (WARN_ON(!nh))
225 return;
226
227 nh->np = np;
228 hash_add(ht, &nh->node, np->phandle);
229 phandle_count++;
230 }
231 selftest(dup_count == 0, "Found %i duplicates in %i phandles\n",
232 dup_count, phandle_count);
233
234 /* Clean up */
235 hash_for_each_safe(ht, i, tmp, nh, node) {
236 hash_del(&nh->node);
237 kfree(nh);
238 }
239}
240
195static void __init of_selftest_parse_phandle_with_args(void) 241static void __init of_selftest_parse_phandle_with_args(void)
196{ 242{
197 struct device_node *np; 243 struct device_node *np;
@@ -825,6 +871,7 @@ static int __init of_selftest(void)
825 871
826 pr_info("start of selftest - you will see error messages\n"); 872 pr_info("start of selftest - you will see error messages\n");
827 of_selftest_check_tree_linkage(); 873 of_selftest_check_tree_linkage();
874 of_selftest_check_phandles();
828 of_selftest_find_node_by_name(); 875 of_selftest_find_node_by_name();
829 of_selftest_dynamic(); 876 of_selftest_dynamic();
830 of_selftest_parse_phandle_with_args(); 877 of_selftest_parse_phandle_with_args();