aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/domain.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2014-11-10 13:39:19 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-13 18:07:31 -0500
commitc8f0ea45169c57f36e6d8c4dcf7ccf09de7f1c2c (patch)
treee00a8b808323f4483d449a23c5b99f6e3d8ba3c2 /drivers/base/power/domain.c
parent895b31f3b6b800b8f46569391f2396b1f221c602 (diff)
PM / Domains: Extract code to power off/on a PM domain
PM domains are powered on/off from various places. Some callers do latency measurements, others don't. Consolidate using two helper functions, which always measure the latencies, and update the stored latencies when needed. Other minor changes: - Use pr_warn() instead of pr_warning(), - There's no need to check genpd->name, %s handles NULL pointers fine, - Make the warning format strings identical, to save memory. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Kevin Hilman <khilman@linaro.org> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power/domain.c')
-rw-r--r--drivers/base/power/domain.c101
1 files changed, 60 insertions, 41 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 28d6e8bf746c..1d1f5cc4293d 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -151,6 +151,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
151 genpd->cpuidle_data->idle_state->exit_latency = usecs64; 151 genpd->cpuidle_data->idle_state->exit_latency = usecs64;
152} 152}
153 153
154static int genpd_power_on(struct generic_pm_domain *genpd)
155{
156 ktime_t time_start;
157 s64 elapsed_ns;
158 int ret;
159
160 if (!genpd->power_on)
161 return 0;
162
163 time_start = ktime_get();
164 ret = genpd->power_on(genpd);
165 if (ret)
166 return ret;
167
168 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
169 if (elapsed_ns <= genpd->power_on_latency_ns)
170 return ret;
171
172 genpd->power_on_latency_ns = elapsed_ns;
173 genpd->max_off_time_changed = true;
174 genpd_recalc_cpu_exit_latency(genpd);
175 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
176 genpd->name, "on", elapsed_ns);
177
178 return ret;
179}
180
181static int genpd_power_off(struct generic_pm_domain *genpd)
182{
183 ktime_t time_start;
184 s64 elapsed_ns;
185 int ret;
186
187 if (!genpd->power_off)
188 return 0;
189
190 time_start = ktime_get();
191 ret = genpd->power_off(genpd);
192 if (ret == -EBUSY)
193 return ret;
194
195 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
196 if (elapsed_ns <= genpd->power_off_latency_ns)
197 return ret;
198
199 genpd->power_off_latency_ns = elapsed_ns;
200 genpd->max_off_time_changed = true;
201 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
202 genpd->name, "off", elapsed_ns);
203
204 return ret;
205}
206
154/** 207/**
155 * __pm_genpd_poweron - Restore power to a given PM domain and its masters. 208 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
156 * @genpd: PM domain to power up. 209 * @genpd: PM domain to power up.
@@ -222,25 +275,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
222 } 275 }
223 } 276 }
224 277
225 if (genpd->power_on) { 278 ret = genpd_power_on(genpd);
226 ktime_t time_start = ktime_get(); 279 if (ret)
227 s64 elapsed_ns; 280 goto err;
228
229 ret = genpd->power_on(genpd);
230 if (ret)
231 goto err;
232
233 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
234 if (elapsed_ns > genpd->power_on_latency_ns) {
235 genpd->power_on_latency_ns = elapsed_ns;
236 genpd->max_off_time_changed = true;
237 genpd_recalc_cpu_exit_latency(genpd);
238 if (genpd->name)
239 pr_warning("%s: Power-on latency exceeded, "
240 "new value %lld ns\n", genpd->name,
241 elapsed_ns);
242 }
243 }
244 281
245 out: 282 out:
246 genpd_set_active(genpd); 283 genpd_set_active(genpd);
@@ -529,16 +566,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
529 } 566 }
530 567
531 if (genpd->power_off) { 568 if (genpd->power_off) {
532 ktime_t time_start;
533 s64 elapsed_ns;
534
535 if (atomic_read(&genpd->sd_count) > 0) { 569 if (atomic_read(&genpd->sd_count) > 0) {
536 ret = -EBUSY; 570 ret = -EBUSY;
537 goto out; 571 goto out;
538 } 572 }
539 573
540 time_start = ktime_get();
541
542 /* 574 /*
543 * If sd_count > 0 at this point, one of the subdomains hasn't 575 * If sd_count > 0 at this point, one of the subdomains hasn't
544 * managed to call pm_genpd_poweron() for the master yet after 576 * managed to call pm_genpd_poweron() for the master yet after
@@ -547,21 +579,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
547 * the pm_genpd_poweron() restore power for us (this shouldn't 579 * the pm_genpd_poweron() restore power for us (this shouldn't
548 * happen very often). 580 * happen very often).
549 */ 581 */
550 ret = genpd->power_off(genpd); 582 ret = genpd_power_off(genpd);
551 if (ret == -EBUSY) { 583 if (ret == -EBUSY) {
552 genpd_set_active(genpd); 584 genpd_set_active(genpd);
553 goto out; 585 goto out;
554 } 586 }
555
556 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
557 if (elapsed_ns > genpd->power_off_latency_ns) {
558 genpd->power_off_latency_ns = elapsed_ns;
559 genpd->max_off_time_changed = true;
560 if (genpd->name)
561 pr_warning("%s: Power-off latency exceeded, "
562 "new value %lld ns\n", genpd->name,
563 elapsed_ns);
564 }
565 } 587 }
566 588
567 genpd->status = GPD_STATE_POWER_OFF; 589 genpd->status = GPD_STATE_POWER_OFF;
@@ -796,8 +818,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
796 || atomic_read(&genpd->sd_count) > 0) 818 || atomic_read(&genpd->sd_count) > 0)
797 return; 819 return;
798 820
799 if (genpd->power_off) 821 genpd_power_off(genpd);
800 genpd->power_off(genpd);
801 822
802 genpd->status = GPD_STATE_POWER_OFF; 823 genpd->status = GPD_STATE_POWER_OFF;
803 824
@@ -828,8 +849,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
828 genpd_sd_counter_inc(link->master); 849 genpd_sd_counter_inc(link->master);
829 } 850 }
830 851
831 if (genpd->power_on) 852 genpd_power_on(genpd);
832 genpd->power_on(genpd);
833 853
834 genpd->status = GPD_STATE_ACTIVE; 854 genpd->status = GPD_STATE_ACTIVE;
835} 855}
@@ -1251,8 +1271,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
1251 * If the domain was off before the hibernation, make 1271 * If the domain was off before the hibernation, make
1252 * sure it will be off going forward. 1272 * sure it will be off going forward.
1253 */ 1273 */
1254 if (genpd->power_off) 1274 genpd_power_off(genpd);
1255 genpd->power_off(genpd);
1256 1275
1257 return 0; 1276 return 0;
1258 } 1277 }