diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 33a3945c023e..9cc0ce43b47b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -125,6 +125,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
 #define genpd_unlock(p)			p->lock_ops->unlock(p)
 
 #define genpd_status_on(genpd)		(genpd->status == GENPD_STATE_ON)
+#define genpd_boot_keep_on(genpd)	(!(genpd->boot_status == GENPD_STATE_OFF))
 #define genpd_is_irq_safe(genpd)	(genpd->flags & GENPD_FLAG_IRQ_SAFE)
 #define genpd_is_always_on(genpd)	(genpd->flags & GENPD_FLAG_ALWAYS_ON)
 #define genpd_is_active_wakeup(genpd)	(genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
@@ -654,6 +655,29 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
 	queue_work(pm_wq, &genpd->power_off_work);
 }
 
+/**
+ * pm_genpd_power_off_unused_sync_state - Power off all domains for provider.
+ * @dev: Provider's device.
+ *
+ * Request power off for all unused domains of the provider.
+ * This should be used exclusively as sync state callback for genpd providers.
+ */
+void pm_genpd_power_off_unused_sync_state(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
+
+	mutex_lock(&gpd_list_lock);
+
+	list_for_each_entry(genpd, &gpd_list, gpd_list_node)
+		if (genpd->provider->dev == dev && genpd_boot_keep_on(genpd)) {
+			genpd->boot_status = GENPD_STATE_OFF;
+			genpd_queue_power_off_work(genpd);
+		}
+
+	mutex_unlock(&gpd_list_lock);
+}
+EXPORT_SYMBOL_GPL(pm_genpd_power_off_unused_sync_state);
+
 /**
  * genpd_power_off - Remove power from a given PM domain.
  * @genpd: PM domain to power down.
@@ -674,6 +698,12 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
 	unsigned int not_suspended = 0;
 	int ret;
 
+	/*
+	 * If the domain was left enabled at boot stage,
+	 * abort power off until sync state is reached.
+	 */
+	if (genpd_boot_keep_on(genpd))
+		return -EBUSY;
 	/*
 	 * Do not try to power off the domain in the following situations:
 	 * (1) The domain is already in the "power off" state.
@@ -763,6 +793,12 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
 	struct gpd_link *link;
 	int ret = 0;
 
+	/*
+	 * Just in case this is the first power on request, mark the boot
+	 * status of it as 'off'.
+	 */
+	genpd->boot_status = GENPD_STATE_OFF;
+
 	if (genpd_status_on(genpd))
 		return 0;
 
@@ -1095,8 +1131,16 @@ static int __init genpd_power_off_unused(void)
 
 	mutex_lock(&gpd_list_lock);
 
+	/*
+	 * If the provider has registered a 'sync state' callback,
+	 * assume that callback will power off its registered unused domains,
+	 * otherwise we power them off from here.
+	 */
 	list_for_each_entry(genpd, &gpd_list, gpd_list_node)
-		genpd_queue_power_off_work(genpd);
+		if (!dev_has_sync_state(&genpd->dev)) {
+			genpd->boot_status = GENPD_STATE_OFF;
+			genpd_queue_power_off_work(genpd);
+		}
 
 	mutex_unlock(&gpd_list_lock);
 
@@ -1124,6 +1168,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
 {
 	struct gpd_link *link;
 
+	if (genpd_boot_keep_on(genpd))
+		return;
+
 	if (!genpd_status_on(genpd) || genpd_is_always_on(genpd))
 		return;
 
@@ -2064,7 +2111,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 	genpd->gov = gov;
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	atomic_set(&genpd->sd_count, 0);
-	genpd->status = boot_status;
+	genpd->status = genpd->boot_status = boot_status;
 	genpd->device_count = 0;
 	genpd->provider = NULL;
 	genpd->has_provider = false;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index c545e44ee52b..86bb531a319c 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -132,6 +132,7 @@ struct generic_pm_domain {
 	const char *name;
 	atomic_t sd_count;	/* Number of subdomains with power "on" */
 	enum gpd_status status;	/* Current state of the domain */
+	enum gpd_status boot_status;	/* Boot state of the domain */
 	unsigned int device_count;	/* Number of devices */
 	unsigned int suspended_count;	/* System suspend device counter */
 	unsigned int prepared_count;	/* Suspend counter of prepared devices */
@@ -233,6 +234,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 		  struct dev_power_governor *gov,
 		  enum gpd_status boot_status);
 int pm_genpd_remove(struct generic_pm_domain *genpd);
+void pm_genpd_power_off_unused_sync_state(struct device *dev);
 int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
 int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb);
 int dev_pm_genpd_remove_notifier(struct device *dev);
@@ -281,6 +283,9 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
 	return -EOPNOTSUPP;
 }
 
+static inline void pm_genpd_power_off_unused_sync_state(struct device *dev)
+{ }
+
 static inline int dev_pm_genpd_set_performance_state(struct device *dev,
 						     unsigned int state)
 {
