aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2017-02-17 04:55:25 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-02-23 16:25:46 -0500
commit2da835452a0875866ca55d23126c77b9372f0015 (patch)
treeed9bc9cad8e875f3ffb7aba39a6510b7a09868b9
parent3c64649d1cf9f32fd16491e69ccc16385e0ef421 (diff)
PM / Domains: Power off masters immediately in the power off sequence
Once a subdomain is powered off, genpd queues a power off work for each of the subdomain's corresponding masters, thus postponing the masters to be powered off to a later point. When genpd used intermediate power off states, which was removed in commit ba2bbfbf6307 ("PM / Domains: Remove intermediate states from the power off sequence"), this behaviour made sense, but now it simply doesn't. Genpd can easily try to power off the masters in the same context as the subdomain, of course by acquiring/releasing the lock. Then, let's convert to this behaviour, as it avoids unnecessary works from being queued. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/domain.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 179bb269a58f..e697dec9d25b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -284,7 +284,8 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
284 * If all of the @genpd's devices have been suspended and all of its subdomains 284 * If all of the @genpd's devices have been suspended and all of its subdomains
285 * have been powered down, remove power from @genpd. 285 * have been powered down, remove power from @genpd.
286 */ 286 */
287static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on) 287static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
288 unsigned int depth)
288{ 289{
289 struct pm_domain_data *pdd; 290 struct pm_domain_data *pdd;
290 struct gpd_link *link; 291 struct gpd_link *link;
@@ -351,7 +352,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on)
351 352
352 list_for_each_entry(link, &genpd->slave_links, slave_node) { 353 list_for_each_entry(link, &genpd->slave_links, slave_node) {
353 genpd_sd_counter_dec(link->master); 354 genpd_sd_counter_dec(link->master);
354 genpd_queue_power_off_work(link->master); 355 genpd_lock_nested(link->master, depth + 1);
356 genpd_power_off(link->master, false, depth + 1);
357 genpd_unlock(link->master);
355 } 358 }
356 359
357 return 0; 360 return 0;
@@ -405,7 +408,9 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
405 &genpd->slave_links, 408 &genpd->slave_links,
406 slave_node) { 409 slave_node) {
407 genpd_sd_counter_dec(link->master); 410 genpd_sd_counter_dec(link->master);
408 genpd_queue_power_off_work(link->master); 411 genpd_lock_nested(link->master, depth + 1);
412 genpd_power_off(link->master, false, depth + 1);
413 genpd_unlock(link->master);
409 } 414 }
410 415
411 return ret; 416 return ret;
@@ -462,7 +467,7 @@ static void genpd_power_off_work_fn(struct work_struct *work)
462 genpd = container_of(work, struct generic_pm_domain, power_off_work); 467 genpd = container_of(work, struct generic_pm_domain, power_off_work);
463 468
464 genpd_lock(genpd); 469 genpd_lock(genpd);
465 genpd_power_off(genpd, false); 470 genpd_power_off(genpd, false, 0);
466 genpd_unlock(genpd); 471 genpd_unlock(genpd);
467} 472}
468 473
@@ -581,7 +586,7 @@ static int genpd_runtime_suspend(struct device *dev)
581 return 0; 586 return 0;
582 587
583 genpd_lock(genpd); 588 genpd_lock(genpd);
584 genpd_power_off(genpd, true); 589 genpd_power_off(genpd, true, 0);
585 genpd_unlock(genpd); 590 genpd_unlock(genpd);
586 591
587 return 0; 592 return 0;
@@ -661,7 +666,7 @@ err_poweroff:
661 if (!pm_runtime_is_irq_safe(dev) || 666 if (!pm_runtime_is_irq_safe(dev) ||
662 (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) { 667 (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) {
663 genpd_lock(genpd); 668 genpd_lock(genpd);
664 genpd_power_off(genpd, true); 669 genpd_power_off(genpd, true, 0);
665 genpd_unlock(genpd); 670 genpd_unlock(genpd);
666 } 671 }
667 672