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 23static struct selftest_results { 24 int passed; 25 int failed; 26} selftest_results; 27 28#define NO_OF_NODES 3 29static struct device_node *nodes[NO_OF_NODES]; 30static int last_node_index; 31static 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 43static 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 88static 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 149static 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 178static 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 196struct node_hash { 197 struct hlist_node node; 198 struct device_node *np; 199}; 200 201static DEFINE_HASHTABLE(phandle_ht, 8); 202static 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 240static 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 342static 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)) 427static 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 448static 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 498static 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 570static 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 639static 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 656static 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 674static 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 705static 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 */ 757static 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 */ 776static 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 */ 814static 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 */ 871static 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 */ 882static 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 918static 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} 962late_initcall(of_selftest); 963