aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-05-07 16:00:59 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-05-11 15:11:44 -0400
commitb723b0eb91e08a0ee9a401c0b22c0d52966d9daa (patch)
tree5730adb87db4c0d8cabec414495a401bcb421cec
parent4fcac10d28e7a046120b51a106b19082d2e57401 (diff)
PM / Domains: Fix computation of maximum domain off time
The default domain power off governor function for generic PM domains, default_power_down_ok(), may violate subdomain maximum off time limit by allowing the master domain to be off for too long. Namely, it only finds the minium of all device maximum off times over the domain's devices and uses that to compute the domain's maximum off time, but it should do the same for the subdomains. Fix this problem by modifying default_power_down_ok() to compute the given domain's maximum off time as the difference between the minimum off time over all devices and subdomains in the domain and its power on latency. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--drivers/base/power/domain_governor.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index 3a5c5346bc47..28dee3053f1f 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -105,7 +105,7 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
105 struct generic_pm_domain *genpd = pd_to_genpd(pd); 105 struct generic_pm_domain *genpd = pd_to_genpd(pd);
106 struct gpd_link *link; 106 struct gpd_link *link;
107 struct pm_domain_data *pdd; 107 struct pm_domain_data *pdd;
108 s64 min_dev_off_time_ns; 108 s64 min_off_time_ns;
109 s64 off_on_time_ns; 109 s64 off_on_time_ns;
110 110
111 if (genpd->max_off_time_changed) { 111 if (genpd->max_off_time_changed) {
@@ -142,6 +142,7 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
142 to_gpd_data(pdd)->td.save_state_latency_ns; 142 to_gpd_data(pdd)->td.save_state_latency_ns;
143 } 143 }
144 144
145 min_off_time_ns = -1;
145 /* 146 /*
146 * Check if subdomains can be off for enough time. 147 * Check if subdomains can be off for enough time.
147 * 148 *
@@ -161,12 +162,14 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
161 */ 162 */
162 if (sd_max_off_ns <= off_on_time_ns) 163 if (sd_max_off_ns <= off_on_time_ns)
163 return false; 164 return false;
165
166 if (min_off_time_ns > sd_max_off_ns || min_off_time_ns < 0)
167 min_off_time_ns = sd_max_off_ns;
164 } 168 }
165 169
166 /* 170 /*
167 * Check if the devices in the domain can be off enough time. 171 * Check if the devices in the domain can be off enough time.
168 */ 172 */
169 min_dev_off_time_ns = -1;
170 list_for_each_entry(pdd, &genpd->dev_list, list_node) { 173 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
171 struct gpd_timing_data *td; 174 struct gpd_timing_data *td;
172 s64 constraint_ns; 175 s64 constraint_ns;
@@ -197,9 +200,8 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
197 if (constraint_ns <= off_on_time_ns) 200 if (constraint_ns <= off_on_time_ns)
198 return false; 201 return false;
199 202
200 if (min_dev_off_time_ns > constraint_ns 203 if (min_off_time_ns > constraint_ns || min_off_time_ns < 0)
201 || min_dev_off_time_ns < 0) 204 min_off_time_ns = constraint_ns;
202 min_dev_off_time_ns = constraint_ns;
203 } 205 }
204 206
205 genpd->cached_power_down_ok = true; 207 genpd->cached_power_down_ok = true;
@@ -209,16 +211,15 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
209 * latency constraints, so the domain can spend arbitrary time in the 211 * latency constraints, so the domain can spend arbitrary time in the
210 * "off" state. 212 * "off" state.
211 */ 213 */
212 if (min_dev_off_time_ns < 0) 214 if (min_off_time_ns < 0)
213 return true; 215 return true;
214 216
215 /* 217 /*
216 * The difference between the computed minimum device off time and the 218 * The difference between the computed minimum subdomain or device off
217 * time needed to turn the domain on is the maximum theoretical time 219 * time and the time needed to turn the domain on is the maximum
218 * this domain can spend in the "off" state. 220 * theoretical time this domain can spend in the "off" state.
219 */ 221 */
220 genpd->max_off_time_ns = min_dev_off_time_ns - 222 genpd->max_off_time_ns = min_off_time_ns - genpd->power_on_latency_ns;
221 genpd->power_on_latency_ns;
222 return true; 223 return true;
223} 224}
224 225