summaryrefslogtreecommitdiff
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-10-30 17:32:43 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-10-31 11:42:51 -0600
commitbaa8809f60971d10220dfe79248f54b2b265f003 (patch)
tree51a4d0c63734bdd7923c025e9ed4e0dd537e3c76 /drivers/base/core.c
parent21d5c57b3726166421251e94dabab047baaf8ce4 (diff)
PM / runtime: Optimize the use of device links
If the device has no links to suppliers that should be used for runtime PM (links with DEVICE_LINK_PM_RUNTIME set), there is no reason to walk the list of suppliers for that device during runtime suspend and resume. Add a simple mechanism to detect that case and possibly avoid the extra unnecessary overhead. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 876c62b12462..d0c9df5cdd9e 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -205,14 +205,17 @@ struct device_link *device_link_add(struct device *consumer,
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;
+ if (flags & DL_FLAG_PM_RUNTIME) {
+ if (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;
}
- link->rpm_active = true;
+ pm_runtime_new_link(consumer);
}
get_device(supplier);
link->supplier = supplier;
@@ -296,6 +299,9 @@ static void __device_link_del(struct device_link *link)
dev_info(link->consumer, "Dropping the link to %s\n",
dev_name(link->supplier));
+ if (link->flags & DL_FLAG_PM_RUNTIME)
+ pm_runtime_drop_link(link->consumer);
+
list_del_rcu(&link->s_node);
list_del_rcu(&link->c_node);
call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu);