diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-10-30 17:32:43 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-10-31 11:42:51 -0600 |
commit | baa8809f60971d10220dfe79248f54b2b265f003 (patch) | |
tree | 51a4d0c63734bdd7923c025e9ed4e0dd537e3c76 /drivers/base/core.c | |
parent | 21d5c57b3726166421251e94dabab047baaf8ce4 (diff) | |
download | lwn-baa8809f60971d10220dfe79248f54b2b265f003.tar.gz lwn-baa8809f60971d10220dfe79248f54b2b265f003.zip |
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.c | 20 |
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); |