Skip to content

Commit

Permalink
PM / Domains: Add time accounting to various genpd states
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thara Gopinath authored and Rafael J. Wysocki committed Jul 24, 2017
1 parent 520eccd commit afece3a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,34 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
smp_mb__after_atomic();
}

#ifdef CONFIG_DEBUG_FS
static void genpd_update_accounting(struct generic_pm_domain *genpd)
{
ktime_t delta, now;

now = ktime_get();
delta = ktime_sub(now, genpd->accounting_time);

/*
* If genpd->status is active, it means we are just
* out of off and so update the idle time and vice
* versa.
*/
if (genpd->status == GPD_STATE_ACTIVE) {
int state_idx = genpd->state_idx;

genpd->states[state_idx].idle_time =
ktime_add(genpd->states[state_idx].idle_time, delta);
} else {
genpd->on_time = ktime_add(genpd->on_time, delta);
}

genpd->accounting_time = now;
}
#else
static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {}
#endif

static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
{
unsigned int state_idx = genpd->state_idx;
Expand Down Expand Up @@ -361,6 +389,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
}

genpd->status = GPD_STATE_POWER_OFF;
genpd_update_accounting(genpd);

list_for_each_entry(link, &genpd->slave_links, slave_node) {
genpd_sd_counter_dec(link->master);
Expand Down Expand Up @@ -413,6 +442,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
goto err;

genpd->status = GPD_STATE_ACTIVE;
genpd_update_accounting(genpd);

return 0;

err:
Expand Down Expand Up @@ -1540,6 +1571,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
genpd->max_off_time_changed = true;
genpd->provider = NULL;
genpd->has_provider = false;
genpd->accounting_time = ktime_get();
genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
genpd->domain.ops.runtime_resume = genpd_runtime_resume;
genpd->domain.ops.prepare = pm_genpd_prepare;
Expand Down
3 changes: 3 additions & 0 deletions include/linux/pm_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct genpd_power_state {
s64 power_on_latency_ns;
s64 residency_ns;
struct fwnode_handle *fwnode;
ktime_t idle_time;
};

struct genpd_lock_ops;
Expand Down Expand Up @@ -78,6 +79,8 @@ struct generic_pm_domain {
unsigned int state_count; /* number of states */
unsigned int state_idx; /* state that genpd will go to when off */
void *free; /* Free the state that was allocated for default */
ktime_t on_time;
ktime_t accounting_time;
const struct genpd_lock_ops *lock_ops;
union {
struct mutex mlock;
Expand Down

0 comments on commit afece3a

Please sign in to comment.