diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 6094b3b75184..0f47a5de585a 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -6,6 +6,9 @@ obj-y			:= component.o core.o bus.o dd.o syscore.o \
 			   attribute_container.o transport_class.o \
 			   topology.o container.o property.o cacheinfo.o
 obj-$(CONFIG_BOOT_CONSTRAINTS) += boot_constraint.o
+ifeq ($(CONFIG_OF),y)
+obj-$(CONFIG_BOOT_CONSTRAINTS) += boot_constraint_of.o
+endif
 obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
 obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
 obj-y			+= power/
diff --git a/drivers/base/base.h b/drivers/base/base.h
index e19b1008e5fb..9d6910cdbc8e 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -136,6 +136,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
 extern int devres_release_all(struct device *dev);
 extern void device_block_probing(void);
 extern void device_unblock_probing(void);
+extern void driver_enable_deferred_probe(void);
 
 /* /sys/devices directory */
 extern struct kset *devices_kset;
diff --git a/drivers/base/boot_constraint.c b/drivers/base/boot_constraint.c
index 4e3b5e1aec7c..80ac3f9aaa72 100644
--- a/drivers/base/boot_constraint.c
+++ b/drivers/base/boot_constraint.c
@@ -50,7 +50,7 @@ static DEFINE_MUTEX(constraint_devices_mutex);
 static int constraint_supply_add(struct constraint *constraint, void *data);
 static void constraint_supply_remove(struct constraint *constraint);
 
-static bool boot_constraints_disabled;
+bool boot_constraints_disabled;
 
 static int __init constraints_disable(char *str)
 {
diff --git a/drivers/base/boot_constraint_of.c b/drivers/base/boot_constraint_of.c
new file mode 100644
index 000000000000..671241b3d3a3
--- /dev/null
+++ b/drivers/base/boot_constraint_of.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 Linaro.
+ * Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#define pr_fmt(fmt) "Boot Constraints: " fmt
+
+#include <linux/boot_constraint.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "base.h"
+
+extern bool boot_constraints_disabled;
+
+struct boot_constraint_of_pdata {
+	struct device *dev;
+	enum boot_constraint_type type;
+	struct boot_constraint_supply_info info;
+};
+
+static void boot_constraint_add_supply(struct device *dev, int index)
+{
+	struct boot_constraint_of_pdata pdata = {
+		.dev = dev,
+		.type = BOOT_CONSTRAINT_SUPPLY,
+	};
+	struct boot_constraint_supply_info *info;
+	struct device_node *np = dev->of_node;
+	struct platform_device *pdev;
+	int ret;
+
+	info = &pdata.info;
+
+	ret = of_property_read_string_index(np, "boot-constraint-supplies",
+					    index, &info->name);
+	if (ret < 0) {
+		dev_err(dev, "%s: Failed to read supply at index %d (%d)\n",
+			__func__, index, ret);
+		return;
+	}
+
+	of_property_read_u32_index(np, "boot-constraint-uV", 2 * index,
+				   &info->u_volt_min);
+
+	of_property_read_u32_index(np, "boot-constraint-uV", 2 * index + 1,
+				   &info->u_volt_max);
+
+	pdev = platform_device_register_data(NULL, "boot-constraints-of", index,
+					     &pdata, sizeof(pdata));
+	if (IS_ERR(pdev)) {
+		dev_err(dev, "%s: Failed to create pdev for index %d (%d)\n",
+			__func__, index, ret);
+	}
+}
+
+static void boot_constraint_add_supplies(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	int i, count;
+
+	count = of_property_count_strings(np, "boot-constraint-supplies");
+	if (count <= 0)
+		return;
+
+	for (i = 0; i < count; i++)
+		boot_constraint_add_supply(dev, i);
+}
+
+void of_boot_constraint_init(struct device *dev)
+{
+	if (boot_constraints_disabled)
+		return;
+
+	BUG_ON(!dev->of_node);
+
+	boot_constraint_add_supplies(dev);
+}
+
+static void boot_constraint_remove_of(void *data)
+{
+	platform_device_unregister(data);
+}
+
+/*
+ * A platform device is added for each and every constraint, to handle
+ * -EPROBE_DEFER properly.
+ */
+static int boot_constraint_of_probe(struct platform_device *pdev)
+{
+	struct boot_constraint_of_pdata *pdata = dev_get_platdata(&pdev->dev);
+	struct boot_constraint_info info;
+	int ret;
+
+	BUG_ON(!pdata);
+
+	info.free_resources = boot_constraint_remove_of;
+	info.free_resources_data = pdev;
+	info.constraint_info = &pdata->info;
+
+	ret = boot_constraint_add(pdata->dev, pdata->type, &info);
+	if (ret == -EPROBE_DEFER)
+		driver_enable_deferred_probe();
+
+	return ret;
+}
+
+static struct platform_driver boot_constraint_of_driver = {
+	.driver = {
+		.name = "boot-constraints-of",
+	},
+	.probe = boot_constraint_of_probe,
+};
+
+static int __init boot_constraint_of_init(void)
+{
+	return platform_driver_register(&boot_constraint_of_driver);
+}
+core_initcall(boot_constraint_of_init);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 4eb9d183d647..aa761e13d8a7 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -204,6 +204,18 @@ void device_unblock_probing(void)
 }
 
 /**
+ * driver_enable_deferred_probe() - Enable probing of deferred devices
+ *
+ * We don't want to get in the way when the bulk of drivers are getting probed
+ * and so deferred probe is disabled in the beginning. Enable it now because we
+ * need it.
+ */
+void driver_enable_deferred_probe(void)
+{
+	driver_deferred_probe_enable = true;
+}
+
+/**
  * deferred_probe_initcall() - Enable probing of deferred devices
  *
  * We don't want to get in the way when the bulk of drivers are getting probed.
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 703a42118ffc..b88a1bf3e7fb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/amba/bus.h>
+#include <linux/boot_constraint.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
@@ -194,6 +195,8 @@ static struct platform_device *of_platform_device_create_pdata(
 		goto err_clear_flag;
 	}
 
+	of_boot_constraint_init(&dev->dev);
+
 	return dev;
 
 err_clear_flag:
@@ -271,6 +274,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 		goto err_free;
 	}
 
+	of_boot_constraint_init(&dev->dev);
 	return dev;
 
 err_free:
diff --git a/include/linux/boot_constraint.h b/include/linux/boot_constraint.h
index 110e5eca36c6..17bec71df228 100644
--- a/include/linux/boot_constraint.h
+++ b/include/linux/boot_constraint.h
@@ -33,10 +33,12 @@ struct boot_constraint_info {
 int boot_constraint_add(struct device *dev, enum boot_constraint_type type,
 			struct boot_constraint_info *info);
 void boot_constraints_remove(struct device *dev);
+void of_boot_constraint_init(struct device *dev);
 #else
 static inline int boot_constraint_add(struct device *dev,
 				      enum boot_constraint_type type,
 				      struct boot_constraint_info *info)
 { return -EINVAL; }
 static inline void boot_constraints_remove(struct device *dev) {}
+static inline void of_boot_constraint_init(struct device *dev) {}
 #endif
