forked from mirrors/linux
		
	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:
		
							parent
							
								
									520eccdfe1
								
							
						
					
					
						commit
						afece3ab9a
					
				
					 2 changed files with 35 additions and 0 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue