diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-06-15 18:02:34 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-07-01 07:31:29 -0400 |
commit | 80de3d7f416f1accd03f2e519ead32d6fde4fcf4 (patch) | |
tree | 4f6c5b3a6355fc6d9f6423b11afa28b119eb6dbc /drivers/base | |
parent | 0b589741b8b83a33e25fb32bb714ea1b972af5aa (diff) |
PM / Domains: Do not stop devices after restoring their states
While resuming a device belonging to a PM domain,
pm_genpd_runtime_resume() calls __pm_genpd_restore_device() to
restore its state, if necessary. The latter starts the device,
using genpd_start_dev(), restores its state, using
genpd_restore_dev(), and then stops it, using genpd_stop_dev().
However, this last operation is not necessary, because the
device is supposed to be operational after pm_genpd_runtime_resume()
has returned and because of it pm_genpd_runtime_resume() has to
call genpd_start_dev() once again for the "restored" device, which
is inefficient.
To make things more efficient, remove the call to genpd_stop_dev()
from __pm_genpd_restore_device() and the direct call to
genpd_start_dev() from pm_genpd_runtime_resume(). [Of course,
genpd_start_dev() still has to be called by it for devices with the
power.irq_safe flag set, because __pm_genpd_restore_device() is not
executed for them.]
This change has been tested on the SH7372 Mackerel board.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/domain.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 49fdd4002b9f..da1d52576ec9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -339,19 +339,16 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, | |||
339 | { | 339 | { |
340 | struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); | 340 | struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); |
341 | struct device *dev = pdd->dev; | 341 | struct device *dev = pdd->dev; |
342 | bool need_restore = gpd_data->need_restore; | ||
342 | 343 | ||
343 | if (!gpd_data->need_restore) | 344 | gpd_data->need_restore = false; |
344 | return; | ||
345 | |||
346 | mutex_unlock(&genpd->lock); | 345 | mutex_unlock(&genpd->lock); |
347 | 346 | ||
348 | genpd_start_dev(genpd, dev); | 347 | genpd_start_dev(genpd, dev); |
349 | genpd_restore_dev(genpd, dev); | 348 | if (need_restore) |
350 | genpd_stop_dev(genpd, dev); | 349 | genpd_restore_dev(genpd, dev); |
351 | 350 | ||
352 | mutex_lock(&genpd->lock); | 351 | mutex_lock(&genpd->lock); |
353 | |||
354 | gpd_data->need_restore = false; | ||
355 | } | 352 | } |
356 | 353 | ||
357 | /** | 354 | /** |
@@ -595,7 +592,7 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
595 | 592 | ||
596 | /* If power.irq_safe, the PM domain is never powered off. */ | 593 | /* If power.irq_safe, the PM domain is never powered off. */ |
597 | if (dev->power.irq_safe) | 594 | if (dev->power.irq_safe) |
598 | goto out; | 595 | return genpd_start_dev(genpd, dev); |
599 | 596 | ||
600 | mutex_lock(&genpd->lock); | 597 | mutex_lock(&genpd->lock); |
601 | ret = __pm_genpd_poweron(genpd); | 598 | ret = __pm_genpd_poweron(genpd); |
@@ -628,9 +625,6 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
628 | wake_up_all(&genpd->status_wait_queue); | 625 | wake_up_all(&genpd->status_wait_queue); |
629 | mutex_unlock(&genpd->lock); | 626 | mutex_unlock(&genpd->lock); |
630 | 627 | ||
631 | out: | ||
632 | genpd_start_dev(genpd, dev); | ||
633 | |||
634 | return 0; | 628 | return 0; |
635 | } | 629 | } |
636 | 630 | ||