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>
This commit is contained in:
Родитель
520eccdfe1
Коммит
afece3ab9a
|
@ -209,6 +209,34 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
|
||||||
smp_mb__after_atomic();
|
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)
|
static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
|
||||||
{
|
{
|
||||||
unsigned int state_idx = genpd->state_idx;
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
genpd->status = GPD_STATE_POWER_OFF;
|
genpd->status = GPD_STATE_POWER_OFF;
|
||||||
|
genpd_update_accounting(genpd);
|
||||||
|
|
||||||
list_for_each_entry(link, &genpd->slave_links, slave_node) {
|
list_for_each_entry(link, &genpd->slave_links, slave_node) {
|
||||||
genpd_sd_counter_dec(link->master);
|
genpd_sd_counter_dec(link->master);
|
||||||
|
@ -413,6 +442,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
genpd->status = GPD_STATE_ACTIVE;
|
genpd->status = GPD_STATE_ACTIVE;
|
||||||
|
genpd_update_accounting(genpd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@ -1540,6 +1571,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
|
||||||
genpd->max_off_time_changed = true;
|
genpd->max_off_time_changed = true;
|
||||||
genpd->provider = NULL;
|
genpd->provider = NULL;
|
||||||
genpd->has_provider = false;
|
genpd->has_provider = false;
|
||||||
|
genpd->accounting_time = ktime_get();
|
||||||
genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
|
genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
|
||||||
genpd->domain.ops.runtime_resume = genpd_runtime_resume;
|
genpd->domain.ops.runtime_resume = genpd_runtime_resume;
|
||||||
genpd->domain.ops.prepare = pm_genpd_prepare;
|
genpd->domain.ops.prepare = pm_genpd_prepare;
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct genpd_power_state {
|
||||||
s64 power_on_latency_ns;
|
s64 power_on_latency_ns;
|
||||||
s64 residency_ns;
|
s64 residency_ns;
|
||||||
struct fwnode_handle *fwnode;
|
struct fwnode_handle *fwnode;
|
||||||
|
ktime_t idle_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct genpd_lock_ops;
|
struct genpd_lock_ops;
|
||||||
|
@ -78,6 +79,8 @@ struct generic_pm_domain {
|
||||||
unsigned int state_count; /* number of states */
|
unsigned int state_count; /* number of states */
|
||||||
unsigned int state_idx; /* state that genpd will go to when off */
|
unsigned int state_idx; /* state that genpd will go to when off */
|
||||||
void *free; /* Free the state that was allocated for default */
|
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;
|
const struct genpd_lock_ops *lock_ops;
|
||||||
union {
|
union {
|
||||||
struct mutex mlock;
|
struct mutex mlock;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче