Skip to content

Commit 874dfb5

Browse files
rafaeljwgregkh
authored andcommitted
PM: runtime: Drop runtime PM references to supplier on link removal
commit e0e398e upstream. While removing a device link, drop the supplier device's runtime PM usage counter as many times as needed to drop all of the runtime PM references to it from the consumer in addition to dropping the consumer's link count. Fixes: baa8809 ("PM / runtime: Optimize the use of device links") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: 5.1+ <stable@vger.kernel.org> # 5.1+ Tested-by: Xiang Chen <chenxiang66@hisilicon.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent fbfca92 commit 874dfb5

3 files changed

Lines changed: 24 additions & 7 deletions

File tree

drivers/base/core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,7 @@ static void __device_link_del(struct kref *kref)
454454
dev_dbg(link->consumer, "Dropping the link to %s\n",
455455
dev_name(link->supplier));
456456

457-
if (link->flags & DL_FLAG_PM_RUNTIME)
458-
pm_runtime_drop_link(link->consumer);
457+
pm_runtime_drop_link(link);
459458

460459
list_del_rcu(&link->s_node);
461460
list_del_rcu(&link->c_node);
@@ -469,8 +468,7 @@ static void __device_link_del(struct kref *kref)
469468
dev_info(link->consumer, "Dropping the link to %s\n",
470469
dev_name(link->supplier));
471470

472-
if (link->flags & DL_FLAG_PM_RUNTIME)
473-
pm_runtime_drop_link(link->consumer);
471+
pm_runtime_drop_link(link);
474472

475473
list_del(&link->s_node);
476474
list_del(&link->c_node);

drivers/base/power/runtime.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,14 +1702,33 @@ void pm_runtime_new_link(struct device *dev)
17021702
spin_unlock_irq(&dev->power.lock);
17031703
}
17041704

1705-
void pm_runtime_drop_link(struct device *dev)
1705+
static void pm_runtime_drop_link_count(struct device *dev)
17061706
{
17071707
spin_lock_irq(&dev->power.lock);
17081708
WARN_ON(dev->power.links_count == 0);
17091709
dev->power.links_count--;
17101710
spin_unlock_irq(&dev->power.lock);
17111711
}
17121712

1713+
/**
1714+
* pm_runtime_drop_link - Prepare for device link removal.
1715+
* @link: Device link going away.
1716+
*
1717+
* Drop the link count of the consumer end of @link and decrement the supplier
1718+
* device's runtime PM usage counter as many times as needed to drop all of the
1719+
* PM runtime reference to it from the consumer.
1720+
*/
1721+
void pm_runtime_drop_link(struct device_link *link)
1722+
{
1723+
if (!(link->flags & DL_FLAG_PM_RUNTIME))
1724+
return;
1725+
1726+
pm_runtime_drop_link_count(link->consumer);
1727+
1728+
while (refcount_dec_not_one(&link->rpm_active))
1729+
pm_runtime_put(link->supplier);
1730+
}
1731+
17131732
static bool pm_runtime_need_not_resume(struct device *dev)
17141733
{
17151734
return atomic_read(&dev->power.usage_count) <= 1 &&

include/linux/pm_runtime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern void pm_runtime_clean_up_links(struct device *dev);
5858
extern void pm_runtime_get_suppliers(struct device *dev);
5959
extern void pm_runtime_put_suppliers(struct device *dev);
6060
extern void pm_runtime_new_link(struct device *dev);
61-
extern void pm_runtime_drop_link(struct device *dev);
61+
extern void pm_runtime_drop_link(struct device_link *link);
6262

6363
static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
6464
{
@@ -177,7 +177,7 @@ static inline void pm_runtime_clean_up_links(struct device *dev) {}
177177
static inline void pm_runtime_get_suppliers(struct device *dev) {}
178178
static inline void pm_runtime_put_suppliers(struct device *dev) {}
179179
static inline void pm_runtime_new_link(struct device *dev) {}
180-
static inline void pm_runtime_drop_link(struct device *dev) {}
180+
static inline void pm_runtime_drop_link(struct device_link *link) {}
181181

182182
#endif /* !CONFIG_PM */
183183

0 commit comments

Comments
 (0)