diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-08-05 19:47:29 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-03 19:36:04 -0400 |
commit | e2e3e4e51ebdcd757079bd7ec5dcc9dfb2ebce24 (patch) | |
tree | 89d658924faebb526d9f0649c1aa5cf984af6c88 /drivers/base/power | |
parent | dbf374142dd7a3c394ec124ebe7339a6c412d9b6 (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.c | 8 |
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 | ||
78 | static 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 | |||
78 | static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) | 84 | static 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); |