diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 18fc6a08569e..9ac6d4e2a762 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -15,3 +15,5 @@ source "drivers/platform/mellanox/Kconfig"
 source "drivers/platform/olpc/Kconfig"
 
 source "drivers/platform/surface/Kconfig"
+
+source "drivers/platform/of/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 4de08ef4ec9d..ca4d74701fd7 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OLPC_EC)		+= olpc/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS)	+= chrome/
 obj-$(CONFIG_SURFACE_PLATFORMS)	+= surface/
+obj-$(CONFIG_PLATFORM_OF_DRV)	+= of/
diff --git a/drivers/platform/of/Kconfig b/drivers/platform/of/Kconfig
new file mode 100644
index 000000000000..a0b5a641a7c6
--- /dev/null
+++ b/drivers/platform/of/Kconfig
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# X86 Platform Specific Drivers
+#
+
+menuconfig PLATFORM_OF_DRV
+	tristate "Platform support via device tree"
+	select OF
+	select OF_FLATTREE
+	help
+	  Say Y here to get to see options for board support that's initialized
+	  via compiled-in flattened device trees.
+
+	  This is entirely independent from traditional DT-based booting (or DT
+	  overlays) and meant for additional devices on non-OF-based (eg. APCI)
+	  boards or composite devices behind probing-capable busses (eg. PCI).
+
+	  Instead of writing individual drivers for just the initialization of
+	  subdevices, this option provides a generic mechanism for describing
+	  these devices via device tree.
+
+	  If you say N, all options in this submenu will be skipped and disabled.
+
+if PLATFORM_OF_DRV
+
+config PLATFORM_OF_DRV_SYSFS_DTB
+	bool "Expose device tree binaries in sysfs"
+	default y
+	depends on SYSFS
+	help
+	  Say Y here to enable exposing device tree binaries at /sys/firmware.
+
+config PLATFORM_OF_DRV_SYSFS_DT
+	bool "Expose parsed device tree in sysfs"
+	default y
+	depends on SYSFS
+	help
+	  Say Y here to enable exposing device tree nodes at
+	  /sys/firmware/devicetree.
+
+endif # PLATFORM_OF_DRV
diff --git a/drivers/platform/of/Makefile b/drivers/platform/of/Makefile
new file mode 100644
index 000000000000..84cf3003c500
--- /dev/null
+++ b/drivers/platform/of/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+ofboard-y := init.o drv.o
+
+obj-$(CONFIG_PLATFORM_OF_DRV) += ofboard.o
diff --git a/drivers/platform/of/drv.c b/drivers/platform/of/drv.c
new file mode 100644
index 000000000000..ff7006c24cf7
--- /dev/null
+++ b/drivers/platform/of/drv.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright (C) 2021 metux IT consult
+ * Author: Enrico Weigelt <info@metux.net>
+ */
+
+#include <linux/dmi.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "ofboard.h"
+
+static bool __init ofboard_match_dmi(struct device *dev)
+{
+#ifdef CONFIG_DMI
+	const char *board = dmi_get_system_info(DMI_BOARD_NAME);
+	const char *vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+	const struct device_node *node = dev->of_node;
+
+	if (!of_match_string(node, "dmi-sys-vendor", vendor))
+		return false;
+
+	if (!of_match_string(node, "dmi-board-name", board))
+		return false;
+
+	dev_info(dev, "matched dmi: vendor=\"%s\" board=\"%s\"\n", vendor,
+		 board);
+
+	return true;
+#else
+	return false;
+#endif
+}
+
+static void __init ofboard_kick_devs(struct device *dev,
+				     struct device_node *np,
+				     const char *bus_name)
+{
+	struct property *prop;
+	const char *walk;
+	struct bus_type *bus;
+	int ret;
+
+	if (strcmp(bus_name, "name")==0)
+		return;
+
+	bus = find_bus(bus_name);
+	if (!bus) {
+		dev_warn(dev, "cant find bus \"%s\"\n", bus_name);
+		return;
+	}
+
+	of_property_for_each_string(np, bus_name, prop, walk) {
+		ret = bus_unregister_device_by_name(bus, walk);
+		if (ret)
+			dev_warn(dev, "failed removing device \"%s\" on bus "
+				 "\"%s\": %d\n", walk, bus_name, ret);
+		else
+			dev_info(dev, "removed device \"%s\" from bus "
+				 "\"%s\"\n", walk, bus_name);
+	}
+
+	bus_put(bus);
+}
+
+static void __init ofboard_unbind(struct device *dev)
+{
+	struct property *pr;
+	struct device_node *np = of_get_child_by_name(dev->of_node, "unbind");
+
+	if (!IS_ERR_OR_NULL(np))
+		for_each_property_of_node(np, pr)
+			ofboard_kick_devs(dev, np, pr->name);
+}
+
+static int ofboard_populate(struct device *dev)
+{
+	int ret;
+	struct device_node *of_node = dev->of_node;
+	struct device_node *np = of_get_child_by_name(of_node, "devices");
+
+	if (IS_ERR_OR_NULL(np)) {
+		dev_info(dev, "board oftree has no devices\n");
+		return -ENOENT;
+	}
+
+	ret = of_platform_populate(np, NULL, NULL, dev);
+	if (ret) {
+		dev_err(dev, "failed probing of childs: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ofboard_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	if (!ofboard_match_dmi(dev))
+		return -EINVAL;
+
+	ofboard_unbind(&pdev->dev);
+
+	return ofboard_populate(dev);
+}
+
+static const struct of_device_id ofboard_of_match[] = {
+	{ .compatible = "virtual,dmi-board" },
+	{}
+};
+
+struct platform_driver ofboard_driver = {
+	.driver = {
+		.name = "ofboard",
+		.of_match_table = ofboard_of_match,
+	},
+	.probe = ofboard_probe,
+};
diff --git a/drivers/platform/of/init.c b/drivers/platform/of/init.c
new file mode 100644
index 000000000000..3b8373cda77a
--- /dev/null
+++ b/drivers/platform/of/init.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright (C) 2021 metux IT consult
+ * Author: Enrico Weigelt <info@metux.net>
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include "ofboard.h"
+
+#define DECLARE_FDT_EXTERN(n) \
+	extern char __dtb_##n##_begin[]; \
+	static struct bin_attribute __dtb_##n##_attr = { \
+		.attr = { .name = "fdt-" #n, .mode = S_IRUSR }, \
+		.private = __dtb_##n##_begin, \
+		.read = fdt_image_raw_read, \
+	};
+
+struct fdt_image {
+	char *begin;
+	size_t size;
+	char *basename;
+	struct bin_attribute *bin_attr;
+	struct device_node *root;
+};
+
+#define FDT_IMAGE_ENT(n)			\
+	{					\
+		.begin = __dtb_##n##_begin,	\
+		.bin_attr = &__dtb_##n##_attr,	\
+		.basename = "ofboard-" #n	\
+	}
+
+static ssize_t fdt_image_raw_read(struct file *filep, struct kobject *kobj,
+				  struct bin_attribute *bin_attr, char *buf,
+				  loff_t off, size_t count)
+{
+	memcpy(buf, bin_attr->private + off, count);
+	return count;
+}
+
+static struct fdt_image fdt[] = {
+};
+
+static int __init ofdrv_init_sysfs(struct fdt_image *image)
+{
+	image->bin_attr->size = image->size;
+	image->bin_attr->private = image->begin;
+
+	if (sysfs_create_bin_file(firmware_kobj, image->bin_attr))
+		pr_warn("failed creating sysfs bin_file\n");
+
+	of_attach_tree_sysfs(image->root, image->basename);
+
+	return 0;
+}
+
+static int __init ofdrv_parse_image(struct fdt_image *image)
+{
+	struct device_node* root;
+	void *new_fdt;
+
+	image->size = fdt_totalsize(image->begin);
+	new_fdt = kmemdup(image->begin, image->size, GFP_KERNEL);
+	if (!new_fdt)
+		return -ENOMEM;
+
+	image->begin = new_fdt;
+	of_fdt_unflatten_tree(new_fdt, NULL, &root);
+
+	if (IS_ERR_OR_NULL(root))
+		return PTR_ERR(root);
+
+	image->root = root;
+
+	return 0;
+}
+
+static int __init ofdrv_init_image(struct fdt_image *image)
+{
+	struct device_node *np;
+	int ret;
+
+	ret = ofdrv_parse_image(image);
+	if (ret)
+		return ret;
+
+	ofdrv_init_sysfs(image);
+
+	for_each_child_of_node(image->root, np) {
+		struct platform_device_info pdevinfo = {
+			.name = np->name,
+			.fwnode = &np->fwnode,
+			.id = PLATFORM_DEVID_NONE,
+		};
+		platform_device_register_full(&pdevinfo);
+	}
+
+	return 0;
+}
+
+static int __init ofdrv_init(void)
+{
+	int x;
+
+	platform_driver_register(&ofboard_driver);
+
+	for (x=0; x<ARRAY_SIZE(fdt); x++)
+		ofdrv_init_image(&fdt[x]);
+
+	return 0;
+}
+
+module_init(ofdrv_init);
+
+MODULE_AUTHOR("Enrico Weigelt, metux IT consult <info@metux.net>");
+MODULE_DESCRIPTION("Generic oftree based initialization of custom board devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/of/ofboard.h b/drivers/platform/of/ofboard.h
new file mode 100644
index 000000000000..7516e5df4f18
--- /dev/null
+++ b/drivers/platform/of/ofboard.h
@@ -0,0 +1,8 @@
+#ifndef __DRIVERS_PLATFORM_OFBOARD_H
+#define __DRIVERS_PLATFORM_OFBOARD_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_driver ofboard_driver;
+
+#endif
