aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-12 04:24:13 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-12 04:24:13 -0400
commitb06c0b2f087ab498d51d50f5ae353133b602f614 (patch)
tree08209ebe683ce27a9c7f755c8c05b853a407ca6f
parent2d5ed61ce9820a1fe7b076cc45c169524d767746 (diff)
Revert "PM / runtime: Fixup reference counting of device link suppliers at probe"
Revert commit 1e8378619841 (PM / runtime: Fixup reference counting of device link suppliers at probe), as it has introduced a regression and the condition it was designed to address should be covered by the existing code. Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/power/runtime.c27
-rw-r--r--include/linux/pm_runtime.h6
3 files changed, 30 insertions, 6 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a41c91bfac0e..10454fe54482 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -580,7 +580,7 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
580 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 580 pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
581 drv->bus->name, __func__, dev_name(dev), drv->name); 581 drv->bus->name, __func__, dev_name(dev), drv->name);
582 582
583 pm_runtime_resume_suppliers(dev); 583 pm_runtime_get_suppliers(dev);
584 if (dev->parent) 584 if (dev->parent)
585 pm_runtime_get_sync(dev->parent); 585 pm_runtime_get_sync(dev->parent);
586 586
@@ -591,6 +591,7 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
591 if (dev->parent) 591 if (dev->parent)
592 pm_runtime_put(dev->parent); 592 pm_runtime_put(dev->parent);
593 593
594 pm_runtime_put_suppliers(dev);
594 return ret; 595 return ret;
595} 596}
596 597
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index c6030f100c08..beb85c31f3fa 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1563,16 +1563,37 @@ void pm_runtime_clean_up_links(struct device *dev)
1563} 1563}
1564 1564
1565/** 1565/**
1566 * pm_runtime_resume_suppliers - Resume supplier devices. 1566 * pm_runtime_get_suppliers - Resume and reference-count supplier devices.
1567 * @dev: Consumer device. 1567 * @dev: Consumer device.
1568 */ 1568 */
1569void pm_runtime_resume_suppliers(struct device *dev) 1569void pm_runtime_get_suppliers(struct device *dev)
1570{ 1570{
1571 struct device_link *link;
1571 int idx; 1572 int idx;
1572 1573
1573 idx = device_links_read_lock(); 1574 idx = device_links_read_lock();
1574 1575
1575 rpm_get_suppliers(dev); 1576 list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1577 if (link->flags & DL_FLAG_PM_RUNTIME)
1578 pm_runtime_get_sync(link->supplier);
1579
1580 device_links_read_unlock(idx);
1581}
1582
1583/**
1584 * pm_runtime_put_suppliers - Drop references to supplier devices.
1585 * @dev: Consumer device.
1586 */
1587void pm_runtime_put_suppliers(struct device *dev)
1588{
1589 struct device_link *link;
1590 int idx;
1591
1592 idx = device_links_read_lock();
1593
1594 list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1595 if (link->flags & DL_FLAG_PM_RUNTIME)
1596 pm_runtime_put(link->supplier);
1576 1597
1577 device_links_read_unlock(idx); 1598 device_links_read_unlock(idx);
1578} 1599}
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index db5dbbf7a48d..f0fc4700b6ff 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -56,7 +56,8 @@ extern void pm_runtime_update_max_time_suspended(struct device *dev,
56 s64 delta_ns); 56 s64 delta_ns);
57extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable); 57extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
58extern void pm_runtime_clean_up_links(struct device *dev); 58extern void pm_runtime_clean_up_links(struct device *dev);
59extern void pm_runtime_resume_suppliers(struct device *dev); 59extern void pm_runtime_get_suppliers(struct device *dev);
60extern void pm_runtime_put_suppliers(struct device *dev);
60extern void pm_runtime_new_link(struct device *dev); 61extern void pm_runtime_new_link(struct device *dev);
61extern void pm_runtime_drop_link(struct device *dev); 62extern void pm_runtime_drop_link(struct device *dev);
62 63
@@ -172,7 +173,8 @@ static inline unsigned long pm_runtime_autosuspend_expiration(
172static inline void pm_runtime_set_memalloc_noio(struct device *dev, 173static inline void pm_runtime_set_memalloc_noio(struct device *dev,
173 bool enable){} 174 bool enable){}
174static inline void pm_runtime_clean_up_links(struct device *dev) {} 175static inline void pm_runtime_clean_up_links(struct device *dev) {}
175static inline void pm_runtime_resume_suppliers(struct device *dev) {} 176static inline void pm_runtime_get_suppliers(struct device *dev) {}
177static inline void pm_runtime_put_suppliers(struct device *dev) {}
176static inline void pm_runtime_new_link(struct device *dev) {} 178static inline void pm_runtime_new_link(struct device *dev) {}
177static inline void pm_runtime_drop_link(struct device *dev) {} 179static inline void pm_runtime_drop_link(struct device *dev) {}
178 180