* @supplier: Supplier end of the link.
  * @flags: Link flags.
  *
+ * The caller is responsible for the proper synchronization of the link creation
+ * with runtime PM.  First, setting the DL_FLAG_PM_RUNTIME flag will cause the
+ * runtime PM framework to take the link into account.  Second, if the
+ * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will
+ * be forced into the active metastate and reference-counted upon the creation
+ * of the link.  If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be
+ * ignored.
+ *
  * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically
  * when the consumer device driver unbinds from it.  The combination of both
  * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL
                if (link->consumer == consumer)
                        goto out;
 
-       link = kmalloc(sizeof(*link), GFP_KERNEL);
+       link = kzalloc(sizeof(*link), GFP_KERNEL);
        if (!link)
                goto out;
 
+       if ((flags & DL_FLAG_PM_RUNTIME) && (flags & DL_FLAG_RPM_ACTIVE)) {
+               if (pm_runtime_get_sync(supplier) < 0) {
+                       pm_runtime_put_noidle(supplier);
+                       kfree(link);
+                       link = NULL;
+                       goto out;
+               }
+               link->rpm_active = true;
+       }
        get_device(supplier);
        link->supplier = supplier;
        INIT_LIST_HEAD(&link->s_node);
                case DL_DEV_DRIVER_BOUND:
                        switch (consumer->links.status) {
                        case DL_DEV_PROBING:
+                               /*
+                                * Balance the decrementation of the supplier's
+                                * runtime PM usage counter after consumer probe
+                                * in driver_probe_device().
+                                */
+                               if (flags & DL_FLAG_PM_RUNTIME)
+                                       pm_runtime_get_sync(supplier);
+
                                link->status = DL_STATE_CONSUMER_PROBE;
                                break;
                        case DL_DEV_DRIVER_BOUND:
 
 #include <linux/pm_runtime.h>
 #include <linux/pm_wakeirq.h>
 #include <trace/events/rpm.h>
+
+#include "../base.h"
 #include "power.h"
 
 typedef int (*pm_callback_t)(struct device *);
        return retval;
 }
 
+static int rpm_get_suppliers(struct device *dev)
+{
+       struct device_link *link;
+
+       list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) {
+               int retval;
+
+               if (!(link->flags & DL_FLAG_PM_RUNTIME))
+                       continue;
+
+               if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND ||
+                   link->rpm_active)
+                       continue;
+
+               retval = pm_runtime_get_sync(link->supplier);
+               if (retval < 0) {
+                       pm_runtime_put_noidle(link->supplier);
+                       return retval;
+               }
+               link->rpm_active = true;
+       }
+       return 0;
+}
+
+static void rpm_put_suppliers(struct device *dev)
+{
+       struct device_link *link;
+
+       list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
+               if (link->rpm_active &&
+                   READ_ONCE(link->status) != DL_STATE_SUPPLIER_UNBIND) {
+                       pm_runtime_put(link->supplier);
+                       link->rpm_active = false;
+               }
+}
+
 /**
  * __rpm_callback - Run a given runtime PM callback for a given device.
  * @cb: Runtime PM callback to run.
 static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
        __releases(&dev->power.lock) __acquires(&dev->power.lock)
 {
-       int retval;
+       int retval, idx;
 
-       if (dev->power.irq_safe)
+       if (dev->power.irq_safe) {
                spin_unlock(&dev->power.lock);
-       else
+       } else {
                spin_unlock_irq(&dev->power.lock);
 
+               /*
+                * Resume suppliers if necessary.
+                *
+                * The device's runtime PM status cannot change until this
+                * routine returns, so it is safe to read the status outside of
+                * the lock.
+                */
+               if (dev->power.runtime_status == RPM_RESUMING) {
+                       idx = device_links_read_lock();
+
+                       retval = rpm_get_suppliers(dev);
+                       if (retval)
+                               goto fail;
+
+                       device_links_read_unlock(idx);
+               }
+       }
+
        retval = cb(dev);
 
-       if (dev->power.irq_safe)
+       if (dev->power.irq_safe) {
                spin_lock(&dev->power.lock);
-       else
+       } else {
+               /*
+                * If the device is suspending and the callback has returned
+                * success, drop the usage counters of the suppliers that have
+                * been reference counted on its resume.
+                *
+                * Do that if resume fails too.
+                */
+               if ((dev->power.runtime_status == RPM_SUSPENDING && !retval)
+                   || (dev->power.runtime_status == RPM_RESUMING && retval)) {
+                       idx = device_links_read_lock();
+
+ fail:
+                       rpm_put_suppliers(dev);
+
+                       device_links_read_unlock(idx);
+               }
+
                spin_lock_irq(&dev->power.lock);
+       }
 
        return retval;
 }
        pm_runtime_reinit(dev);
 }
 
+/**
+ * pm_runtime_clean_up_links - Prepare links to consumers for driver removal.
+ * @dev: Device whose driver is going to be removed.
+ *
+ * Check links from this device to any consumers and if any of them have active
+ * runtime PM references to the device, drop the usage counter of the device
+ * (once per link).
+ *
+ * Links with the DL_FLAG_STATELESS flag set are ignored.
+ *
+ * Since the device is guaranteed to be runtime-active at the point this is
+ * called, nothing else needs to be done here.
+ *
+ * Moreover, this is called after device_links_busy() has returned 'false', so
+ * the status of each link is guaranteed to be DL_STATE_SUPPLIER_UNBIND and
+ * therefore rpm_active can't be manipulated concurrently.
+ */
+void pm_runtime_clean_up_links(struct device *dev)
+{
+       struct device_link *link;
+       int idx;
+
+       idx = device_links_read_lock();
+
+       list_for_each_entry_rcu(link, &dev->links.consumers, s_node) {
+               if (link->flags & DL_FLAG_STATELESS)
+                       continue;
+
+               if (link->rpm_active) {
+                       pm_runtime_put_noidle(dev);
+                       link->rpm_active = false;
+               }
+       }
+
+       device_links_read_unlock(idx);
+}
+
+/**
+ * pm_runtime_get_suppliers - Resume and reference-count supplier devices.
+ * @dev: Consumer device.
+ */
+void pm_runtime_get_suppliers(struct device *dev)
+{
+       struct device_link *link;
+       int idx;
+
+       idx = device_links_read_lock();
+
+       list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
+               if (link->flags & DL_FLAG_PM_RUNTIME)
+                       pm_runtime_get_sync(link->supplier);
+
+       device_links_read_unlock(idx);
+}
+
+/**
+ * pm_runtime_put_suppliers - Drop references to supplier devices.
+ * @dev: Consumer device.
+ */
+void pm_runtime_put_suppliers(struct device *dev)
+{
+       struct device_link *link;
+       int idx;
+
+       idx = device_links_read_lock();
+
+       list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
+               if (link->flags & DL_FLAG_PM_RUNTIME)
+                       pm_runtime_put(link->supplier);
+
+       device_links_read_unlock(idx);
+}
+
 /**
  * pm_runtime_force_suspend - Force a device into suspend state if needed.
  * @dev: Device to suspend.