aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-08-05 19:47:29 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-09-03 19:36:04 -0400
commite2e3e4e51ebdcd757079bd7ec5dcc9dfb2ebce24 (patch)
tree89d658924faebb526d9f0649c1aa5cf984af6c88 /drivers/base/power
parentdbf374142dd7a3c394ec124ebe7339a6c412d9b6 (diff)
PM / Domains: Do not measure start time for "irq safe" devices
The genpd_start_dev() routine used by pm_genpd_runtime_resume() to put "irq safe" devices into the full power state measures the time necessary to "start" the device and updates its PM QoS timing data if necessary. This may lead to a deadlock if the given device is a clock source and genpd_start_dev() is invoked from within the clock source's .enable() routine, which will happen if that routine uses pm_runtime_get_sync(), for example, to ensure that the device is operational. For this reason, introduce a special routine analogous to genpd_start_dev(), called genpd_start_dev_no_timing(), that doesn't carry out the time measurement, and make pm_genpd_runtime_resume() use it instead of genpd_start_dev() to power up "irq safe" devices. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/domain.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 52172754ff78..d7e71b5b080e 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -75,6 +75,12 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
75 start_latency_ns, "start"); 75 start_latency_ns, "start");
76} 76}
77 77
78static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
79 struct device *dev)
80{
81 return GENPD_DEV_CALLBACK(genpd, int, start, dev);
82}
83
78static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) 84static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
79{ 85{
80 bool ret = false; 86 bool ret = false;
@@ -626,7 +632,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
626 632
627 /* If power.irq_safe, the PM domain is never powered off. */ 633 /* If power.irq_safe, the PM domain is never powered off. */
628 if (dev->power.irq_safe) 634 if (dev->power.irq_safe)
629 return genpd_start_dev(genpd, dev); 635 return genpd_start_dev_no_timing(genpd, dev);
630 636
631 mutex_lock(&genpd->lock); 637 mutex_lock(&genpd->lock);
632 ret = __pm_genpd_poweron(genpd); 638 ret = __pm_genpd_poweron(genpd);