diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index fe47d38..5b9dc22 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -55,6 +55,7 @@ static LIST_HEAD(regulator_map_list);
 static LIST_HEAD(regulator_ena_gpio_list);
 static LIST_HEAD(regulator_supply_alias_list);
 static bool has_full_constraints;
+static bool regulator_has_booted;
 
 static struct dentry *debugfs_root;
 
@@ -139,7 +140,15 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
 		return false;
 	}
 
-	if (rdev->constraints->valid_ops_mask & ops)
+	/*
+	 * Ignore regulator boot-protection, after later_initcall.
+	 */
+	if (!regulator_has_booted && rdev->constraints->boot_protection) {
+		if (rdev->constraints->boot_valid_ops_mask & ops)
+			return true;
+		else
+			rdev_info(rdev, "rejected operation 0x%02x\n", ops);
+	} else if (rdev->constraints->valid_ops_mask & ops)
 		return true;
 
 	return false;
@@ -868,7 +877,7 @@ static void print_constraints(struct regulator_dev *rdev)
 	rdev_dbg(rdev, "%s\n", buf);
 
 	if ((constraints->min_uV != constraints->max_uV) &&
-	    !regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
+	    !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
 		rdev_warn(rdev,
 			  "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
 }
@@ -1309,7 +1318,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 	 * it is then we don't need to do nearly so much work for
 	 * enable/disable calls.
 	 */
-	if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS) &&
+	if (rdev->constraints &&
+	    !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) &&
 	    _regulator_is_enabled(rdev))
 		regulator->always_on = true;
 
@@ -4353,6 +4363,12 @@ static int __init regulator_late_cleanup(struct device *dev, void *data)
 	struct regulation_constraints *c = rdev->constraints;
 	int enabled, ret;
 
+	/*
+	 * The kernel boot is finished, let's unset boot_protection
+	 * Need a lock?
+	 */
+	c->boot_protection = 0;
+
 	if (c && c->always_on)
 		return 0;
 
@@ -4406,6 +4422,8 @@ static int __init regulator_init_complete(void)
 	if (of_have_populated_dt())
 		has_full_constraints = true;
 
+	regulator_has_booted = true;
+
 	/* If we have a full configuration then disable any regulators
 	 * we have permission to change the status for and which are
 	 * not in use or always_on.  This is effectively the default
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 6b0aa80..bfec59c 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -78,6 +78,35 @@ static void of_get_regulation_constraints(struct device_node *np,
 	if (of_property_read_bool(np, "regulator-allow-set-load"))
 		constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;
 
+	constraints->boot_protection = of_property_read_bool(np,
+			"regulator-boot-protection");
+
+	if (constraints->boot_protection) {
+		if (of_property_read_bool(np, "boot-allow-set-voltage"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_VOLTAGE;
+		if (of_property_read_bool(np, "boot-allow-set-current"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_CURRENT;
+		if (of_property_read_bool(np, "boot-allow-set-mode"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_MODE;
+		if (of_property_read_bool(np, "boot-allow-set-status"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_STATUS;
+		if (of_property_read_bool(np, "boot-allow-set-load"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_DRMS;
+		if (of_property_read_bool(np, "boot-allow-bypass"))
+			constraints->boot_valid_ops_mask |=
+				REGULATOR_CHANGE_BYPASS;
+
+		/*
+		 * boot_valid_ops_mask is a subset of valid_ops_mask
+		 */
+		constraints->boot_valid_ops_mask &= constraints->valid_ops_mask;
+	}
+
 	ret = of_property_read_u32(np, "regulator-ramp-delay", &pval);
 	if (!ret) {
 		if (pval)
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 5d627c8..a4f5c0f 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -134,6 +134,7 @@ struct regulation_constraints {
 
 	/* valid operations for regulator on this machine */
 	unsigned int valid_ops_mask;
+	unsigned int boot_valid_ops_mask;
 
 	/* regulator input voltage - only if supply is another regulator */
 	int input_uV;
@@ -155,6 +156,7 @@ struct regulation_constraints {
 	/* constraint flags */
 	unsigned always_on:1;	/* regulator never off when system is on */
 	unsigned boot_on:1;	/* bootloader/firmware enabled regulator */
+	unsigned boot_protection:1;
 	unsigned apply_uV:1;	/* apply uV constraint if min == max */
 	unsigned ramp_disable:1; /* disable ramp delay */
 	unsigned soft_start:1;	/* ramp voltage slowly */
