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

Enabling OF selftest to run without machine's devicetree

If there is no devicetree present, this patch adds the selftest
data as a live devicetree. It also removes the same after the
testcase execution is complete.

Tested with and without machine's devicetree.

Signed-off-by: Gaurav Minocha <gaurav.minocha.os@gmail.com>
Signed-off-by: Grant Likely <grant.likely@linaro.org>

authored by

Gaurav Minocha and committed by
Grant Likely
b951f9dc b5f2a8c0

+31 -9
+31 -9
drivers/of/selftest.c
··· 27 27 #define NO_OF_NODES 2 28 28 static struct device_node *nodes[NO_OF_NODES]; 29 29 static int last_node_index; 30 + static bool selftest_live_tree; 30 31 31 32 #define selftest(result, fmt, ...) { \ 32 33 if (!(result)) { \ ··· 631 630 { 632 631 struct device_node *next, *root = np, *dup; 633 632 634 - if (!np) { 635 - pr_warn("%s: No tree to attach; not running tests\n", 636 - __func__); 637 - return -ENODATA; 638 - } 639 - 640 - 641 633 /* skip root node */ 642 634 np = np->child; 643 635 /* storing a copy in temporary node */ ··· 666 672 static int __init selftest_data_add(void) 667 673 { 668 674 void *selftest_data; 669 - struct device_node *selftest_data_node; 675 + struct device_node *selftest_data_node, *np; 670 676 extern uint8_t __dtb_testcases_begin[]; 671 677 extern uint8_t __dtb_testcases_end[]; 672 678 const int size = __dtb_testcases_end - __dtb_testcases_begin; 673 679 674 - if (!size || !of_allnodes) { 680 + if (!size) { 675 681 pr_warn("%s: No testcase data to attach; not running tests\n", 676 682 __func__); 677 683 return -ENODATA; ··· 686 692 return -ENOMEM; 687 693 } 688 694 of_fdt_unflatten_tree(selftest_data, &selftest_data_node); 695 + if (!selftest_data_node) { 696 + pr_warn("%s: No tree to attach; not running tests\n", __func__); 697 + return -ENODATA; 698 + } 699 + 700 + if (!of_allnodes) { 701 + /* enabling flag for removing nodes */ 702 + selftest_live_tree = true; 703 + of_allnodes = selftest_data_node; 704 + 705 + for_each_of_allnodes(np) 706 + __of_attach_node_sysfs(np); 707 + of_aliases = of_find_node_by_path("/aliases"); 708 + of_chosen = of_find_node_by_path("/chosen"); 709 + return 0; 710 + } 689 711 690 712 /* attach the sub-tree to live tree */ 691 713 return attach_node_and_children(selftest_data_node); ··· 732 722 { 733 723 struct device_node *np; 734 724 struct property *prop; 725 + 726 + if (selftest_live_tree) { 727 + of_node_put(of_aliases); 728 + of_node_put(of_chosen); 729 + of_aliases = NULL; 730 + of_chosen = NULL; 731 + for_each_child_of_node(of_allnodes, np) 732 + detach_node_and_children(np); 733 + __of_detach_node_sysfs(of_allnodes); 734 + of_allnodes = NULL; 735 + return; 736 + } 735 737 736 738 while (last_node_index >= 0) { 737 739 if (nodes[last_node_index]) {