diff options
Diffstat (limited to 'drivers/pmdomain/core.c')
| -rw-r--r-- | drivers/pmdomain/core.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index bf82775f6a67..4d32fc676aaf 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -1438,6 +1438,13 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, return; } else { genpd->states[genpd->state_idx].usage++; + + /* + * The ->system_power_down_ok() callback is currently used only + * for s2idle. Use it to know when to update the usage counter. + */ + if (genpd->gov && genpd->gov->system_power_down_ok) + genpd->states[genpd->state_idx].usage_s2idle++; } genpd->status = GENPD_STATE_OFF; @@ -1811,7 +1818,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, if (ret) return ERR_PTR(ret); - gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); + gpd_data = kzalloc_obj(*gpd_data); if (!gpd_data) { ret = -ENOMEM; goto err_put; @@ -1822,7 +1829,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, /* Allocate data used by a governor. */ if (has_governor) { - td = kzalloc(sizeof(*td), GFP_KERNEL); + td = kzalloc_obj(*td); if (!td) { ret = -ENOMEM; goto err_free; @@ -2161,7 +2168,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd, return -EINVAL; } - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; @@ -2269,7 +2276,7 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd) { struct genpd_power_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -2295,7 +2302,7 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd) return -ENOMEM; if (genpd->gov) { - gd = kzalloc(sizeof(*gd), GFP_KERNEL); + gd = kzalloc_obj(*gd); if (!gd) { ret = -ENOMEM; goto free; @@ -2623,7 +2630,7 @@ static int genpd_add_provider(struct device_node *np, genpd_xlate_t xlate, { struct of_genpd_provider *cp; - cp = kzalloc(sizeof(*cp), GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return -ENOMEM; @@ -3316,7 +3323,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev, return ERR_PTR(-ENODEV); /* Allocate and register device on the genpd bus. */ - virt_dev = kzalloc(sizeof(*virt_dev), GFP_KERNEL); + virt_dev = kzalloc_obj(*virt_dev); if (!virt_dev) return ERR_PTR(-ENOMEM); @@ -3474,7 +3481,7 @@ int of_genpd_parse_idle_states(struct device_node *dn, return 0; } - st = kcalloc(ret, sizeof(*st), GFP_KERNEL); + st = kzalloc_objs(*st, ret); if (!st) return -ENOMEM; @@ -3772,11 +3779,11 @@ static int idle_states_show(struct seq_file *s, void *data) if (ret) return -ERESTARTSYS; - seq_puts(s, "State Time Spent(ms) Usage Rejected Above Below\n"); + seq_puts(s, "State Time(ms) Usage Rejected Above Below S2idle\n"); for (i = 0; i < genpd->state_count; i++) { struct genpd_power_state *state = &genpd->states[i]; - char state_name[15]; + char state_name[7]; idle_time += state->idle_time; @@ -3788,14 +3795,45 @@ static int idle_states_show(struct seq_file *s, void *data) } } - if (!state->name) - snprintf(state_name, ARRAY_SIZE(state_name), "S%-13d", i); - + snprintf(state_name, ARRAY_SIZE(state_name), "S%-5d", i); do_div(idle_time, NSEC_PER_MSEC); - seq_printf(s, "%-14s %-14llu %-10llu %-10llu %-10llu %llu\n", - state->name ?: state_name, idle_time, - state->usage, state->rejected, state->above, - state->below); + seq_printf(s, "%-6s %-14llu %-10llu %-10llu %-10llu %-10llu %llu\n", + state_name, idle_time, state->usage, state->rejected, + state->above, state->below, state->usage_s2idle); + } + + genpd_unlock(genpd); + return ret; +} + +static int idle_states_desc_show(struct seq_file *s, void *data) +{ + struct generic_pm_domain *genpd = s->private; + unsigned int i; + int ret = 0; + + ret = genpd_lock_interruptible(genpd); + if (ret) + return -ERESTARTSYS; + + seq_puts(s, "State Latency(us) Residency(us) Name\n"); + + for (i = 0; i < genpd->state_count; i++) { + struct genpd_power_state *state = &genpd->states[i]; + u64 latency, residency; + char state_name[7]; + + latency = state->power_off_latency_ns + + state->power_on_latency_ns; + do_div(latency, NSEC_PER_USEC); + + residency = state->residency_ns; + do_div(residency, NSEC_PER_USEC); + + snprintf(state_name, ARRAY_SIZE(state_name), "S%-5d", i); + seq_printf(s, "%-6s %-12llu %-14llu %s\n", + state_name, latency, residency, + state->name ?: "N/A"); } genpd_unlock(genpd); @@ -3891,6 +3929,7 @@ DEFINE_SHOW_ATTRIBUTE(summary); DEFINE_SHOW_ATTRIBUTE(status); DEFINE_SHOW_ATTRIBUTE(sub_domains); DEFINE_SHOW_ATTRIBUTE(idle_states); +DEFINE_SHOW_ATTRIBUTE(idle_states_desc); DEFINE_SHOW_ATTRIBUTE(active_time); DEFINE_SHOW_ATTRIBUTE(total_idle_time); DEFINE_SHOW_ATTRIBUTE(devices); @@ -3911,6 +3950,8 @@ static void genpd_debug_add(struct generic_pm_domain *genpd) d, genpd, &sub_domains_fops); debugfs_create_file("idle_states", 0444, d, genpd, &idle_states_fops); + debugfs_create_file("idle_states_desc", 0444, + d, genpd, &idle_states_desc_fops); debugfs_create_file("active_time", 0444, d, genpd, &active_time_fops); debugfs_create_file("total_idle_time", 0444, |
