aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThara Gopinath <thara.gopinath@linaro.org>2017-07-14 13:10:15 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-24 17:02:02 -0400
commitafece3ab9a3640f9c1e064f56c8cdd4d783f6144 (patch)
treef28da8ffb3bb4406f2b0407adb698e6cb0c77588
parent520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 (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.c32
-rw-r--r--include/linux/pm_domain.h3
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
213static 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
237static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {}
238#endif
239
212static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) 240static 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
48struct genpd_lock_ops; 49struct 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;