Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc6 801 lines 23 kB view raw
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/module.h> 11#include <linux/of.h> 12#include <linux/of_fdt.h> 13#include <linux/of_irq.h> 14#include <linux/of_platform.h> 15#include <linux/list.h> 16#include <linux/mutex.h> 17#include <linux/slab.h> 18#include <linux/device.h> 19 20#include "of_private.h" 21 22static struct selftest_results { 23 int passed; 24 int failed; 25} selftest_results; 26 27#define NO_OF_NODES 2 28static struct device_node *nodes[NO_OF_NODES]; 29static int last_node_index; 30static bool selftest_live_tree; 31 32#define selftest(result, fmt, ...) { \ 33 if (!(result)) { \ 34 selftest_results.failed++; \ 35 pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ 36 } else { \ 37 selftest_results.passed++; \ 38 pr_debug("pass %s():%i\n", __func__, __LINE__); \ 39 } \ 40} 41 42static 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 87static 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 148static void __init of_selftest_parse_phandle_with_args(void) 149{ 150 struct device_node *np; 151 struct of_phandle_args args; 152 int i, rc; 153 154 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); 155 if (!np) { 156 pr_err("missing testcase data\n"); 157 return; 158 } 159 160 rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); 161 selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); 162 163 for (i = 0; i < 8; i++) { 164 bool passed = true; 165 rc = of_parse_phandle_with_args(np, "phandle-list", 166 "#phandle-cells", i, &args); 167 168 /* Test the values from tests-phandle.dtsi */ 169 switch (i) { 170 case 0: 171 passed &= !rc; 172 passed &= (args.args_count == 1); 173 passed &= (args.args[0] == (i + 1)); 174 break; 175 case 1: 176 passed &= !rc; 177 passed &= (args.args_count == 2); 178 passed &= (args.args[0] == (i + 1)); 179 passed &= (args.args[1] == 0); 180 break; 181 case 2: 182 passed &= (rc == -ENOENT); 183 break; 184 case 3: 185 passed &= !rc; 186 passed &= (args.args_count == 3); 187 passed &= (args.args[0] == (i + 1)); 188 passed &= (args.args[1] == 4); 189 passed &= (args.args[2] == 3); 190 break; 191 case 4: 192 passed &= !rc; 193 passed &= (args.args_count == 2); 194 passed &= (args.args[0] == (i + 1)); 195 passed &= (args.args[1] == 100); 196 break; 197 case 5: 198 passed &= !rc; 199 passed &= (args.args_count == 0); 200 break; 201 case 6: 202 passed &= !rc; 203 passed &= (args.args_count == 1); 204 passed &= (args.args[0] == (i + 1)); 205 break; 206 case 7: 207 passed &= (rc == -ENOENT); 208 break; 209 default: 210 passed = false; 211 } 212 213 selftest(passed, "index %i - data error on node %s rc=%i\n", 214 i, args.np->full_name, rc); 215 } 216 217 /* Check for missing list property */ 218 rc = of_parse_phandle_with_args(np, "phandle-list-missing", 219 "#phandle-cells", 0, &args); 220 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); 221 rc = of_count_phandle_with_args(np, "phandle-list-missing", 222 "#phandle-cells"); 223 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); 224 225 /* Check for missing cells property */ 226 rc = of_parse_phandle_with_args(np, "phandle-list", 227 "#phandle-cells-missing", 0, &args); 228 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 229 rc = of_count_phandle_with_args(np, "phandle-list", 230 "#phandle-cells-missing"); 231 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 232 233 /* Check for bad phandle in list */ 234 rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", 235 "#phandle-cells", 0, &args); 236 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 237 rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle", 238 "#phandle-cells"); 239 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 240 241 /* Check for incorrectly formed argument list */ 242 rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", 243 "#phandle-cells", 1, &args); 244 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 245 rc = of_count_phandle_with_args(np, "phandle-list-bad-args", 246 "#phandle-cells"); 247 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 248} 249 250static void __init of_selftest_property_match_string(void) 251{ 252 struct device_node *np; 253 int rc; 254 255 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); 256 if (!np) { 257 pr_err("No testcase data in device tree\n"); 258 return; 259 } 260 261 rc = of_property_match_string(np, "phandle-list-names", "first"); 262 selftest(rc == 0, "first expected:0 got:%i\n", rc); 263 rc = of_property_match_string(np, "phandle-list-names", "second"); 264 selftest(rc == 1, "second expected:0 got:%i\n", rc); 265 rc = of_property_match_string(np, "phandle-list-names", "third"); 266 selftest(rc == 2, "third expected:0 got:%i\n", rc); 267 rc = of_property_match_string(np, "phandle-list-names", "fourth"); 268 selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); 269 rc = of_property_match_string(np, "missing-property", "blah"); 270 selftest(rc == -EINVAL, "missing property; rc=%i", rc); 271 rc = of_property_match_string(np, "empty-property", "blah"); 272 selftest(rc == -ENODATA, "empty property; rc=%i", rc); 273 rc = of_property_match_string(np, "unterminated-string", "blah"); 274 selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); 275} 276 277#define propcmp(p1, p2) (((p1)->length == (p2)->length) && \ 278 (p1)->value && (p2)->value && \ 279 !memcmp((p1)->value, (p2)->value, (p1)->length) && \ 280 !strcmp((p1)->name, (p2)->name)) 281static void __init of_selftest_property_copy(void) 282{ 283#ifdef CONFIG_OF_DYNAMIC 284 struct property p1 = { .name = "p1", .length = 0, .value = "" }; 285 struct property p2 = { .name = "p2", .length = 5, .value = "abcd" }; 286 struct property *new; 287 288 new = __of_prop_dup(&p1, GFP_KERNEL); 289 selftest(new && propcmp(&p1, new), "empty property didn't copy correctly\n"); 290 kfree(new->value); 291 kfree(new->name); 292 kfree(new); 293 294 new = __of_prop_dup(&p2, GFP_KERNEL); 295 selftest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n"); 296 kfree(new->value); 297 kfree(new->name); 298 kfree(new); 299#endif 300} 301 302static void __init of_selftest_changeset(void) 303{ 304#ifdef CONFIG_OF_DYNAMIC 305 struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" }; 306 struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" }; 307 struct property *ppremove; 308 struct device_node *n1, *n2, *n21, *nremove, *parent; 309 struct of_changeset chgset; 310 311 of_changeset_init(&chgset); 312 n1 = __of_node_alloc("/testcase-data/changeset/n1", GFP_KERNEL); 313 selftest(n1, "testcase setup failure\n"); 314 n2 = __of_node_alloc("/testcase-data/changeset/n2", GFP_KERNEL); 315 selftest(n2, "testcase setup failure\n"); 316 n21 = __of_node_alloc("/testcase-data/changeset/n2/n21", GFP_KERNEL); 317 selftest(n21, "testcase setup failure %p\n", n21); 318 nremove = of_find_node_by_path("/testcase-data/changeset/node-remove"); 319 selftest(nremove, "testcase setup failure\n"); 320 ppadd = __of_prop_dup(&padd, GFP_KERNEL); 321 selftest(ppadd, "testcase setup failure\n"); 322 ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL); 323 selftest(ppupdate, "testcase setup failure\n"); 324 parent = nremove->parent; 325 n1->parent = parent; 326 n2->parent = parent; 327 n21->parent = n2; 328 n2->child = n21; 329 ppremove = of_find_property(parent, "prop-remove", NULL); 330 selftest(ppremove, "failed to find removal prop"); 331 332 of_changeset_init(&chgset); 333 selftest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n"); 334 selftest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n"); 335 selftest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n"); 336 selftest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n"); 337 selftest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n"); 338 selftest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n"); 339 selftest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n"); 340 mutex_lock(&of_mutex); 341 selftest(!of_changeset_apply(&chgset), "apply failed\n"); 342 mutex_unlock(&of_mutex); 343 344 mutex_lock(&of_mutex); 345 selftest(!of_changeset_revert(&chgset), "revert failed\n"); 346 mutex_unlock(&of_mutex); 347 348 of_changeset_destroy(&chgset); 349#endif 350} 351 352static void __init of_selftest_parse_interrupts(void) 353{ 354 struct device_node *np; 355 struct of_phandle_args args; 356 int i, rc; 357 358 np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); 359 if (!np) { 360 pr_err("missing testcase data\n"); 361 return; 362 } 363 364 for (i = 0; i < 4; i++) { 365 bool passed = true; 366 args.args_count = 0; 367 rc = of_irq_parse_one(np, i, &args); 368 369 passed &= !rc; 370 passed &= (args.args_count == 1); 371 passed &= (args.args[0] == (i + 1)); 372 373 selftest(passed, "index %i - data error on node %s rc=%i\n", 374 i, args.np->full_name, rc); 375 } 376 of_node_put(np); 377 378 np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); 379 if (!np) { 380 pr_err("missing testcase data\n"); 381 return; 382 } 383 384 for (i = 0; i < 4; i++) { 385 bool passed = true; 386 args.args_count = 0; 387 rc = of_irq_parse_one(np, i, &args); 388 389 /* Test the values from tests-phandle.dtsi */ 390 switch (i) { 391 case 0: 392 passed &= !rc; 393 passed &= (args.args_count == 1); 394 passed &= (args.args[0] == 9); 395 break; 396 case 1: 397 passed &= !rc; 398 passed &= (args.args_count == 3); 399 passed &= (args.args[0] == 10); 400 passed &= (args.args[1] == 11); 401 passed &= (args.args[2] == 12); 402 break; 403 case 2: 404 passed &= !rc; 405 passed &= (args.args_count == 2); 406 passed &= (args.args[0] == 13); 407 passed &= (args.args[1] == 14); 408 break; 409 case 3: 410 passed &= !rc; 411 passed &= (args.args_count == 2); 412 passed &= (args.args[0] == 15); 413 passed &= (args.args[1] == 16); 414 break; 415 default: 416 passed = false; 417 } 418 selftest(passed, "index %i - data error on node %s rc=%i\n", 419 i, args.np->full_name, rc); 420 } 421 of_node_put(np); 422} 423 424static void __init of_selftest_parse_interrupts_extended(void) 425{ 426 struct device_node *np; 427 struct of_phandle_args args; 428 int i, rc; 429 430 np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); 431 if (!np) { 432 pr_err("missing testcase data\n"); 433 return; 434 } 435 436 for (i = 0; i < 7; i++) { 437 bool passed = true; 438 rc = of_irq_parse_one(np, i, &args); 439 440 /* Test the values from tests-phandle.dtsi */ 441 switch (i) { 442 case 0: 443 passed &= !rc; 444 passed &= (args.args_count == 1); 445 passed &= (args.args[0] == 1); 446 break; 447 case 1: 448 passed &= !rc; 449 passed &= (args.args_count == 3); 450 passed &= (args.args[0] == 2); 451 passed &= (args.args[1] == 3); 452 passed &= (args.args[2] == 4); 453 break; 454 case 2: 455 passed &= !rc; 456 passed &= (args.args_count == 2); 457 passed &= (args.args[0] == 5); 458 passed &= (args.args[1] == 6); 459 break; 460 case 3: 461 passed &= !rc; 462 passed &= (args.args_count == 1); 463 passed &= (args.args[0] == 9); 464 break; 465 case 4: 466 passed &= !rc; 467 passed &= (args.args_count == 3); 468 passed &= (args.args[0] == 10); 469 passed &= (args.args[1] == 11); 470 passed &= (args.args[2] == 12); 471 break; 472 case 5: 473 passed &= !rc; 474 passed &= (args.args_count == 2); 475 passed &= (args.args[0] == 13); 476 passed &= (args.args[1] == 14); 477 break; 478 case 6: 479 passed &= !rc; 480 passed &= (args.args_count == 1); 481 passed &= (args.args[0] == 15); 482 break; 483 default: 484 passed = false; 485 } 486 487 selftest(passed, "index %i - data error on node %s rc=%i\n", 488 i, args.np->full_name, rc); 489 } 490 of_node_put(np); 491} 492 493static struct of_device_id match_node_table[] = { 494 { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ 495 { .data = "B", .type = "type1", }, /* followed by type alone */ 496 497 { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */ 498 { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */ 499 { .data = "Cc", .name = "name2", .type = "type2", }, 500 501 { .data = "E", .compatible = "compat3" }, 502 { .data = "G", .compatible = "compat2", }, 503 { .data = "H", .compatible = "compat2", .name = "name5", }, 504 { .data = "I", .compatible = "compat2", .type = "type1", }, 505 { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", }, 506 { .data = "K", .compatible = "compat2", .name = "name9", }, 507 {} 508}; 509 510static struct { 511 const char *path; 512 const char *data; 513} match_node_tests[] = { 514 { .path = "/testcase-data/match-node/name0", .data = "A", }, 515 { .path = "/testcase-data/match-node/name1", .data = "B", }, 516 { .path = "/testcase-data/match-node/a/name2", .data = "Ca", }, 517 { .path = "/testcase-data/match-node/b/name2", .data = "Cb", }, 518 { .path = "/testcase-data/match-node/c/name2", .data = "Cc", }, 519 { .path = "/testcase-data/match-node/name3", .data = "E", }, 520 { .path = "/testcase-data/match-node/name4", .data = "G", }, 521 { .path = "/testcase-data/match-node/name5", .data = "H", }, 522 { .path = "/testcase-data/match-node/name6", .data = "G", }, 523 { .path = "/testcase-data/match-node/name7", .data = "I", }, 524 { .path = "/testcase-data/match-node/name8", .data = "J", }, 525 { .path = "/testcase-data/match-node/name9", .data = "K", }, 526}; 527 528static void __init of_selftest_match_node(void) 529{ 530 struct device_node *np; 531 const struct of_device_id *match; 532 int i; 533 534 for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) { 535 np = of_find_node_by_path(match_node_tests[i].path); 536 if (!np) { 537 selftest(0, "missing testcase node %s\n", 538 match_node_tests[i].path); 539 continue; 540 } 541 542 match = of_match_node(match_node_table, np); 543 if (!match) { 544 selftest(0, "%s didn't match anything\n", 545 match_node_tests[i].path); 546 continue; 547 } 548 549 if (strcmp(match->data, match_node_tests[i].data) != 0) { 550 selftest(0, "%s got wrong match. expected %s, got %s\n", 551 match_node_tests[i].path, match_node_tests[i].data, 552 (const char *)match->data); 553 continue; 554 } 555 selftest(1, "passed"); 556 } 557} 558 559static void __init of_selftest_platform_populate(void) 560{ 561 int irq; 562 struct device_node *np, *child; 563 struct platform_device *pdev; 564 struct of_device_id match[] = { 565 { .compatible = "test-device", }, 566 {} 567 }; 568 569 np = of_find_node_by_path("/testcase-data"); 570 of_platform_populate(np, of_default_bus_match_table, NULL, NULL); 571 572 /* Test that a missing irq domain returns -EPROBE_DEFER */ 573 np = of_find_node_by_path("/testcase-data/testcase-device1"); 574 pdev = of_find_device_by_node(np); 575 selftest(pdev, "device 1 creation failed\n"); 576 577 irq = platform_get_irq(pdev, 0); 578 selftest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq); 579 580 /* Test that a parsing failure does not return -EPROBE_DEFER */ 581 np = of_find_node_by_path("/testcase-data/testcase-device2"); 582 pdev = of_find_device_by_node(np); 583 selftest(pdev, "device 2 creation failed\n"); 584 irq = platform_get_irq(pdev, 0); 585 selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq); 586 587 np = of_find_node_by_path("/testcase-data/platform-tests"); 588 if (!np) { 589 pr_err("No testcase data in device tree\n"); 590 return; 591 } 592 593 for_each_child_of_node(np, child) { 594 struct device_node *grandchild; 595 of_platform_populate(child, match, NULL, NULL); 596 for_each_child_of_node(child, grandchild) 597 selftest(of_find_device_by_node(grandchild), 598 "Could not create device for node '%s'\n", 599 grandchild->name); 600 } 601} 602 603/** 604 * update_node_properties - adds the properties 605 * of np into dup node (present in live tree) and 606 * updates parent of children of np to dup. 607 * 608 * @np: node already present in live tree 609 * @dup: node present in live tree to be updated 610 */ 611static void update_node_properties(struct device_node *np, 612 struct device_node *dup) 613{ 614 struct property *prop; 615 struct device_node *child; 616 617 for_each_property_of_node(np, prop) 618 of_add_property(dup, prop); 619 620 for_each_child_of_node(np, child) 621 child->parent = dup; 622} 623 624/** 625 * attach_node_and_children - attaches nodes 626 * and its children to live tree 627 * 628 * @np: Node to attach to live tree 629 */ 630static int attach_node_and_children(struct device_node *np) 631{ 632 struct device_node *next, *root = np, *dup; 633 634 /* skip root node */ 635 np = np->child; 636 /* storing a copy in temporary node */ 637 dup = np; 638 639 while (dup) { 640 nodes[last_node_index++] = dup; 641 dup = dup->sibling; 642 } 643 dup = NULL; 644 645 while (np) { 646 next = np->allnext; 647 dup = of_find_node_by_path(np->full_name); 648 if (dup) 649 update_node_properties(np, dup); 650 else { 651 np->child = NULL; 652 if (np->parent == root) 653 np->parent = of_allnodes; 654 of_attach_node(np); 655 } 656 np = next; 657 } 658 659 return 0; 660} 661 662/** 663 * selftest_data_add - Reads, copies data from 664 * linked tree and attaches it to the live tree 665 */ 666static int __init selftest_data_add(void) 667{ 668 void *selftest_data; 669 struct device_node *selftest_data_node, *np; 670 extern uint8_t __dtb_testcases_begin[]; 671 extern uint8_t __dtb_testcases_end[]; 672 const int size = __dtb_testcases_end - __dtb_testcases_begin; 673 674 if (!size) { 675 pr_warn("%s: No testcase data to attach; not running tests\n", 676 __func__); 677 return -ENODATA; 678 } 679 680 /* creating copy */ 681 selftest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL); 682 683 if (!selftest_data) { 684 pr_warn("%s: Failed to allocate memory for selftest_data; " 685 "not running tests\n", __func__); 686 return -ENOMEM; 687 } 688 of_fdt_unflatten_tree(selftest_data, &selftest_data_node); 689 if (!selftest_data_node) { 690 pr_warn("%s: No tree to attach; not running tests\n", __func__); 691 return -ENODATA; 692 } 693 694 if (!of_allnodes) { 695 /* enabling flag for removing nodes */ 696 selftest_live_tree = true; 697 of_allnodes = selftest_data_node; 698 699 for_each_of_allnodes(np) 700 __of_attach_node_sysfs(np); 701 of_aliases = of_find_node_by_path("/aliases"); 702 of_chosen = of_find_node_by_path("/chosen"); 703 return 0; 704 } 705 706 /* attach the sub-tree to live tree */ 707 return attach_node_and_children(selftest_data_node); 708} 709 710/** 711 * detach_node_and_children - detaches node 712 * and its children from live tree 713 * 714 * @np: Node to detach from live tree 715 */ 716static void detach_node_and_children(struct device_node *np) 717{ 718 while (np->child) 719 detach_node_and_children(np->child); 720 721 while (np->sibling) 722 detach_node_and_children(np->sibling); 723 724 of_detach_node(np); 725} 726 727/** 728 * selftest_data_remove - removes the selftest data 729 * nodes from the live tree 730 */ 731static void selftest_data_remove(void) 732{ 733 struct device_node *np; 734 struct property *prop; 735 736 if (selftest_live_tree) { 737 of_node_put(of_aliases); 738 of_node_put(of_chosen); 739 of_aliases = NULL; 740 of_chosen = NULL; 741 for_each_child_of_node(of_allnodes, np) 742 detach_node_and_children(np); 743 __of_detach_node_sysfs(of_allnodes); 744 of_allnodes = NULL; 745 return; 746 } 747 748 while (last_node_index >= 0) { 749 if (nodes[last_node_index]) { 750 np = of_find_node_by_path(nodes[last_node_index]->full_name); 751 if (strcmp(np->full_name, "/aliases") != 0) { 752 detach_node_and_children(np->child); 753 of_detach_node(np); 754 } else { 755 for_each_property_of_node(np, prop) { 756 if (strcmp(prop->name, "testcase-alias") == 0) 757 of_remove_property(np, prop); 758 } 759 } 760 } 761 last_node_index--; 762 } 763} 764 765static int __init of_selftest(void) 766{ 767 struct device_node *np; 768 int res; 769 770 /* adding data for selftest */ 771 res = selftest_data_add(); 772 if (res) 773 return res; 774 775 np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); 776 if (!np) { 777 pr_info("No testcase data in device tree; not running tests\n"); 778 return 0; 779 } 780 of_node_put(np); 781 782 pr_info("start of selftest - you will see error messages\n"); 783 of_selftest_find_node_by_name(); 784 of_selftest_dynamic(); 785 of_selftest_parse_phandle_with_args(); 786 of_selftest_property_match_string(); 787 of_selftest_property_copy(); 788 of_selftest_changeset(); 789 of_selftest_parse_interrupts(); 790 of_selftest_parse_interrupts_extended(); 791 of_selftest_match_node(); 792 of_selftest_platform_populate(); 793 pr_info("end of selftest - %i passed, %i failed\n", 794 selftest_results.passed, selftest_results.failed); 795 796 /* removing selftest data from live tree */ 797 selftest_data_remove(); 798 799 return 0; 800} 801late_initcall(of_selftest);