blob: 252a7eda8d6a91404a1e21e6bcb654c968e0de78 [file] [log] [blame]
Grant Likely53a42092011-12-12 09:25:57 -07001/*
2 * Self tests for device tree subsystem
3 */
4
Grant Likelycabb7d52013-02-12 21:19:37 +00005#define pr_fmt(fmt) "### dt-test ### " fmt
Grant Likely53a42092011-12-12 09:25:57 -07006
7#include <linux/clk.h>
8#include <linux/err.h>
9#include <linux/errno.h>
10#include <linux/module.h>
11#include <linux/of.h>
Gaurav Minochaae9304c2014-07-16 23:09:39 -070012#include <linux/of_fdt.h>
Grant Likelya9f10ca2013-10-11 22:04:23 +010013#include <linux/of_irq.h>
Rob Herring82c0f582014-04-23 17:57:40 -050014#include <linux/of_platform.h>
Grant Likely53a42092011-12-12 09:25:57 -070015#include <linux/list.h>
16#include <linux/mutex.h>
17#include <linux/slab.h>
18#include <linux/device.h>
19
Pantelis Antoniou69843392014-07-04 19:58:47 +030020#include "of_private.h"
21
Grant Likelya9f10ca2013-10-11 22:04:23 +010022static struct selftest_results {
23 int passed;
24 int failed;
25} selftest_results;
26
Gaurav Minochaae9304c2014-07-16 23:09:39 -070027#define NO_OF_NODES 2
28static struct device_node *nodes[NO_OF_NODES];
29static int last_node_index;
Gaurav Minochab951f9d2014-07-26 12:48:50 -070030static bool selftest_live_tree;
Gaurav Minochaae9304c2014-07-16 23:09:39 -070031
Grant Likely53a42092011-12-12 09:25:57 -070032#define selftest(result, fmt, ...) { \
Grant Likelycabb7d52013-02-12 21:19:37 +000033 if (!(result)) { \
Grant Likelya9f10ca2013-10-11 22:04:23 +010034 selftest_results.failed++; \
35 pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
Grant Likelycabb7d52013-02-12 21:19:37 +000036 } else { \
Grant Likelya9f10ca2013-10-11 22:04:23 +010037 selftest_results.passed++; \
38 pr_debug("pass %s():%i\n", __func__, __LINE__); \
Grant Likelycabb7d52013-02-12 21:19:37 +000039 } \
Grant Likely53a42092011-12-12 09:25:57 -070040}
41
Grant Likelyae91ff72014-03-14 13:53:10 +000042static void __init of_selftest_find_node_by_name(void)
43{
44 struct device_node *np;
45
46 np = of_find_node_by_path("/testcase-data");
47 selftest(np && !strcmp("/testcase-data", np->full_name),
48 "find /testcase-data failed\n");
49 of_node_put(np);
50
51 /* Test if trailing '/' works */
52 np = of_find_node_by_path("/testcase-data/");
53 selftest(!np, "trailing '/' on /testcase-data/ should fail\n");
54
55 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
56 selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
57 "find /testcase-data/phandle-tests/consumer-a failed\n");
58 of_node_put(np);
59
60 np = of_find_node_by_path("testcase-alias");
61 selftest(np && !strcmp("/testcase-data", np->full_name),
62 "find testcase-alias failed\n");
63 of_node_put(np);
64
65 /* Test if trailing '/' works on aliases */
66 np = of_find_node_by_path("testcase-alias/");
67 selftest(!np, "trailing '/' on testcase-alias/ should fail\n");
68
69 np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
70 selftest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name),
71 "find testcase-alias/phandle-tests/consumer-a failed\n");
72 of_node_put(np);
73
74 np = of_find_node_by_path("/testcase-data/missing-path");
75 selftest(!np, "non-existent path returned node %s\n", np->full_name);
76 of_node_put(np);
77
78 np = of_find_node_by_path("missing-alias");
79 selftest(!np, "non-existent alias returned node %s\n", np->full_name);
80 of_node_put(np);
81
82 np = of_find_node_by_path("testcase-alias/missing-path");
83 selftest(!np, "non-existent alias with relative path returned node %s\n", np->full_name);
84 of_node_put(np);
85}
86
Grant Likely7e66c5c2013-11-15 17:19:09 +000087static void __init of_selftest_dynamic(void)
88{
89 struct device_node *np;
90 struct property *prop;
91
92 np = of_find_node_by_path("/testcase-data");
93 if (!np) {
94 pr_err("missing testcase data\n");
95 return;
96 }
97
98 /* Array of 4 properties for the purpose of testing */
99 prop = kzalloc(sizeof(*prop) * 4, GFP_KERNEL);
100 if (!prop) {
101 selftest(0, "kzalloc() failed\n");
102 return;
103 }
104
105 /* Add a new property - should pass*/
106 prop->name = "new-property";
107 prop->value = "new-property-data";
108 prop->length = strlen(prop->value);
109 selftest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
110
111 /* Try to add an existing property - should fail */
112 prop++;
113 prop->name = "new-property";
114 prop->value = "new-property-data-should-fail";
115 prop->length = strlen(prop->value);
116 selftest(of_add_property(np, prop) != 0,
117 "Adding an existing property should have failed\n");
118
119 /* Try to modify an existing property - should pass */
120 prop->value = "modify-property-data-should-pass";
121 prop->length = strlen(prop->value);
122 selftest(of_update_property(np, prop) == 0,
123 "Updating an existing property should have passed\n");
124
125 /* Try to modify non-existent property - should pass*/
126 prop++;
127 prop->name = "modify-property";
128 prop->value = "modify-missing-property-data-should-pass";
129 prop->length = strlen(prop->value);
130 selftest(of_update_property(np, prop) == 0,
131 "Updating a missing property should have passed\n");
132
133 /* Remove property - should pass */
134 selftest(of_remove_property(np, prop) == 0,
135 "Removing a property should have passed\n");
136
137 /* Adding very large property - should pass */
138 prop++;
139 prop->name = "large-property-PAGE_SIZEx8";
140 prop->length = PAGE_SIZE * 8;
141 prop->value = kzalloc(prop->length, GFP_KERNEL);
142 selftest(prop->value != NULL, "Unable to allocate large buffer\n");
143 if (prop->value)
144 selftest(of_add_property(np, prop) == 0,
145 "Adding a large property should have passed\n");
146}
147
Grant Likelyf2051d62014-10-01 17:40:22 +0100148static int __init of_selftest_check_node_linkage(struct device_node *np)
149{
150 struct device_node *child, *allnext_index = np;
151 int count = 0, rc;
152
153 for_each_child_of_node(np, child) {
154 if (child->parent != np) {
155 pr_err("Child node %s links to wrong parent %s\n",
156 child->name, np->name);
157 return -EINVAL;
158 }
159
160 while (allnext_index && allnext_index != child)
161 allnext_index = allnext_index->allnext;
162 if (allnext_index != child) {
163 pr_err("Node %s is ordered differently in sibling and allnode lists\n",
164 child->name);
165 return -EINVAL;
166 }
167
168 rc = of_selftest_check_node_linkage(child);
169 if (rc < 0)
170 return rc;
171 count += rc;
172 }
173
174 return count + 1;
175}
176
177static void __init of_selftest_check_tree_linkage(void)
178{
179 struct device_node *np;
180 int allnode_count = 0, child_count;
181
182 if (!of_allnodes)
183 return;
184
185 for_each_of_allnodes(np)
186 allnode_count++;
187 child_count = of_selftest_check_node_linkage(of_allnodes);
188
189 selftest(child_count > 0, "Device node data structure is corrupted\n");
190 selftest(child_count == allnode_count, "allnodes list size (%i) doesn't match"
191 "sibling lists size (%i)\n", allnode_count, child_count);
192 pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count);
193}
194
Grant Likely53a42092011-12-12 09:25:57 -0700195static void __init of_selftest_parse_phandle_with_args(void)
196{
197 struct device_node *np;
198 struct of_phandle_args args;
Grant Likelycabb7d52013-02-12 21:19:37 +0000199 int i, rc;
Grant Likely53a42092011-12-12 09:25:57 -0700200
Grant Likely53a42092011-12-12 09:25:57 -0700201 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
202 if (!np) {
203 pr_err("missing testcase data\n");
204 return;
205 }
206
Grant Likelybd69f732013-02-10 22:57:21 +0000207 rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
208 selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
209
Grant Likelyf7f951c2013-02-12 17:41:22 +0000210 for (i = 0; i < 8; i++) {
Grant Likely53a42092011-12-12 09:25:57 -0700211 bool passed = true;
212 rc = of_parse_phandle_with_args(np, "phandle-list",
213 "#phandle-cells", i, &args);
214
215 /* Test the values from tests-phandle.dtsi */
216 switch (i) {
217 case 0:
218 passed &= !rc;
219 passed &= (args.args_count == 1);
220 passed &= (args.args[0] == (i + 1));
221 break;
222 case 1:
223 passed &= !rc;
224 passed &= (args.args_count == 2);
225 passed &= (args.args[0] == (i + 1));
226 passed &= (args.args[1] == 0);
227 break;
228 case 2:
229 passed &= (rc == -ENOENT);
230 break;
231 case 3:
232 passed &= !rc;
233 passed &= (args.args_count == 3);
234 passed &= (args.args[0] == (i + 1));
235 passed &= (args.args[1] == 4);
236 passed &= (args.args[2] == 3);
237 break;
238 case 4:
239 passed &= !rc;
240 passed &= (args.args_count == 2);
241 passed &= (args.args[0] == (i + 1));
242 passed &= (args.args[1] == 100);
243 break;
244 case 5:
245 passed &= !rc;
246 passed &= (args.args_count == 0);
247 break;
248 case 6:
249 passed &= !rc;
250 passed &= (args.args_count == 1);
251 passed &= (args.args[0] == (i + 1));
252 break;
253 case 7:
Grant Likelycabb7d52013-02-12 21:19:37 +0000254 passed &= (rc == -ENOENT);
Grant Likely53a42092011-12-12 09:25:57 -0700255 break;
256 default:
257 passed = false;
258 }
259
Grant Likelycabb7d52013-02-12 21:19:37 +0000260 selftest(passed, "index %i - data error on node %s rc=%i\n",
261 i, args.np->full_name, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700262 }
263
264 /* Check for missing list property */
265 rc = of_parse_phandle_with_args(np, "phandle-list-missing",
266 "#phandle-cells", 0, &args);
Grant Likelycabb7d52013-02-12 21:19:37 +0000267 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000268 rc = of_count_phandle_with_args(np, "phandle-list-missing",
269 "#phandle-cells");
270 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700271
272 /* Check for missing cells property */
273 rc = of_parse_phandle_with_args(np, "phandle-list",
274 "#phandle-cells-missing", 0, &args);
Grant Likelycabb7d52013-02-12 21:19:37 +0000275 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000276 rc = of_count_phandle_with_args(np, "phandle-list",
277 "#phandle-cells-missing");
278 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700279
280 /* Check for bad phandle in list */
281 rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
282 "#phandle-cells", 0, &args);
Grant Likelycabb7d52013-02-12 21:19:37 +0000283 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000284 rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle",
285 "#phandle-cells");
286 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700287
288 /* Check for incorrectly formed argument list */
289 rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
290 "#phandle-cells", 1, &args);
Grant Likelycabb7d52013-02-12 21:19:37 +0000291 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likelybd69f732013-02-10 22:57:21 +0000292 rc = of_count_phandle_with_args(np, "phandle-list-bad-args",
293 "#phandle-cells");
294 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
Grant Likely53a42092011-12-12 09:25:57 -0700295}
296
Grant Likely7aff0fe2011-12-12 09:25:58 -0700297static void __init of_selftest_property_match_string(void)
298{
299 struct device_node *np;
300 int rc;
301
Grant Likely7aff0fe2011-12-12 09:25:58 -0700302 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
303 if (!np) {
304 pr_err("No testcase data in device tree\n");
305 return;
306 }
307
308 rc = of_property_match_string(np, "phandle-list-names", "first");
309 selftest(rc == 0, "first expected:0 got:%i\n", rc);
310 rc = of_property_match_string(np, "phandle-list-names", "second");
311 selftest(rc == 1, "second expected:0 got:%i\n", rc);
312 rc = of_property_match_string(np, "phandle-list-names", "third");
313 selftest(rc == 2, "third expected:0 got:%i\n", rc);
314 rc = of_property_match_string(np, "phandle-list-names", "fourth");
315 selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
316 rc = of_property_match_string(np, "missing-property", "blah");
317 selftest(rc == -EINVAL, "missing property; rc=%i", rc);
318 rc = of_property_match_string(np, "empty-property", "blah");
319 selftest(rc == -ENODATA, "empty property; rc=%i", rc);
320 rc = of_property_match_string(np, "unterminated-string", "blah");
321 selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
322}
323
Pantelis Antoniou69843392014-07-04 19:58:47 +0300324#define propcmp(p1, p2) (((p1)->length == (p2)->length) && \
325 (p1)->value && (p2)->value && \
326 !memcmp((p1)->value, (p2)->value, (p1)->length) && \
327 !strcmp((p1)->name, (p2)->name))
328static void __init of_selftest_property_copy(void)
329{
330#ifdef CONFIG_OF_DYNAMIC
331 struct property p1 = { .name = "p1", .length = 0, .value = "" };
332 struct property p2 = { .name = "p2", .length = 5, .value = "abcd" };
333 struct property *new;
334
335 new = __of_prop_dup(&p1, GFP_KERNEL);
336 selftest(new && propcmp(&p1, new), "empty property didn't copy correctly\n");
337 kfree(new->value);
338 kfree(new->name);
339 kfree(new);
340
341 new = __of_prop_dup(&p2, GFP_KERNEL);
342 selftest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n");
343 kfree(new->value);
344 kfree(new->name);
345 kfree(new);
346#endif
347}
348
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300349static void __init of_selftest_changeset(void)
350{
351#ifdef CONFIG_OF_DYNAMIC
352 struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" };
353 struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };
354 struct property *ppremove;
355 struct device_node *n1, *n2, *n21, *nremove, *parent;
356 struct of_changeset chgset;
357
358 of_changeset_init(&chgset);
359 n1 = __of_node_alloc("/testcase-data/changeset/n1", GFP_KERNEL);
360 selftest(n1, "testcase setup failure\n");
361 n2 = __of_node_alloc("/testcase-data/changeset/n2", GFP_KERNEL);
362 selftest(n2, "testcase setup failure\n");
363 n21 = __of_node_alloc("/testcase-data/changeset/n2/n21", GFP_KERNEL);
364 selftest(n21, "testcase setup failure %p\n", n21);
365 nremove = of_find_node_by_path("/testcase-data/changeset/node-remove");
366 selftest(nremove, "testcase setup failure\n");
367 ppadd = __of_prop_dup(&padd, GFP_KERNEL);
368 selftest(ppadd, "testcase setup failure\n");
369 ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);
370 selftest(ppupdate, "testcase setup failure\n");
371 parent = nremove->parent;
372 n1->parent = parent;
373 n2->parent = parent;
374 n21->parent = n2;
375 n2->child = n21;
376 ppremove = of_find_property(parent, "prop-remove", NULL);
377 selftest(ppremove, "failed to find removal prop");
378
379 of_changeset_init(&chgset);
380 selftest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");
381 selftest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");
382 selftest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");
383 selftest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");
384 selftest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n");
385 selftest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
386 selftest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
387 mutex_lock(&of_mutex);
388 selftest(!of_changeset_apply(&chgset), "apply failed\n");
389 mutex_unlock(&of_mutex);
390
391 mutex_lock(&of_mutex);
392 selftest(!of_changeset_revert(&chgset), "revert failed\n");
393 mutex_unlock(&of_mutex);
394
395 of_changeset_destroy(&chgset);
396#endif
397}
398
Grant Likelya9f10ca2013-10-11 22:04:23 +0100399static void __init of_selftest_parse_interrupts(void)
400{
401 struct device_node *np;
402 struct of_phandle_args args;
403 int i, rc;
404
405 np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");
406 if (!np) {
407 pr_err("missing testcase data\n");
408 return;
409 }
410
411 for (i = 0; i < 4; i++) {
412 bool passed = true;
413 args.args_count = 0;
414 rc = of_irq_parse_one(np, i, &args);
415
416 passed &= !rc;
417 passed &= (args.args_count == 1);
418 passed &= (args.args[0] == (i + 1));
419
420 selftest(passed, "index %i - data error on node %s rc=%i\n",
421 i, args.np->full_name, rc);
422 }
423 of_node_put(np);
424
425 np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");
426 if (!np) {
427 pr_err("missing testcase data\n");
428 return;
429 }
430
431 for (i = 0; i < 4; i++) {
432 bool passed = true;
433 args.args_count = 0;
434 rc = of_irq_parse_one(np, i, &args);
435
436 /* Test the values from tests-phandle.dtsi */
437 switch (i) {
438 case 0:
439 passed &= !rc;
440 passed &= (args.args_count == 1);
441 passed &= (args.args[0] == 9);
442 break;
443 case 1:
444 passed &= !rc;
445 passed &= (args.args_count == 3);
446 passed &= (args.args[0] == 10);
447 passed &= (args.args[1] == 11);
448 passed &= (args.args[2] == 12);
449 break;
450 case 2:
451 passed &= !rc;
452 passed &= (args.args_count == 2);
453 passed &= (args.args[0] == 13);
454 passed &= (args.args[1] == 14);
455 break;
456 case 3:
457 passed &= !rc;
458 passed &= (args.args_count == 2);
459 passed &= (args.args[0] == 15);
460 passed &= (args.args[1] == 16);
461 break;
462 default:
463 passed = false;
464 }
465 selftest(passed, "index %i - data error on node %s rc=%i\n",
466 i, args.np->full_name, rc);
467 }
468 of_node_put(np);
469}
470
Grant Likely79d97012013-09-19 16:47:37 -0500471static void __init of_selftest_parse_interrupts_extended(void)
472{
473 struct device_node *np;
474 struct of_phandle_args args;
475 int i, rc;
476
477 np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
478 if (!np) {
479 pr_err("missing testcase data\n");
480 return;
481 }
482
483 for (i = 0; i < 7; i++) {
484 bool passed = true;
485 rc = of_irq_parse_one(np, i, &args);
486
487 /* Test the values from tests-phandle.dtsi */
488 switch (i) {
489 case 0:
490 passed &= !rc;
491 passed &= (args.args_count == 1);
492 passed &= (args.args[0] == 1);
493 break;
494 case 1:
495 passed &= !rc;
496 passed &= (args.args_count == 3);
497 passed &= (args.args[0] == 2);
498 passed &= (args.args[1] == 3);
499 passed &= (args.args[2] == 4);
500 break;
501 case 2:
502 passed &= !rc;
503 passed &= (args.args_count == 2);
504 passed &= (args.args[0] == 5);
505 passed &= (args.args[1] == 6);
506 break;
507 case 3:
508 passed &= !rc;
509 passed &= (args.args_count == 1);
510 passed &= (args.args[0] == 9);
511 break;
512 case 4:
513 passed &= !rc;
514 passed &= (args.args_count == 3);
515 passed &= (args.args[0] == 10);
516 passed &= (args.args[1] == 11);
517 passed &= (args.args[2] == 12);
518 break;
519 case 5:
520 passed &= !rc;
521 passed &= (args.args_count == 2);
522 passed &= (args.args[0] == 13);
523 passed &= (args.args[1] == 14);
524 break;
525 case 6:
526 passed &= !rc;
527 passed &= (args.args_count == 1);
528 passed &= (args.args[0] == 15);
529 break;
530 default:
531 passed = false;
532 }
533
534 selftest(passed, "index %i - data error on node %s rc=%i\n",
535 i, args.np->full_name, rc);
536 }
537 of_node_put(np);
538}
539
Grant Likely1f42e5d2014-02-18 21:38:55 +0000540static struct of_device_id match_node_table[] = {
541 { .data = "A", .name = "name0", }, /* Name alone is lowest priority */
542 { .data = "B", .type = "type1", }, /* followed by type alone */
543
544 { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */
545 { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */
546 { .data = "Cc", .name = "name2", .type = "type2", },
547
548 { .data = "E", .compatible = "compat3" },
549 { .data = "G", .compatible = "compat2", },
550 { .data = "H", .compatible = "compat2", .name = "name5", },
551 { .data = "I", .compatible = "compat2", .type = "type1", },
552 { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },
553 { .data = "K", .compatible = "compat2", .name = "name9", },
554 {}
555};
556
557static struct {
558 const char *path;
559 const char *data;
560} match_node_tests[] = {
561 { .path = "/testcase-data/match-node/name0", .data = "A", },
562 { .path = "/testcase-data/match-node/name1", .data = "B", },
563 { .path = "/testcase-data/match-node/a/name2", .data = "Ca", },
564 { .path = "/testcase-data/match-node/b/name2", .data = "Cb", },
565 { .path = "/testcase-data/match-node/c/name2", .data = "Cc", },
566 { .path = "/testcase-data/match-node/name3", .data = "E", },
567 { .path = "/testcase-data/match-node/name4", .data = "G", },
568 { .path = "/testcase-data/match-node/name5", .data = "H", },
569 { .path = "/testcase-data/match-node/name6", .data = "G", },
570 { .path = "/testcase-data/match-node/name7", .data = "I", },
571 { .path = "/testcase-data/match-node/name8", .data = "J", },
572 { .path = "/testcase-data/match-node/name9", .data = "K", },
573};
574
575static void __init of_selftest_match_node(void)
576{
577 struct device_node *np;
578 const struct of_device_id *match;
579 int i;
580
581 for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {
582 np = of_find_node_by_path(match_node_tests[i].path);
583 if (!np) {
584 selftest(0, "missing testcase node %s\n",
585 match_node_tests[i].path);
586 continue;
587 }
588
589 match = of_match_node(match_node_table, np);
590 if (!match) {
591 selftest(0, "%s didn't match anything\n",
592 match_node_tests[i].path);
593 continue;
594 }
595
596 if (strcmp(match->data, match_node_tests[i].data) != 0) {
597 selftest(0, "%s got wrong match. expected %s, got %s\n",
598 match_node_tests[i].path, match_node_tests[i].data,
599 (const char *)match->data);
600 continue;
601 }
602 selftest(1, "passed");
603 }
604}
605
Rob Herring82c0f582014-04-23 17:57:40 -0500606static void __init of_selftest_platform_populate(void)
607{
608 int irq;
Rob Herringfb2caa52014-05-13 10:07:54 -0500609 struct device_node *np, *child;
Rob Herring82c0f582014-04-23 17:57:40 -0500610 struct platform_device *pdev;
Rob Herringfb2caa52014-05-13 10:07:54 -0500611 struct of_device_id match[] = {
612 { .compatible = "test-device", },
613 {}
614 };
Rob Herring82c0f582014-04-23 17:57:40 -0500615
616 np = of_find_node_by_path("/testcase-data");
617 of_platform_populate(np, of_default_bus_match_table, NULL, NULL);
618
619 /* Test that a missing irq domain returns -EPROBE_DEFER */
620 np = of_find_node_by_path("/testcase-data/testcase-device1");
621 pdev = of_find_device_by_node(np);
Rob Herring7d1cdc82014-05-13 10:07:29 -0500622 selftest(pdev, "device 1 creation failed\n");
623
Rob Herring82c0f582014-04-23 17:57:40 -0500624 irq = platform_get_irq(pdev, 0);
Rob Herring7d1cdc82014-05-13 10:07:29 -0500625 selftest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq);
Rob Herring82c0f582014-04-23 17:57:40 -0500626
627 /* Test that a parsing failure does not return -EPROBE_DEFER */
628 np = of_find_node_by_path("/testcase-data/testcase-device2");
629 pdev = of_find_device_by_node(np);
Rob Herring7d1cdc82014-05-13 10:07:29 -0500630 selftest(pdev, "device 2 creation failed\n");
Rob Herring82c0f582014-04-23 17:57:40 -0500631 irq = platform_get_irq(pdev, 0);
Rob Herring7d1cdc82014-05-13 10:07:29 -0500632 selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq);
Rob Herring82c0f582014-04-23 17:57:40 -0500633
Rob Herringfb2caa52014-05-13 10:07:54 -0500634 np = of_find_node_by_path("/testcase-data/platform-tests");
635 if (!np) {
636 pr_err("No testcase data in device tree\n");
637 return;
638 }
639
640 for_each_child_of_node(np, child) {
641 struct device_node *grandchild;
642 of_platform_populate(child, match, NULL, NULL);
643 for_each_child_of_node(child, grandchild)
644 selftest(of_find_device_by_node(grandchild),
645 "Could not create device for node '%s'\n",
646 grandchild->name);
647 }
Rob Herring82c0f582014-04-23 17:57:40 -0500648}
649
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700650/**
651 * update_node_properties - adds the properties
652 * of np into dup node (present in live tree) and
653 * updates parent of children of np to dup.
654 *
655 * @np: node already present in live tree
656 * @dup: node present in live tree to be updated
657 */
658static void update_node_properties(struct device_node *np,
659 struct device_node *dup)
660{
661 struct property *prop;
662 struct device_node *child;
663
664 for_each_property_of_node(np, prop)
665 of_add_property(dup, prop);
666
667 for_each_child_of_node(np, child)
668 child->parent = dup;
669}
670
671/**
672 * attach_node_and_children - attaches nodes
673 * and its children to live tree
674 *
675 * @np: Node to attach to live tree
676 */
677static int attach_node_and_children(struct device_node *np)
678{
679 struct device_node *next, *root = np, *dup;
680
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700681 /* skip root node */
682 np = np->child;
683 /* storing a copy in temporary node */
684 dup = np;
685
686 while (dup) {
Grant Likelye66c98c2014-10-01 16:57:07 +0100687 if (WARN_ON(last_node_index >= NO_OF_NODES))
688 return -EINVAL;
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700689 nodes[last_node_index++] = dup;
690 dup = dup->sibling;
691 }
692 dup = NULL;
693
694 while (np) {
695 next = np->allnext;
696 dup = of_find_node_by_path(np->full_name);
697 if (dup)
698 update_node_properties(np, dup);
699 else {
700 np->child = NULL;
701 if (np->parent == root)
702 np->parent = of_allnodes;
703 of_attach_node(np);
704 }
705 np = next;
706 }
707
708 return 0;
709}
710
711/**
712 * selftest_data_add - Reads, copies data from
713 * linked tree and attaches it to the live tree
714 */
715static int __init selftest_data_add(void)
716{
717 void *selftest_data;
Gaurav Minochab951f9d2014-07-26 12:48:50 -0700718 struct device_node *selftest_data_node, *np;
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700719 extern uint8_t __dtb_testcases_begin[];
720 extern uint8_t __dtb_testcases_end[];
721 const int size = __dtb_testcases_end - __dtb_testcases_begin;
722
Gaurav Minochab951f9d2014-07-26 12:48:50 -0700723 if (!size) {
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700724 pr_warn("%s: No testcase data to attach; not running tests\n",
725 __func__);
726 return -ENODATA;
727 }
728
729 /* creating copy */
730 selftest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL);
731
732 if (!selftest_data) {
733 pr_warn("%s: Failed to allocate memory for selftest_data; "
734 "not running tests\n", __func__);
735 return -ENOMEM;
736 }
737 of_fdt_unflatten_tree(selftest_data, &selftest_data_node);
Gaurav Minochab951f9d2014-07-26 12:48:50 -0700738 if (!selftest_data_node) {
739 pr_warn("%s: No tree to attach; not running tests\n", __func__);
740 return -ENODATA;
741 }
742
743 if (!of_allnodes) {
744 /* enabling flag for removing nodes */
745 selftest_live_tree = true;
746 of_allnodes = selftest_data_node;
747
748 for_each_of_allnodes(np)
749 __of_attach_node_sysfs(np);
750 of_aliases = of_find_node_by_path("/aliases");
751 of_chosen = of_find_node_by_path("/chosen");
752 return 0;
753 }
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700754
755 /* attach the sub-tree to live tree */
756 return attach_node_and_children(selftest_data_node);
757}
758
759/**
760 * detach_node_and_children - detaches node
761 * and its children from live tree
762 *
763 * @np: Node to detach from live tree
764 */
765static void detach_node_and_children(struct device_node *np)
766{
767 while (np->child)
768 detach_node_and_children(np->child);
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700769 of_detach_node(np);
770}
771
772/**
773 * selftest_data_remove - removes the selftest data
774 * nodes from the live tree
775 */
776static void selftest_data_remove(void)
777{
778 struct device_node *np;
779 struct property *prop;
780
Gaurav Minochab951f9d2014-07-26 12:48:50 -0700781 if (selftest_live_tree) {
782 of_node_put(of_aliases);
783 of_node_put(of_chosen);
784 of_aliases = NULL;
785 of_chosen = NULL;
786 for_each_child_of_node(of_allnodes, np)
787 detach_node_and_children(np);
788 __of_detach_node_sysfs(of_allnodes);
789 of_allnodes = NULL;
790 return;
791 }
792
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700793 while (last_node_index >= 0) {
794 if (nodes[last_node_index]) {
795 np = of_find_node_by_path(nodes[last_node_index]->full_name);
796 if (strcmp(np->full_name, "/aliases") != 0) {
Grant Likelye66c98c2014-10-01 16:57:07 +0100797 detach_node_and_children(np);
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700798 } else {
799 for_each_property_of_node(np, prop) {
800 if (strcmp(prop->name, "testcase-alias") == 0)
801 of_remove_property(np, prop);
802 }
803 }
804 }
805 last_node_index--;
806 }
807}
808
Grant Likely53a42092011-12-12 09:25:57 -0700809static int __init of_selftest(void)
810{
811 struct device_node *np;
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700812 int res;
813
814 /* adding data for selftest */
815 res = selftest_data_add();
816 if (res)
817 return res;
Grant Likely53a42092011-12-12 09:25:57 -0700818
819 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
820 if (!np) {
821 pr_info("No testcase data in device tree; not running tests\n");
822 return 0;
823 }
824 of_node_put(np);
825
826 pr_info("start of selftest - you will see error messages\n");
Grant Likelyf2051d62014-10-01 17:40:22 +0100827 of_selftest_check_tree_linkage();
Grant Likelyae91ff72014-03-14 13:53:10 +0000828 of_selftest_find_node_by_name();
Grant Likely7e66c5c2013-11-15 17:19:09 +0000829 of_selftest_dynamic();
Grant Likely53a42092011-12-12 09:25:57 -0700830 of_selftest_parse_phandle_with_args();
Grant Likely7aff0fe2011-12-12 09:25:58 -0700831 of_selftest_property_match_string();
Pantelis Antoniou69843392014-07-04 19:58:47 +0300832 of_selftest_property_copy();
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300833 of_selftest_changeset();
Grant Likelya9f10ca2013-10-11 22:04:23 +0100834 of_selftest_parse_interrupts();
Grant Likely79d97012013-09-19 16:47:37 -0500835 of_selftest_parse_interrupts_extended();
Grant Likely1f42e5d2014-02-18 21:38:55 +0000836 of_selftest_match_node();
Rob Herring82c0f582014-04-23 17:57:40 -0500837 of_selftest_platform_populate();
Gaurav Minochaae9304c2014-07-16 23:09:39 -0700838
839 /* removing selftest data from live tree */
840 selftest_data_remove();
841
Grant Likelyf2051d62014-10-01 17:40:22 +0100842 /* Double check linkage after removing testcase data */
843 of_selftest_check_tree_linkage();
844
845 pr_info("end of selftest - %i passed, %i failed\n",
846 selftest_results.passed, selftest_results.failed);
847
Grant Likely53a42092011-12-12 09:25:57 -0700848 return 0;
849}
850late_initcall(of_selftest);