@@ -1,3 +1,5 @@
CONFIG_KUNIT=y
CONFIG_OF=y
CONFIG_OF_KUNIT_TEST=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_OVERLAY_KUNIT_TEST=y
@@ -112,6 +112,16 @@ config OF_OVERLAY
While this option is selected automatically when needed, you can
enable it manually to improve device tree unit test coverage.
+config OF_OVERLAY_KUNIT_TEST
+ tristate "Device Tree overlay KUnit tests" if !KUNIT_ALL_TESTS
+ depends on OF_OVERLAY
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This option builds KUnit unit tests for the device tree overlay code.
+
+ If unsure, say N here, but this option is safe to enable.
+
config OF_NUMA
bool
@@ -24,5 +24,6 @@ obj-$(CONFIG_KUNIT) += of_kunit.o
DTC_FLAGS_kunit += -@
obj-$(CONFIG_OF_KUNIT) += kunit.dtbo.o
obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o
+obj-$(CONFIG_OF_OVERLAY_KUNIT_TEST) += overlay_test.o kunit_overlay_test.dtbo.o
obj-$(CONFIG_OF_UNITTEST) += unittest-data/
new file mode 100644
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+&kunit_bus {
+ test-kunit {
+ compatible = "test,kunit-empty";
+ };
+};
new file mode 100644
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for device tree overlays
+ */
+#include <linux/device/bus.h>
+#include <linux/kconfig.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <kunit/of.h>
+#include <kunit/test.h>
+
+/* Test that of_overlay_apply_kunit() adds a node to the live tree */
+static void of_overlay_apply_kunit_apply(struct kunit *test)
+{
+ struct device_node *np;
+
+ KUNIT_ASSERT_EQ(test, 0,
+ of_overlay_apply_kunit(test, kunit_overlay_test));
+
+ np = of_find_node_by_name(NULL, "test-kunit");
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np);
+ of_node_put(np);
+}
+
+static int bus_match_np(struct device *dev, const void *data)
+{
+ const struct device_node *np = data;
+
+ return np == dev->of_node;
+}
+
+/*
+ * Test that of_overlay_apply_kunit() creates platform devices with the
+ * expected device_node
+ */
+static void of_overlay_apply_kunit_platform_device(struct kunit *test)
+{
+ struct device *dev;
+ struct device_node *np;
+
+ KUNIT_ASSERT_EQ(test, 0,
+ of_overlay_apply_kunit(test, kunit_overlay_test));
+
+ np = of_find_node_by_name(NULL, "test-kunit");
+ of_node_put_kunit(test, np);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np);
+
+ dev = bus_find_device(&platform_bus_type, NULL, np, bus_match_np);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev);
+ put_device(dev);
+}
+
+static int of_overlay_bus_match_compatible(struct device *dev, const void *data)
+{
+ return of_device_is_compatible(dev->of_node, data);
+}
+
+/* Test that of_overlay_apply_kunit() cleans up after the test is finished */
+static void of_overlay_apply_kunit_cleanup(struct kunit *test)
+{
+ struct device *dev;
+ struct device_node *np;
+
+ KUNIT_ASSERT_EQ(test, 0,
+ of_overlay_apply_kunit(test, kunit_overlay_test));
+
+ np = of_find_node_by_name(NULL, "test-kunit");
+ of_node_put(np); /* Not derefing 'np' after this */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np);
+
+ dev = bus_find_device(&platform_bus_type, NULL, np, bus_match_np);
+ put_device(dev); /* Not derefing 'device' after this */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ /* Remove overlay */
+ kunit_cleanup(test);
+
+ np = of_find_node_by_name(NULL, "test-kunit");
+ KUNIT_EXPECT_PTR_EQ(test, NULL, np);
+ of_node_put(np);
+
+ dev = bus_find_device(&platform_bus_type, NULL, "test,kunit-empty",
+ of_overlay_bus_match_compatible);
+ KUNIT_EXPECT_PTR_EQ(test, NULL, dev);
+ put_device(dev);
+}
+
+static struct kunit_case of_overlay_apply_kunit_test_cases[] = {
+ KUNIT_CASE(of_overlay_apply_kunit_apply),
+ KUNIT_CASE(of_overlay_apply_kunit_platform_device),
+ KUNIT_CASE(of_overlay_apply_kunit_cleanup),
+ {}
+};
+
+/*
+ * Test suite for test managed device tree overlays.
+ */
+static struct kunit_suite of_overlay_apply_kunit_suite = {
+ .name = "of_overlay_apply_kunit",
+ .test_cases = of_overlay_apply_kunit_test_cases,
+};
+
+kunit_test_suites(
+ &of_overlay_apply_kunit_suite,
+);
+MODULE_LICENSE("GPL");