diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ea1732e..865737a 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1549,14 +1549,16 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (!dev->power.is_rpm_sleep)
+				dev->parent->power.direct_complete = false;
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;
 
 			spin_unlock_irq(&parent->power.lock);
 		}
-		dpm_clear_suppliers_direct_complete(dev);
+		if (!dev->power.is_rpm_sleep)
+			dpm_clear_suppliers_direct_complete(dev);
 	}
 
 	device_unlock(dev);
@@ -1709,11 +1711,14 @@ static int device_prepare(struct device *dev, pm_message_t state)
 	 * A positive return value from ->prepare() means "this device appears
 	 * to be runtime-suspended and its state is fine, so if it really is
 	 * runtime-suspended, you can leave it in that state provided that you
-	 * will do the same thing with all of its descendants".  This only
-	 * applies to suspend transitions, however.
+	 * will do the same thing with all of its descendants". To allow this,
+	 * the is_rpm_sleep flag must not be set, which is default false, but
+	 * may have been changed by a driver. This only applies to suspend
+	 * transitions, however.
 	 */
 	spin_lock_irq(&dev->power.lock);
-	dev->power.direct_complete = ret > 0 && state.event == PM_EVENT_SUSPEND;
+	dev->power.direct_complete = ret > 0 && !dev->power.is_rpm_sleep &&
+				state.event == PM_EVENT_SUSPEND;
 	spin_unlock_irq(&dev->power.lock);
 	return 0;
 }
@@ -1841,6 +1846,40 @@ void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
 }
 EXPORT_SYMBOL_GPL(dpm_for_each_dev);
 
+/**
+ * dev_pm_use_rpm_sleep - use the runtime PM centric sleep path.
+ * @dev: the device to use the path for.
+ *
+ * The runtime PM centric path requires the system sleep callbacks for the
+ * driver of the device to be invoked. This function sets the is_rpm_sleep flag
+ * to enable this path to be used, which makes the PM core to adopt to this
+ * behaviour. More precisely the PM core makes sure to not run the
+ * direct_complete path for the chosen device during system sleep, when the
+ * is_rpm_sleep flag is set. A driver using the runtime PM centric path, shall
+ * use the pm_runtime_force_suspend|resume() helpers, to deploy system sleep
+ * support and call this function during ->probe().
+ * The is_rpm_sleep flag is cleared when unbinding/bind-failure of the driver.
+ */
+void dev_pm_use_rpm_sleep(struct device *dev)
+{
+	dev->power.is_rpm_sleep = true;
+}
+EXPORT_SYMBOL_GPL(dev_pm_use_rpm_sleep);
+
+/**
+ * dev_pm_is_rpm_sleep - Returns the value of the is_rpm_sleep flag.
+ * @dev: the device to return the flag for.
+ *
+ * The caller of this function is typically a subsystem or a PM domain that
+ * needs to know if the runtime PM centric path is used for the device. It may
+ * be invoked during any of the system sleep phases.
+ */
+bool dev_pm_is_rpm_sleep(struct device *dev)
+{
+	return dev->power.is_rpm_sleep;
+}
+EXPORT_SYMBOL_GPL(dev_pm_is_rpm_sleep);
+
 static bool pm_ops_is_empty(const struct dev_pm_ops *ops)
 {
 	if (!ops)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 7bcf80f..b2ab22c 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1522,6 +1522,7 @@ void pm_runtime_reinit(struct device *dev)
 				pm_runtime_put(dev->parent);
 		}
 	}
+	dev->power.is_rpm_sleep = false;
 }
 
 /**
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 47ded8a..5bf96d2 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -559,6 +559,7 @@ struct dev_pm_info {
 	bool			is_suspended:1;	/* Ditto */
 	bool			is_noirq_suspended:1;
 	bool			is_late_suspended:1;
+	bool			is_rpm_sleep:1;	/* Owned by the PM core */
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
 	spinlock_t		lock;
@@ -716,6 +717,9 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
 extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);
 extern void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *));
 
+extern void dev_pm_use_rpm_sleep(struct device *dev);
+extern bool dev_pm_is_rpm_sleep(struct device *dev);
+
 extern int pm_generic_prepare(struct device *dev);
 extern int pm_generic_suspend_late(struct device *dev);
 extern int pm_generic_suspend_noirq(struct device *dev);
@@ -759,6 +763,9 @@ static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void
 {
 }
 
+static inline void dev_pm_use_rpm_sleep(struct device *dev) {}
+static inline bool dev_pm_is_rpm_sleep(struct device *dev) { return false; }
+
 #define pm_generic_prepare		NULL
 #define pm_generic_suspend_late		NULL
 #define pm_generic_suspend_noirq	NULL
