diff options
author | Thara Gopinath <thara.gopinath@linaro.org> | 2017-07-14 13:10:15 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-07-24 17:02:02 -0400 |
commit | afece3ab9a3640f9c1e064f56c8cdd4d783f6144 (patch) | |
tree | f28da8ffb3bb4406f2b0407adb698e6cb0c77588 | |
parent | 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 (diff) |
PM / Domains: Add time accounting to various genpd states
This patch adds support to calculate the time spent by the generic
power domains in on and various idle states.
Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org>
Acked-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.c | 32 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 3 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 60303aa28587..431488914982 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -209,6 +209,34 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) | |||
209 | smp_mb__after_atomic(); | 209 | smp_mb__after_atomic(); |
210 | } | 210 | } |
211 | 211 | ||
212 | #ifdef CONFIG_DEBUG_FS | ||
213 | static void genpd_update_accounting(struct generic_pm_domain *genpd) | ||
214 | { | ||
215 | ktime_t delta, now; | ||
216 | |||
217 | now = ktime_get(); | ||
218 | delta = ktime_sub(now, genpd->accounting_time); | ||
219 | |||
220 | /* | ||
221 | * If genpd->status is active, it means we are just | ||
222 | * out of off and so update the idle time and vice | ||
223 | * versa. | ||
224 | */ | ||
225 | if (genpd->status == GPD_STATE_ACTIVE) { | ||
226 | int state_idx = genpd->state_idx; | ||
227 | |||
228 | genpd->states[state_idx].idle_time = | ||
229 | ktime_add(genpd->states[state_idx].idle_time, delta); | ||
230 | } else { | ||
231 | genpd->on_time = ktime_add(genpd->on_time, delta); | ||
232 | } | ||
233 | |||
234 | genpd->accounting_time = now; | ||
235 | } | ||
236 | #else | ||
237 | static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {} | ||
238 | #endif | ||
239 | |||
212 | static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) | 240 | static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) |
213 | { | 241 | { |
214 | unsigned int state_idx = genpd->state_idx; | 242 | unsigned int state_idx = genpd->state_idx; |
@@ -361,6 +389,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, | |||
361 | } | 389 | } |
362 | 390 | ||
363 | genpd->status = GPD_STATE_POWER_OFF; | 391 | genpd->status = GPD_STATE_POWER_OFF; |
392 | genpd_update_accounting(genpd); | ||
364 | 393 | ||
365 | list_for_each_entry(link, &genpd->slave_links, slave_node) { | 394 | list_for_each_entry(link, &genpd->slave_links, slave_node) { |
366 | genpd_sd_counter_dec(link->master); | 395 | genpd_sd_counter_dec(link->master); |
@@ -413,6 +442,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) | |||
413 | goto err; | 442 | goto err; |
414 | 443 | ||
415 | genpd->status = GPD_STATE_ACTIVE; | 444 | genpd->status = GPD_STATE_ACTIVE; |
445 | genpd_update_accounting(genpd); | ||
446 | |||
416 | return 0; | 447 | return 0; |
417 | 448 | ||
418 | err: | 449 | err: |
@@ -1540,6 +1571,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, | |||
1540 | genpd->max_off_time_changed = true; | 1571 | genpd->max_off_time_changed = true; |
1541 | genpd->provider = NULL; | 1572 | genpd->provider = NULL; |
1542 | genpd->has_provider = false; | 1573 | genpd->has_provider = false; |
1574 | genpd->accounting_time = ktime_get(); | ||
1543 | genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; | 1575 | genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; |
1544 | genpd->domain.ops.runtime_resume = genpd_runtime_resume; | 1576 | genpd->domain.ops.runtime_resume = genpd_runtime_resume; |
1545 | genpd->domain.ops.prepare = pm_genpd_prepare; | 1577 | genpd->domain.ops.prepare = pm_genpd_prepare; |
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 41004d97cefa..84f423d5633e 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -43,6 +43,7 @@ struct genpd_power_state { | |||
43 | s64 power_on_latency_ns; | 43 | s64 power_on_latency_ns; |
44 | s64 residency_ns; | 44 | s64 residency_ns; |
45 | struct fwnode_handle *fwnode; | 45 | struct fwnode_handle *fwnode; |
46 | ktime_t idle_time; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | struct genpd_lock_ops; | 49 | struct genpd_lock_ops; |
@@ -78,6 +79,8 @@ struct generic_pm_domain { | |||
78 | unsigned int state_count; /* number of states */ | 79 | unsigned int state_count; /* number of states */ |
79 | unsigned int state_idx; /* state that genpd will go to when off */ | 80 | unsigned int state_idx; /* state that genpd will go to when off */ |
80 | void *free; /* Free the state that was allocated for default */ | 81 | void *free; /* Free the state that was allocated for default */ |
82 | ktime_t on_time; | ||
83 | ktime_t accounting_time; | ||
81 | const struct genpd_lock_ops *lock_ops; | 84 | const struct genpd_lock_ops *lock_ops; |
82 | union { | 85 | union { |
83 | struct mutex mlock; | 86 | struct mutex mlock; |