These tests exercise the application of the overlay fragments by of_overlay_apply_fragment() with the following test cases:
1. Fragment target is found by target-path and phandle 2. Fragment properties are merged into existing nodes 3. Fragment children without an __overlay__ node are skipped 4. Error path for a fragment whose target does not exist Signed-off-by: Stefan Kerkmann <[email protected]> --- test/self/Makefile | 1 + test/self/of_overlay.c | 68 ++++++++++++++++++++++++++++++++ test/self/of_overlay.dtso | 34 ++++++++++++++++ test/self/of_overlay_missing_target.dtso | 24 +++++++++++ 4 files changed, 127 insertions(+) diff --git a/test/self/Makefile b/test/self/Makefile index f6cec81011..0fba7ac566 100644 --- a/test/self/Makefile +++ b/test/self/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_SELFTEST_OF_OVERLAY) += of_overlay.o # Enforce generation of __symbols__ table for overlay tests DTC_FLAGS_of_overlay_with_symbols := -@ obj-$(CONFIG_SELFTEST_OF_OVERLAY) += of_overlay_with_symbols.dtb.o of_overlay_with_symbols.dtbo.o +obj-$(CONFIG_SELFTEST_OF_OVERLAY) += of_overlay.dtbo.o of_overlay_missing_target.dtbo.o obj-$(CONFIG_SELFTEST_ENVIRONMENT_VARIABLES) += envvar.o obj-$(CONFIG_SELFTEST_FS_RAMFS) += ramfs.o obj-$(CONFIG_SELFTEST_DIRFD) += dirfd.o diff --git a/test/self/of_overlay.c b/test/self/of_overlay.c index 2804c936c0..4c17cae16d 100644 --- a/test/self/of_overlay.c +++ b/test/self/of_overlay.c @@ -98,9 +98,77 @@ static void test_of_overlay_symbol_outside_overlay(void) of_delete_node(root); } +extern char __dtbo_of_overlay_start[], __dtbo_of_overlay_end[]; + +static void test_of_overlay_fragments(void) +{ + struct device_node *root, *overlay, *node; + int ret; + + if (!test_setup(&root, &overlay, __dtb_of_overlay_with_symbols_start, + __dtb_of_overlay_with_symbols_end, + __dtbo_of_overlay_start, __dtbo_of_overlay_end)) + return; + + ret = of_overlay_apply_tree(root, overlay); + assert_inteq(ret, 0); + + node = of_find_node_by_path_from(root, "/target-node"); + assert_cond(node != NULL); + assert_inteq(of_property_match_string(node, "new-prop", "target-path"), + 0); + assert_cond(of_get_child_by_name(node, "added-child") != NULL); + + node = of_find_node_by_path_from(root, "/target-node/existing-child"); + assert_cond(node != NULL); + assert_inteq(of_property_match_string(node, "old-prop", "old"), 0); + assert_inteq(of_property_match_string(node, "new-prop", "merged"), 0); + + node = of_find_node_by_path_from(root, "/phandle-target-node"); + assert_cond(node != NULL); + assert_inteq(of_property_match_string(node, "new-prop", + "target-phandle"), + 0); + + node = of_find_node_by_path_from(root, "/non-fragment-node"); + assert_cond(node == NULL); + + of_delete_node(overlay); + of_delete_node(root); +} + +extern char __dtbo_of_overlay_missing_target_start[], + __dtbo_of_overlay_missing_target_end[]; + +static void test_of_overlay_missing_target(void) +{ + struct device_node *root, *overlay, *node; + int ret; + + if (!test_setup(&root, &overlay, __dtb_of_overlay_with_symbols_start, + __dtb_of_overlay_with_symbols_end, + __dtbo_of_overlay_missing_target_start, + __dtbo_of_overlay_missing_target_end)) + return; + + ret = of_overlay_apply_tree(root, overlay); + assert_inteq(ret, -ENOENT); + + node = of_find_node_by_path_from(root, "/does-not-exist"); + assert_cond(node == NULL); + + node = of_find_node_by_path_from(root, "/target-node/applied-anyway"); + assert_cond(node != NULL); + + of_delete_node(overlay); + of_delete_node(root); +} + static void test_of_overlay(void) { test_of_overlay_symbol_without_overlay(); test_of_overlay_symbol_outside_overlay(); + test_of_overlay_fragments(); + test_of_overlay_missing_target(); } bselftest(core, test_of_overlay); diff --git a/test/self/of_overlay.dtso b/test/self/of_overlay.dtso new file mode 100644 index 0000000000..21dc85a8e4 --- /dev/null +++ b/test/self/of_overlay.dtso @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; +/plugin/; + +/ { + /* not a fragment, must not be applied */ + non-fragment-node { + }; + + fragment@0 { + target-path = "/target-node"; + + __overlay__ { + new-prop = "target-path"; + + added-child { + child-prop; + }; + + existing-child { + new-prop = "merged"; + }; + }; + }; + + fragment@1 { + target = <&phandle_target>; + + __overlay__ { + new-prop = "target-phandle"; + }; + }; +}; diff --git a/test/self/of_overlay_missing_target.dtso b/test/self/of_overlay_missing_target.dtso new file mode 100644 index 0000000000..39362b0a0e --- /dev/null +++ b/test/self/of_overlay_missing_target.dtso @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target-path = "/does-not-exist"; + + __overlay__ { + never-applied { + }; + }; + }; + + fragment@1 { + target-path = "/target-node"; + + __overlay__ { + applied-anyway { + }; + }; + }; +}; -- 2.47.3
