• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Self tests for device tree subsystem
3  */
4 
5 #define pr_fmt(fmt) "### dt-test ### " fmt
6 
7 #include <linux/clk.h>
8 #include <linux/err.h>
9 #include <linux/errno.h>
10 #include <linux/hashtable.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_fdt.h>
14 #include <linux/of_irq.h>
15 #include <linux/of_platform.h>
16 #include <linux/list.h>
17 #include <linux/mutex.h>
18 #include <linux/slab.h>
19 #include <linux/device.h>
20 
21 #include "of_private.h"
22 
23 static struct selftest_results {
24 	int passed;
25 	int failed;
26 } selftest_results;
27 
28 #define NO_OF_NODES 3
29 static struct device_node *nodes[NO_OF_NODES];
30 static int last_node_index;
31 static bool selftest_live_tree;
32 
33 #define selftest(result, fmt, ...) { \
34 	if (!(result)) { \
35 		selftest_results.failed++; \
36 		pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
37 	} else { \
38 		selftest_results.passed++; \
39 		pr_debug("pass %s():%i\n", __func__, __LINE__); \
40 	} \
41 }
42 
of_selftest_find_node_by_name(void)43 static void __init of_selftest_find_node_by_name(void)
44 {
45 	struct device_node *np;
46 
47 	np = of_find_node_by_path("/testcase-data");
48 	selftest(np && !strcmp("/testcase-data", np->full_name),
49 		"find /testcase-data failed\n");
50 	of_node_put(np);
51 
52 	/* Test if trailing '/' works */
53 	np = of_find_node_by_path("/testcase-data/");
54 	selftest(!np, "trailing '/' on /testcase-data/ should fail\n");
55 
56 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
57 	selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
58 		"find /testcase-data/phandle-tests/consumer-a failed\n");
59 	of_node_put(np);
60 
61 	np = of_find_node_by_path("testcase-alias");
62 	selftest(np && !strcmp("/testcase-data", np->full_name),
63 		"find testcase-alias failed\n");
64 	of_node_put(np);
65 
66 	/* Test if trailing '/' works on aliases */
67 	np = of_find_node_by_path("testcase-alias/");
68 	selftest(!np, "trailing '/' on testcase-alias/ should fail\n");
69 
70 	np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
71 	selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
72 		"find testcase-alias/phandle-tests/consumer-a failed\n");
73 	of_node_put(np);
74 
75 	np = of_find_node_by_path("/testcase-data/missing-path");
76 	selftest(!np, "non-existent path returned node %s\n", np->full_name);
77 	of_node_put(np);
78 
79 	np = of_find_node_by_path("missing-alias");
80 	selftest(!np, "non-existent alias returned node %s\n", np->full_name);
81 	of_node_put(np);
82 
83 	np = of_find_node_by_path("testcase-alias/missing-path");
84 	selftest(!np, "non-existent alias with relative path returned node %s\n", np->full_name);
85 	of_node_put(np);
86 }
87 
of_selftest_dynamic(void)88 static void __init of_selftest_dynamic(void)
89 {
90 	struct device_node *np;
91 	struct property *prop;
92 
93 	np = of_find_node_by_path("/testcase-data");
94 	if (!np) {
95 		pr_err("missing testcase data\n");
96 		return;
97 	}
98 
99 	/* Array of 4 properties for the purpose of testing */
100 	prop = kzalloc(sizeof(*prop) * 4, GFP_KERNEL);
101 	if (!prop) {
102 		selftest(0, "kzalloc() failed\n");
103 		return;
104 	}
105 
106 	/* Add a new property - should pass*/
107 	prop->name = "new-property";
108 	prop->value = "new-property-data";
109 	prop->length = strlen(prop->value);
110 	selftest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
111 
112 	/* Try to add an existing property - should fail */
113 	prop++;
114 	prop->name = "new-property";
115 	prop->value = "new-property-data-should-fail";
116 	prop->length = strlen(prop->value);
117 	selftest(of_add_property(np, prop) != 0,
118 		 "Adding an existing property should have failed\n");
119 
120 	/* Try to modify an existing property - should pass */
121 	prop->value = "modify-property-data-should-pass";
122 	prop->length = strlen(prop->value);
123 	selftest(of_update_property(np, prop) == 0,
124 		 "Updating an existing property should have passed\n");
125 
126 	/* Try to modify non-existent property - should pass*/
127 	prop++;
128 	prop->name = "modify-property";
129 	prop->value = "modify-missing-property-data-should-pass";
130 	prop->length = strlen(prop->value);
131 	selftest(of_update_property(np, prop) == 0,
132 		 "Updating a missing property should have passed\n");
133 
134 	/* Remove property - should pass */
135 	selftest(of_remove_property(np, prop) == 0,
136 		 "Removing a property should have passed\n");
137 
138 	/* Adding very large property - should pass */
139 	prop++;
140 	prop->name = "large-property-PAGE_SIZEx8";
141 	prop->length = PAGE_SIZE * 8;
142 	prop->value = kzalloc(prop->length, GFP_KERNEL);
143 	selftest(prop->value != NULL, "Unable to allocate large buffer\n");
144 	if (prop->value)
145 		selftest(of_add_property(np, prop) == 0,
146 			 "Adding a large property should have passed\n");
147 }
148 
of_selftest_check_node_linkage(struct device_node * np)149 static int __init of_selftest_check_node_linkage(struct device_node *np)
150 {
151 	struct device_node *child, *allnext_index = np;
152 	int count = 0, rc;
153 
154 	for_each_child_of_node(np, child) {
155 		if (child->parent != np) {
156 			pr_err("Child node %s links to wrong parent %s\n",
157 				 child->name, np->name);
158 			return -EINVAL;
159 		}
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);
170 		if (rc < 0)
171 			return rc;
172 		count += rc;
173 	}
174 
175 	return count + 1;
176 }
177 
of_selftest_check_tree_linkage(void)178 static void __init of_selftest_check_tree_linkage(void)
179 {
180 	struct device_node *np;
181 	int allnode_count = 0, child_count;
182 
183 	if (!of_allnodes)
184 		return;
185 
186 	for_each_of_allnodes(np)
187 		allnode_count++;
188 	child_count = of_selftest_check_node_linkage(of_allnodes);
189 
190 	selftest(child_count > 0, "Device node data structure is corrupted\n");
191 	selftest(child_count == allnode_count, "allnodes list size (%i) doesn't match"
192 		 "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);
194 }
195 
196 struct node_hash {
197 	struct hlist_node node;
198 	struct device_node *np;
199 };
200 
201 static DEFINE_HASHTABLE(phandle_ht, 8);
of_selftest_check_phandles(void)202 static void __init of_selftest_check_phandles(void)
203 {
204 	struct device_node *np;
205 	struct node_hash *nh;
206 	struct hlist_node *tmp;
207 	int i, dup_count = 0, phandle_count = 0;
208 
209 	for_each_of_allnodes(np) {
210 		if (!np->phandle)
211 			continue;
212 
213 		hash_for_each_possible(phandle_ht, nh, node, np->phandle) {
214 			if (nh->np->phandle == np->phandle) {
215 				pr_info("Duplicate phandle! %i used by %s and %s\n",
216 					np->phandle, nh->np->full_name, np->full_name);
217 				dup_count++;
218 				break;
219 			}
220 		}
221 
222 		nh = kzalloc(sizeof(*nh), GFP_KERNEL);
223 		if (WARN_ON(!nh))
224 			return;
225 
226 		nh->np = np;
227 		hash_add(phandle_ht, &nh->node, np->phandle);
228 		phandle_count++;
229 	}
230 	selftest(dup_count == 0, "Found %i duplicates in %i phandles\n",
231 		 dup_count, phandle_count);
232 
233 	/* Clean up */
234 	hash_for_each_safe(phandle_ht, i, tmp, nh, node) {
235 		hash_del(&nh->node);
236 		kfree(nh);
237 	}
238 }
239 
of_selftest_parse_phandle_with_args(void)240 static void __init of_selftest_parse_phandle_with_args(void)
241 {
242 	struct device_node *np;
243 	struct of_phandle_args args;
244 	int i, rc;
245 
246 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
247 	if (!np) {
248 		pr_err("missing testcase data\n");
249 		return;
250 	}
251 
252 	rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
253 	selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
254 
255 	for (i = 0; i < 8; i++) {
256 		bool passed = true;
257 		rc = of_parse_phandle_with_args(np, "phandle-list",
258 						"#phandle-cells", i, &args);
259 
260 		/* Test the values from tests-phandle.dtsi */
261 		switch (i) {
262 		case 0:
263 			passed &= !rc;
264 			passed &= (args.args_count == 1);
265 			passed &= (args.args[0] == (i + 1));
266 			break;
267 		case 1:
268 			passed &= !rc;
269 			passed &= (args.args_count == 2);
270 			passed &= (args.args[0] == (i + 1));
271 			passed &= (args.args[1] == 0);
272 			break;
273 		case 2:
274 			passed &= (rc == -ENOENT);
275 			break;
276 		case 3:
277 			passed &= !rc;
278 			passed &= (args.args_count == 3);
279 			passed &= (args.args[0] == (i + 1));
280 			passed &= (args.args[1] == 4);
281 			passed &= (args.args[2] == 3);
282 			break;
283 		case 4:
284 			passed &= !rc;
285 			passed &= (args.args_count == 2);
286 			passed &= (args.args[0] == (i + 1));
287 			passed &= (args.args[1] == 100);
288 			break;
289 		case 5:
290 			passed &= !rc;
291 			passed &= (args.args_count == 0);
292 			break;
293 		case 6:
294 			passed &= !rc;
295 			passed &= (args.args_count == 1);
296 			passed &= (args.args[0] == (i + 1));
297 			break;
298 		case 7:
299 			passed &= (rc == -ENOENT);
300 			break;
301 		default:
302 			passed = false;
303 		}
304 
305 		selftest(passed, "index %i - data error on node %s rc=%i\n",
306 			 i, args.np->full_name, rc);
307 	}
308 
309 	/* Check for missing list property */
310 	rc = of_parse_phandle_with_args(np, "phandle-list-missing",
311 					"#phandle-cells", 0, &args);
312 	selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
313 	rc = of_count_phandle_with_args(np, "phandle-list-missing",
314 					"#phandle-cells");
315 	selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
316 
317 	/* Check for missing cells property */
318 	rc = of_parse_phandle_with_args(np, "phandle-list",
319 					"#phandle-cells-missing", 0, &args);
320 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
321 	rc = of_count_phandle_with_args(np, "phandle-list",
322 					"#phandle-cells-missing");
323 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
324 
325 	/* Check for bad phandle in list */
326 	rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
327 					"#phandle-cells", 0, &args);
328 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
329 	rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle",
330 					"#phandle-cells");
331 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
332 
333 	/* Check for incorrectly formed argument list */
334 	rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
335 					"#phandle-cells", 1, &args);
336 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
337 	rc = of_count_phandle_with_args(np, "phandle-list-bad-args",
338 					"#phandle-cells");
339 	selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
340 }
341 
of_selftest_property_string(void)342 static void __init of_selftest_property_string(void)
343 {
344 	const char *strings[4];
345 	struct device_node *np;
346 	int rc;
347 
348 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
349 	if (!np) {
350 		pr_err("No testcase data in device tree\n");
351 		return;
352 	}
353 
354 	rc = of_property_match_string(np, "phandle-list-names", "first");
355 	selftest(rc == 0, "first expected:0 got:%i\n", rc);
356 	rc = of_property_match_string(np, "phandle-list-names", "second");
357 	selftest(rc == 1, "second expected:0 got:%i\n", rc);
358 	rc = of_property_match_string(np, "phandle-list-names", "third");
359 	selftest(rc == 2, "third expected:0 got:%i\n", rc);
360 	rc = of_property_match_string(np, "phandle-list-names", "fourth");
361 	selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);
362 	rc = of_property_match_string(np, "missing-property", "blah");
363 	selftest(rc == -EINVAL, "missing property; rc=%i\n", rc);
364 	rc = of_property_match_string(np, "empty-property", "blah");
365 	selftest(rc == -ENODATA, "empty property; rc=%i\n", rc);
366 	rc = of_property_match_string(np, "unterminated-string", "blah");
367 	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
368 
369 	/* of_property_count_strings() tests */
370 	rc = of_property_count_strings(np, "string-property");
371 	selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
372 	rc = of_property_count_strings(np, "phandle-list-names");
373 	selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
374 	rc = of_property_count_strings(np, "unterminated-string");
375 	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
376 	rc = of_property_count_strings(np, "unterminated-string-list");
377 	selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
378 
379 	/* of_property_read_string_index() tests */
380 	rc = of_property_read_string_index(np, "string-property", 0, strings);
381 	selftest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc);
382 	strings[0] = NULL;
383 	rc = of_property_read_string_index(np, "string-property", 1, strings);
384 	selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
385 	rc = of_property_read_string_index(np, "phandle-list-names", 0, strings);
386 	selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
387 	rc = of_property_read_string_index(np, "phandle-list-names", 1, strings);
388 	selftest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc);
389 	rc = of_property_read_string_index(np, "phandle-list-names", 2, strings);
390 	selftest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc);
391 	strings[0] = NULL;
392 	rc = of_property_read_string_index(np, "phandle-list-names", 3, strings);
393 	selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
394 	strings[0] = NULL;
395 	rc = of_property_read_string_index(np, "unterminated-string", 0, strings);
396 	selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
397 	rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings);
398 	selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
399 	strings[0] = NULL;
400 	rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */
401 	selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
402 	strings[1] = NULL;
403 
404 	/* of_property_read_string_array() tests */
405 	rc = of_property_read_string_array(np, "string-property", strings, 4);
406 	selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
407 	rc = of_property_read_string_array(np, "phandle-list-names", strings, 4);
408 	selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
409 	rc = of_property_read_string_array(np, "unterminated-string", strings, 4);
410 	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
411 	/* -- An incorrectly formed string should cause a failure */
412 	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4);
413 	selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
414 	/* -- parsing the correctly formed strings should still work: */
415 	strings[2] = NULL;
416 	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2);
417 	selftest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc);
418 	strings[1] = NULL;
419 	rc = of_property_read_string_array(np, "phandle-list-names", strings, 1);
420 	selftest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]);
421 }
422 
423 #define propcmp(p1, p2) (((p1)->length == (p2)->length) && \
424 			(p1)->value && (p2)->value && \
425 			!memcmp((p1)->value, (p2)->value, (p1)->length) && \
426 			!strcmp((p1)->name, (p2)->name))
of_selftest_property_copy(void)427 static void __init of_selftest_property_copy(void)
428 {
429 #ifdef CONFIG_OF_DYNAMIC
430 	struct property p1 = { .name = "p1", .length = 0, .value = "" };
431 	struct property p2 = { .name = "p2", .length = 5, .value = "abcd" };
432 	struct property *new;
433 
434 	new = __of_prop_dup(&p1, GFP_KERNEL);
435 	selftest(new && propcmp(&p1, new), "empty property didn't copy correctly\n");
436 	kfree(new->value);
437 	kfree(new->name);
438 	kfree(new);
439 
440 	new = __of_prop_dup(&p2, GFP_KERNEL);
441 	selftest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n");
442 	kfree(new->value);
443 	kfree(new->name);
444 	kfree(new);
445 #endif
446 }
447 
of_selftest_changeset(void)448 static void __init of_selftest_changeset(void)
449 {
450 #ifdef CONFIG_OF_DYNAMIC
451 	struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" };
452 	struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };
453 	struct property *ppremove;
454 	struct device_node *n1, *n2, *n21, *nremove, *parent;
455 	struct of_changeset chgset;
456 
457 	of_changeset_init(&chgset);
458 	n1 = __of_node_alloc("/testcase-data/changeset/n1", GFP_KERNEL);
459 	selftest(n1, "testcase setup failure\n");
460 	n2 = __of_node_alloc("/testcase-data/changeset/n2", GFP_KERNEL);
461 	selftest(n2, "testcase setup failure\n");
462 	n21 = __of_node_alloc("/testcase-data/changeset/n2/n21", GFP_KERNEL);
463 	selftest(n21, "testcase setup failure %p\n", n21);
464 	nremove = of_find_node_by_path("/testcase-data/changeset/node-remove");
465 	selftest(nremove, "testcase setup failure\n");
466 	ppadd = __of_prop_dup(&padd, GFP_KERNEL);
467 	selftest(ppadd, "testcase setup failure\n");
468 	ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);
469 	selftest(ppupdate, "testcase setup failure\n");
470 	parent = nremove->parent;
471 	n1->parent = parent;
472 	n2->parent = parent;
473 	n21->parent = n2;
474 	n2->child = n21;
475 	ppremove = of_find_property(parent, "prop-remove", NULL);
476 	selftest(ppremove, "failed to find removal prop");
477 
478 	of_changeset_init(&chgset);
479 	selftest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");
480 	selftest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");
481 	selftest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");
482 	selftest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");
483 	selftest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n");
484 	selftest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
485 	selftest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
486 	mutex_lock(&of_mutex);
487 	selftest(!of_changeset_apply(&chgset), "apply failed\n");
488 	mutex_unlock(&of_mutex);
489 
490 	mutex_lock(&of_mutex);
491 	selftest(!of_changeset_revert(&chgset), "revert failed\n");
492 	mutex_unlock(&of_mutex);
493 
494 	of_changeset_destroy(&chgset);
495 #endif
496 }
497 
of_selftest_parse_interrupts(void)498 static void __init of_selftest_parse_interrupts(void)
499 {
500 	struct device_node *np;
501 	struct of_phandle_args args;
502 	int i, rc;
503 
504 	np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");
505 	if (!np) {
506 		pr_err("missing testcase data\n");
507 		return;
508 	}
509 
510 	for (i = 0; i < 4; i++) {
511 		bool passed = true;
512 		args.args_count = 0;
513 		rc = of_irq_parse_one(np, i, &args);
514 
515 		passed &= !rc;
516 		passed &= (args.args_count == 1);
517 		passed &= (args.args[0] == (i + 1));
518 
519 		selftest(passed, "index %i - data error on node %s rc=%i\n",
520 			 i, args.np->full_name, rc);
521 	}
522 	of_node_put(np);
523 
524 	np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");
525 	if (!np) {
526 		pr_err("missing testcase data\n");
527 		return;
528 	}
529 
530 	for (i = 0; i < 4; i++) {
531 		bool passed = true;
532 		args.args_count = 0;
533 		rc = of_irq_parse_one(np, i, &args);
534 
535 		/* Test the values from tests-phandle.dtsi */
536 		switch (i) {
537 		case 0:
538 			passed &= !rc;
539 			passed &= (args.args_count == 1);
540 			passed &= (args.args[0] == 9);
541 			break;
542 		case 1:
543 			passed &= !rc;
544 			passed &= (args.args_count == 3);
545 			passed &= (args.args[0] == 10);
546 			passed &= (args.args[1] == 11);
547 			passed &= (args.args[2] == 12);
548 			break;
549 		case 2:
550 			passed &= !rc;
551 			passed &= (args.args_count == 2);
552 			passed &= (args.args[0] == 13);
553 			passed &= (args.args[1] == 14);
554 			break;
555 		case 3:
556 			passed &= !rc;
557 			passed &= (args.args_count == 2);
558 			passed &= (args.args[0] == 15);
559 			passed &= (args.args[1] == 16);
560 			break;
561 		default:
562 			passed = false;
563 		}
564 		selftest(passed, "index %i - data error on node %s rc=%i\n",
565 			 i, args.np->full_name, rc);
566 	}
567 	of_node_put(np);
568 }
569 
of_selftest_parse_interrupts_extended(void)570 static void __init of_selftest_parse_interrupts_extended(void)
571 {
572 	struct device_node *np;
573 	struct of_phandle_args args;
574 	int i, rc;
575 
576 	np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
577 	if (!np) {
578 		pr_err("missing testcase data\n");
579 		return;
580 	}
581 
582 	for (i = 0; i < 7; i++) {
583 		bool passed = true;
584 		rc = of_irq_parse_one(np, i, &args);
585 
586 		/* Test the values from tests-phandle.dtsi */
587 		switch (i) {
588 		case 0:
589 			passed &= !rc;
590 			passed &= (args.args_count == 1);
591 			passed &= (args.args[0] == 1);
592 			break;
593 		case 1:
594 			passed &= !rc;
595 			passed &= (args.args_count == 3);
596 			passed &= (args.args[0] == 2);
597 			passed &= (args.args[1] == 3);
598 			passed &= (args.args[2] == 4);
599 			break;
600 		case 2:
601 			passed &= !rc;
602 			passed &= (args.args_count == 2);
603 			passed &= (args.args[0] == 5);
604 			passed &= (args.args[1] == 6);
605 			break;
606 		case 3:
607 			passed &= !rc;
608 			passed &= (args.args_count == 1);
609 			passed &= (args.args[0] == 9);
610 			break;
611 		case 4:
612 			passed &= !rc;
613 			passed &= (args.args_count == 3);
614 			passed &= (args.args[0] == 10);
615 			passed &= (args.args[1] == 11);
616 			passed &= (args.args[2] == 12);
617 			break;
618 		case 5:
619 			passed &= !rc;
620 			passed &= (args.args_count == 2);
621 			passed &= (args.args[0] == 13);
622 			passed &= (args.args[1] == 14);
623 			break;
624 		case 6:
625 			passed &= !rc;
626 			passed &= (args.args_count == 1);
627 			passed &= (args.args[0] == 15);
628 			break;
629 		default:
630 			passed = false;
631 		}
632 
633 		selftest(passed, "index %i - data error on node %s rc=%i\n",
634 			 i, args.np->full_name, rc);
635 	}
636 	of_node_put(np);
637 }
638 
639 static struct of_device_id match_node_table[] = {
640 	{ .data = "A", .name = "name0", }, /* Name alone is lowest priority */
641 	{ .data = "B", .type = "type1", }, /* followed by type alone */
642 
643 	{ .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */
644 	{ .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */
645 	{ .data = "Cc", .name = "name2", .type = "type2", },
646 
647 	{ .data = "E", .compatible = "compat3" },
648 	{ .data = "G", .compatible = "compat2", },
649 	{ .data = "H", .compatible = "compat2", .name = "name5", },
650 	{ .data = "I", .compatible = "compat2", .type = "type1", },
651 	{ .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },
652 	{ .data = "K", .compatible = "compat2", .name = "name9", },
653 	{}
654 };
655 
656 static struct {
657 	const char *path;
658 	const char *data;
659 } match_node_tests[] = {
660 	{ .path = "/testcase-data/match-node/name0", .data = "A", },
661 	{ .path = "/testcase-data/match-node/name1", .data = "B", },
662 	{ .path = "/testcase-data/match-node/a/name2", .data = "Ca", },
663 	{ .path = "/testcase-data/match-node/b/name2", .data = "Cb", },
664 	{ .path = "/testcase-data/match-node/c/name2", .data = "Cc", },
665 	{ .path = "/testcase-data/match-node/name3", .data = "E", },
666 	{ .path = "/testcase-data/match-node/name4", .data = "G", },
667 	{ .path = "/testcase-data/match-node/name5", .data = "H", },
668 	{ .path = "/testcase-data/match-node/name6", .data = "G", },
669 	{ .path = "/testcase-data/match-node/name7", .data = "I", },
670 	{ .path = "/testcase-data/match-node/name8", .data = "J", },
671 	{ .path = "/testcase-data/match-node/name9", .data = "K", },
672 };
673 
of_selftest_match_node(void)674 static void __init of_selftest_match_node(void)
675 {
676 	struct device_node *np;
677 	const struct of_device_id *match;
678 	int i;
679 
680 	for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {
681 		np = of_find_node_by_path(match_node_tests[i].path);
682 		if (!np) {
683 			selftest(0, "missing testcase node %s\n",
684 				match_node_tests[i].path);
685 			continue;
686 		}
687 
688 		match = of_match_node(match_node_table, np);
689 		if (!match) {
690 			selftest(0, "%s didn't match anything\n",
691 				match_node_tests[i].path);
692 			continue;
693 		}
694 
695 		if (strcmp(match->data, match_node_tests[i].data) != 0) {
696 			selftest(0, "%s got wrong match. expected %s, got %s\n",
697 				match_node_tests[i].path, match_node_tests[i].data,
698 				(const char *)match->data);
699 			continue;
700 		}
701 		selftest(1, "passed");
702 	}
703 }
704 
of_selftest_platform_populate(void)705 static void __init of_selftest_platform_populate(void)
706 {
707 	int irq;
708 	struct device_node *np, *child;
709 	struct platform_device *pdev;
710 	struct of_device_id match[] = {
711 		{ .compatible = "test-device", },
712 		{}
713 	};
714 
715 	np = of_find_node_by_path("/testcase-data");
716 	of_platform_populate(np, of_default_bus_match_table, NULL, NULL);
717 
718 	/* Test that a missing irq domain returns -EPROBE_DEFER */
719 	np = of_find_node_by_path("/testcase-data/testcase-device1");
720 	pdev = of_find_device_by_node(np);
721 	selftest(pdev, "device 1 creation failed\n");
722 
723 	irq = platform_get_irq(pdev, 0);
724 	selftest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq);
725 
726 	/* Test that a parsing failure does not return -EPROBE_DEFER */
727 	np = of_find_node_by_path("/testcase-data/testcase-device2");
728 	pdev = of_find_device_by_node(np);
729 	selftest(pdev, "device 2 creation failed\n");
730 	irq = platform_get_irq(pdev, 0);
731 	selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq);
732 
733 	np = of_find_node_by_path("/testcase-data/platform-tests");
734 	if (!np) {
735 		pr_err("No testcase data in device tree\n");
736 		return;
737 	}
738 
739 	for_each_child_of_node(np, child) {
740 		struct device_node *grandchild;
741 		of_platform_populate(child, match, NULL, NULL);
742 		for_each_child_of_node(child, grandchild)
743 			selftest(of_find_device_by_node(grandchild),
744 				 "Could not create device for node '%s'\n",
745 				 grandchild->name);
746 	}
747 }
748 
749 /**
750  *	update_node_properties - adds the properties
751  *	of np into dup node (present in live tree) and
752  *	updates parent of children of np to dup.
753  *
754  *	@np:	node already present in live tree
755  *	@dup:	node present in live tree to be updated
756  */
update_node_properties(struct device_node * np,struct device_node * dup)757 static void update_node_properties(struct device_node *np,
758 					struct device_node *dup)
759 {
760 	struct property *prop;
761 	struct device_node *child;
762 
763 	for_each_property_of_node(np, prop)
764 		of_add_property(dup, prop);
765 
766 	for_each_child_of_node(np, child)
767 		child->parent = dup;
768 }
769 
770 /**
771  *	attach_node_and_children - attaches nodes
772  *	and its children to live tree
773  *
774  *	@np:	Node to attach to live tree
775  */
attach_node_and_children(struct device_node * np)776 static int attach_node_and_children(struct device_node *np)
777 {
778 	struct device_node *next, *root = np, *dup;
779 
780 	/* skip root node */
781 	np = np->child;
782 	/* storing a copy in temporary node */
783 	dup = np;
784 
785 	while (dup) {
786 		if (WARN_ON(last_node_index >= NO_OF_NODES))
787 			return -EINVAL;
788 		nodes[last_node_index++] = dup;
789 		dup = dup->sibling;
790 	}
791 	dup = NULL;
792 
793 	while (np) {
794 		next = np->allnext;
795 		dup = of_find_node_by_path(np->full_name);
796 		if (dup)
797 			update_node_properties(np, dup);
798 		else {
799 			np->child = NULL;
800 			if (np->parent == root)
801 				np->parent = of_allnodes;
802 			of_attach_node(np);
803 		}
804 		np = next;
805 	}
806 
807 	return 0;
808 }
809 
810 /**
811  *	selftest_data_add - Reads, copies data from
812  *	linked tree and attaches it to the live tree
813  */
selftest_data_add(void)814 static int __init selftest_data_add(void)
815 {
816 	void *selftest_data;
817 	struct device_node *selftest_data_node, *np;
818 	extern uint8_t __dtb_testcases_begin[];
819 	extern uint8_t __dtb_testcases_end[];
820 	const int size = __dtb_testcases_end - __dtb_testcases_begin;
821 	int rc;
822 
823 	if (!size) {
824 		pr_warn("%s: No testcase data to attach; not running tests\n",
825 			__func__);
826 		return -ENODATA;
827 	}
828 
829 	/* creating copy */
830 	selftest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL);
831 
832 	if (!selftest_data) {
833 		pr_warn("%s: Failed to allocate memory for selftest_data; "
834 			"not running tests\n", __func__);
835 		return -ENOMEM;
836 	}
837 	of_fdt_unflatten_tree(selftest_data, &selftest_data_node);
838 	if (!selftest_data_node) {
839 		pr_warn("%s: No tree to attach; not running tests\n", __func__);
840 		return -ENODATA;
841 	}
842 	of_node_set_flag(selftest_data_node, OF_DETACHED);
843 	rc = of_resolve_phandles(selftest_data_node);
844 	if (rc) {
845 		pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
846 		return -EINVAL;
847 	}
848 
849 	if (!of_allnodes) {
850 		/* enabling flag for removing nodes */
851 		selftest_live_tree = true;
852 		of_allnodes = selftest_data_node;
853 
854 		for_each_of_allnodes(np)
855 			__of_attach_node_sysfs(np);
856 		of_aliases = of_find_node_by_path("/aliases");
857 		of_chosen = of_find_node_by_path("/chosen");
858 		return 0;
859 	}
860 
861 	/* attach the sub-tree to live tree */
862 	return attach_node_and_children(selftest_data_node);
863 }
864 
865 /**
866  *	detach_node_and_children - detaches node
867  *	and its children from live tree
868  *
869  *	@np:	Node to detach from live tree
870  */
detach_node_and_children(struct device_node * np)871 static void detach_node_and_children(struct device_node *np)
872 {
873 	while (np->child)
874 		detach_node_and_children(np->child);
875 	of_detach_node(np);
876 }
877 
878 /**
879  *	selftest_data_remove - removes the selftest data
880  *	nodes from the live tree
881  */
selftest_data_remove(void)882 static void selftest_data_remove(void)
883 {
884 	struct device_node *np;
885 	struct property *prop;
886 
887 	if (selftest_live_tree) {
888 		of_node_put(of_aliases);
889 		of_node_put(of_chosen);
890 		of_aliases = NULL;
891 		of_chosen = NULL;
892 		for_each_child_of_node(of_allnodes, np)
893 			detach_node_and_children(np);
894 		__of_detach_node_sysfs(of_allnodes);
895 		of_allnodes = NULL;
896 		return;
897 	}
898 
899 	while (last_node_index-- > 0) {
900 		if (nodes[last_node_index]) {
901 			np = of_find_node_by_path(nodes[last_node_index]->full_name);
902 			if (np == nodes[last_node_index]) {
903 				if (of_aliases == np) {
904 					of_node_put(of_aliases);
905 					of_aliases = NULL;
906 				}
907 				detach_node_and_children(np);
908 			} else {
909 				for_each_property_of_node(np, prop) {
910 					if (strcmp(prop->name, "testcase-alias") == 0)
911 						of_remove_property(np, prop);
912 				}
913 			}
914 		}
915 	}
916 }
917 
of_selftest(void)918 static int __init of_selftest(void)
919 {
920 	struct device_node *np;
921 	int res;
922 
923 	/* adding data for selftest */
924 	res = selftest_data_add();
925 	if (res)
926 		return res;
927 	if (!of_aliases)
928 		of_aliases = of_find_node_by_path("/aliases");
929 
930 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
931 	if (!np) {
932 		pr_info("No testcase data in device tree; not running tests\n");
933 		return 0;
934 	}
935 	of_node_put(np);
936 
937 	pr_info("start of selftest - you will see error messages\n");
938 	of_selftest_check_tree_linkage();
939 	of_selftest_check_phandles();
940 	of_selftest_find_node_by_name();
941 	of_selftest_dynamic();
942 	of_selftest_parse_phandle_with_args();
943 	of_selftest_property_string();
944 	of_selftest_property_copy();
945 	of_selftest_changeset();
946 	of_selftest_parse_interrupts();
947 	of_selftest_parse_interrupts_extended();
948 	of_selftest_match_node();
949 	of_selftest_platform_populate();
950 
951 	/* removing selftest data from live tree */
952 	selftest_data_remove();
953 
954 	/* Double check linkage after removing testcase data */
955 	of_selftest_check_tree_linkage();
956 
957 	pr_info("end of selftest - %i passed, %i failed\n",
958 		selftest_results.passed, selftest_results.failed);
959 
960 	return 0;
961 }
962 late_initcall(of_selftest);
963