aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2015-10-13 10:10:28 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-10-13 20:34:43 -0400
commita98f1b78ecf325bf29c9d3d1eb38cbc9340000af (patch)
tree796360c6c35034ed8dc59558954ef8ef05dae25c
parent25cb62b76430a91cc6195f902e61c2cb84ade622 (diff)
PM / Domains: Fix validation of latency constraints in genpd governor
Commit ba2bbfbf6307 (PM / Domains: Remove intermediate states from the power off sequence) changed the power off sequence in genpd. That also required some updates regarding the validation of latency constraints in the genpd governor. Unfortunate that wasn't covered, so let's fix this. From a runtime PM and latency point of view, we need to consider the worst case scenario while validating latency constraints. That's typically when a call to pm_runtime_get_sync() needs to wait for a ongoing runtime suspend operation to be carried out, as it then also needs to wait for the device to be runtime resumed again. The above mentioned commit made the genpd governor's ->stop_ok() callback responsible of validating genpd's device's runtime suspend/resume latency. In other words, the constraint needs to be validated towards the relevant latencies present in genpd's ->runtime_suspend|resume() callbacks. Earlier, that included latencies from the ->stop|start() callbacks, but as ->save|restore_state() are now also being invoked from genpd's ->runtime_suspend|resume() and to comply with the worst case scenario, let's take also those latencies into account. Fixes: ba2bbfbf6307 (PM / Domains: Remove intermediate states from the power off sequence) 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_governor.c22
1 files changed, 6 insertions, 16 deletions
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index 2a4154a09e4d..85e17bacc834 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -77,13 +77,16 @@ static bool default_stop_ok(struct device *dev)
77 dev_update_qos_constraint); 77 dev_update_qos_constraint);
78 78
79 if (constraint_ns > 0) { 79 if (constraint_ns > 0) {
80 constraint_ns -= td->start_latency_ns; 80 constraint_ns -= td->save_state_latency_ns +
81 td->stop_latency_ns +
82 td->start_latency_ns +
83 td->restore_state_latency_ns;
81 if (constraint_ns == 0) 84 if (constraint_ns == 0)
82 return false; 85 return false;
83 } 86 }
84 td->effective_constraint_ns = constraint_ns; 87 td->effective_constraint_ns = constraint_ns;
85 td->cached_stop_ok = constraint_ns > td->stop_latency_ns || 88 td->cached_stop_ok = constraint_ns >= 0;
86 constraint_ns == 0; 89
87 /* 90 /*
88 * The children have been suspended already, so we don't need to take 91 * The children have been suspended already, so we don't need to take
89 * their stop latencies into account here. 92 * their stop latencies into account here.
@@ -126,18 +129,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
126 129
127 off_on_time_ns = genpd->power_off_latency_ns + 130 off_on_time_ns = genpd->power_off_latency_ns +
128 genpd->power_on_latency_ns; 131 genpd->power_on_latency_ns;
129 /*
130 * It doesn't make sense to remove power from the domain if saving
131 * the state of all devices in it and the power off/power on operations
132 * take too much time.
133 *
134 * All devices in this domain have been stopped already at this point.
135 */
136 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
137 if (pdd->dev->driver)
138 off_on_time_ns +=
139 to_gpd_data(pdd)->td.save_state_latency_ns;
140 }
141 132
142 min_off_time_ns = -1; 133 min_off_time_ns = -1;
143 /* 134 /*
@@ -193,7 +184,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
193 * constraint_ns cannot be negative here, because the device has 184 * constraint_ns cannot be negative here, because the device has
194 * been suspended. 185 * been suspended.
195 */ 186 */
196 constraint_ns -= td->restore_state_latency_ns;
197 if (constraint_ns <= off_on_time_ns) 187 if (constraint_ns <= off_on_time_ns)
198 return false; 188 return false;
199 189