aboutsummaryrefslogtreecommitdiff
path: root/drivers/pmdomain/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pmdomain/core.c')
-rw-r--r--drivers/pmdomain/core.c75
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,