diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
index 65f6577113235749c3635dc30d321fa3c775b1c0..8d39677b7d4c8922bd285e24d1c2fe82645e9fe1 100644
--- a/arch/arm/boot/dts/versatile-pb.dts
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -46,5 +46,3 @@ mmc@b000 {
 		};
 	};
 };
-
-#include <testcases.dtsi>
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 2dcb0541012d0133a417cc18ff2cd7ec2acbee2f..868f3712bc67462df07a01c910a996c33a2a8d22 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -10,6 +10,7 @@ menu "Device Tree and Open Firmware support"
 config OF_SELFTEST
 	bool "Device Tree Runtime self tests"
 	depends on OF_IRQ
+	select OF_DYNAMIC
 	help
 	  This option builds in test cases for the device tree infrastructure
 	  that are executed once at boot time, and the results dumped to the
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 099b1fb00af4ac6fd09be4341919cfeb84e45634..b9e753b56964b6dd747f7cca882865c799773d5d 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -5,7 +5,8 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_NET)	+= of_net.o
-obj-$(CONFIG_OF_SELFTEST) += selftest.o
+obj-$(CONFIG_OF_SELFTEST) += of_selftest.o
+of_selftest-objs := selftest.o testcase-data/testcases.dtb.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 077314eebb95c785b1f1cb8f46790f6004464ee3..df599db1554c25a99acc73a9ee8335391c82700e 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_fdt.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/list.h>
@@ -21,6 +22,10 @@ static struct selftest_results {
 	int failed;
 } selftest_results;
 
+#define NO_OF_NODES 2
+static struct device_node *nodes[NO_OF_NODES];
+static int last_node_index;
+
 #define selftest(result, fmt, ...) { \
 	if (!(result)) { \
 		selftest_results.failed++; \
@@ -517,9 +522,156 @@ static void __init of_selftest_platform_populate(void)
 	}
 }
 
+/**
+ *	update_node_properties - adds the properties
+ *	of np into dup node (present in live tree) and
+ *	updates parent of children of np to dup.
+ *
+ *	@np:	node already present in live tree
+ *	@dup:	node present in live tree to be updated
+ */
+static void update_node_properties(struct device_node *np,
+					struct device_node *dup)
+{
+	struct property *prop;
+	struct device_node *child;
+
+	for_each_property_of_node(np, prop)
+		of_add_property(dup, prop);
+
+	for_each_child_of_node(np, child)
+		child->parent = dup;
+}
+
+/**
+ *	attach_node_and_children - attaches nodes
+ *	and its children to live tree
+ *
+ *	@np:	Node to attach to live tree
+ */
+static int attach_node_and_children(struct device_node *np)
+{
+	struct device_node *next, *root = np, *dup;
+
+	if (!np) {
+		pr_warn("%s: No tree to attach; not running tests\n",
+			__func__);
+		return -ENODATA;
+	}
+
+
+	/* skip root node */
+	np = np->child;
+	/* storing a copy in temporary node */
+	dup = np;
+
+	while (dup) {
+		nodes[last_node_index++] = dup;
+		dup = dup->sibling;
+	}
+	dup = NULL;
+
+	while (np) {
+		next = np->allnext;
+		dup = of_find_node_by_path(np->full_name);
+		if (dup)
+			update_node_properties(np, dup);
+		else {
+			np->child = NULL;
+			if (np->parent == root)
+				np->parent = of_allnodes;
+			of_attach_node(np);
+		}
+		np = next;
+	}
+
+	return 0;
+}
+
+/**
+ *	selftest_data_add - Reads, copies data from
+ *	linked tree and attaches it to the live tree
+ */
+static int __init selftest_data_add(void)
+{
+	void *selftest_data;
+	struct device_node *selftest_data_node;
+	extern uint8_t __dtb_testcases_begin[];
+	extern uint8_t __dtb_testcases_end[];
+	const int size = __dtb_testcases_end - __dtb_testcases_begin;
+
+	if (!size || !of_allnodes) {
+		pr_warn("%s: No testcase data to attach; not running tests\n",
+			__func__);
+		return -ENODATA;
+	}
+
+	/* creating copy */
+	selftest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL);
+
+	if (!selftest_data) {
+		pr_warn("%s: Failed to allocate memory for selftest_data; "
+			"not running tests\n", __func__);
+		return -ENOMEM;
+	}
+	of_fdt_unflatten_tree(selftest_data, &selftest_data_node);
+
+	/* attach the sub-tree to live tree */
+	return attach_node_and_children(selftest_data_node);
+}
+
+/**
+ *	detach_node_and_children - detaches node
+ *	and its children from live tree
+ *
+ *	@np:	Node to detach from live tree
+ */
+static void detach_node_and_children(struct device_node *np)
+{
+	while (np->child)
+		detach_node_and_children(np->child);
+
+	while (np->sibling)
+		detach_node_and_children(np->sibling);
+
+	of_detach_node(np);
+}
+
+/**
+ *	selftest_data_remove - removes the selftest data
+ *	nodes from the live tree
+ */
+static void selftest_data_remove(void)
+{
+	struct device_node *np;
+	struct property *prop;
+
+	while (last_node_index >= 0) {
+		if (nodes[last_node_index]) {
+			np = of_find_node_by_path(nodes[last_node_index]->full_name);
+			if (strcmp(np->full_name, "/aliases") != 0) {
+				detach_node_and_children(np->child);
+				of_detach_node(np);
+			} else {
+				for_each_property_of_node(np, prop) {
+					if (strcmp(prop->name, "testcase-alias") == 0)
+						of_remove_property(np, prop);
+				}
+			}
+		}
+		last_node_index--;
+	}
+}
+
 static int __init of_selftest(void)
 {
 	struct device_node *np;
+	int res;
+
+	/* adding data for selftest */
+	res = selftest_data_add();
+	if (res)
+		return res;
 
 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
 	if (!np) {
@@ -539,6 +691,10 @@ static int __init of_selftest(void)
 	of_selftest_platform_populate();
 	pr_info("end of selftest - %i passed, %i failed\n",
 		selftest_results.passed, selftest_results.failed);
+
+	/* removing selftest data from live tree */
+	selftest_data_remove();
+
 	return 0;
 }
 late_initcall(of_selftest);
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dts
similarity index 92%
rename from drivers/of/testcase-data/testcases.dtsi
rename to drivers/of/testcase-data/testcases.dts
index 6d8d980ac858e732faa203f78a5a9357756eb67b..8e7568ee31750402d708a1be3179388d65201520 100644
--- a/drivers/of/testcase-data/testcases.dtsi
+++ b/drivers/of/testcase-data/testcases.dts
@@ -1,3 +1,4 @@
+/dts-v1/;
 #include "tests-phandle.dtsi"
 #include "tests-interrupts.dtsi"
 #include "tests-match.dtsi"