Skip to content

Commit b6a1d09

Browse files
tharagopinathrafaeljw
authored andcommitted
PM / Domains: Extend generic power domain debugfs
This patch extends the existing generic power domain debugfs. Changes involve the following - Introduce a unique debugfs entry for each generic power domain with the following attributes - current_state - Displays current state of the domain. - devices - Displays the devices associated with this domain. - sub_domains - Displays the sub power domains. - active_time - Displays the time the domain was in active state in ms. - total_idle_time - Displays the time the domain was in any of the idle states in ms. - idle_states - Displays the various idle states and the time spent in each idle state in ms. Signed-off-by: Thara Gopinath <[email protected]> Acked-by: Ulf Hansson <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent afece3a commit b6a1d09

File tree

1 file changed

+195
-10
lines changed

1 file changed

+195
-10
lines changed

drivers/base/power/domain.c

Lines changed: 195 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,7 +2359,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
23592359
return 0;
23602360
}
23612361

2362-
static int pm_genpd_summary_show(struct seq_file *s, void *data)
2362+
static int genpd_summary_show(struct seq_file *s, void *data)
23632363
{
23642364
struct generic_pm_domain *genpd;
23652365
int ret = 0;
@@ -2382,32 +2382,217 @@ static int pm_genpd_summary_show(struct seq_file *s, void *data)
23822382
return ret;
23832383
}
23842384

2385-
static int pm_genpd_summary_open(struct inode *inode, struct file *file)
2385+
static int genpd_status_show(struct seq_file *s, void *data)
23862386
{
2387-
return single_open(file, pm_genpd_summary_show, NULL);
2387+
static const char * const status_lookup[] = {
2388+
[GPD_STATE_ACTIVE] = "on",
2389+
[GPD_STATE_POWER_OFF] = "off"
2390+
};
2391+
2392+
struct generic_pm_domain *genpd = s->private;
2393+
int ret = 0;
2394+
2395+
ret = genpd_lock_interruptible(genpd);
2396+
if (ret)
2397+
return -ERESTARTSYS;
2398+
2399+
if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup)))
2400+
goto exit;
2401+
2402+
if (genpd->status == GPD_STATE_POWER_OFF)
2403+
seq_printf(s, "%s-%u\n", status_lookup[genpd->status],
2404+
genpd->state_idx);
2405+
else
2406+
seq_printf(s, "%s\n", status_lookup[genpd->status]);
2407+
exit:
2408+
genpd_unlock(genpd);
2409+
return ret;
23882410
}
23892411

2390-
static const struct file_operations pm_genpd_summary_fops = {
2391-
.open = pm_genpd_summary_open,
2392-
.read = seq_read,
2393-
.llseek = seq_lseek,
2394-
.release = single_release,
2395-
};
2412+
static int genpd_sub_domains_show(struct seq_file *s, void *data)
2413+
{
2414+
struct generic_pm_domain *genpd = s->private;
2415+
struct gpd_link *link;
2416+
int ret = 0;
2417+
2418+
ret = genpd_lock_interruptible(genpd);
2419+
if (ret)
2420+
return -ERESTARTSYS;
2421+
2422+
list_for_each_entry(link, &genpd->master_links, master_node)
2423+
seq_printf(s, "%s\n", link->slave->name);
2424+
2425+
genpd_unlock(genpd);
2426+
return ret;
2427+
}
2428+
2429+
static int genpd_idle_states_show(struct seq_file *s, void *data)
2430+
{
2431+
struct generic_pm_domain *genpd = s->private;
2432+
unsigned int i;
2433+
int ret = 0;
2434+
2435+
ret = genpd_lock_interruptible(genpd);
2436+
if (ret)
2437+
return -ERESTARTSYS;
2438+
2439+
seq_puts(s, "State Time Spent(ms)\n");
2440+
2441+
for (i = 0; i < genpd->state_count; i++) {
2442+
ktime_t delta = 0;
2443+
s64 msecs;
2444+
2445+
if ((genpd->status == GPD_STATE_POWER_OFF) &&
2446+
(genpd->state_idx == i))
2447+
delta = ktime_sub(ktime_get(), genpd->accounting_time);
2448+
2449+
msecs = ktime_to_ms(
2450+
ktime_add(genpd->states[i].idle_time, delta));
2451+
seq_printf(s, "S%-13i %lld\n", i, msecs);
2452+
}
2453+
2454+
genpd_unlock(genpd);
2455+
return ret;
2456+
}
2457+
2458+
static int genpd_active_time_show(struct seq_file *s, void *data)
2459+
{
2460+
struct generic_pm_domain *genpd = s->private;
2461+
ktime_t delta = 0;
2462+
int ret = 0;
2463+
2464+
ret = genpd_lock_interruptible(genpd);
2465+
if (ret)
2466+
return -ERESTARTSYS;
2467+
2468+
if (genpd->status == GPD_STATE_ACTIVE)
2469+
delta = ktime_sub(ktime_get(), genpd->accounting_time);
2470+
2471+
seq_printf(s, "%lld ms\n", ktime_to_ms(
2472+
ktime_add(genpd->on_time, delta)));
2473+
2474+
genpd_unlock(genpd);
2475+
return ret;
2476+
}
2477+
2478+
static int genpd_total_idle_time_show(struct seq_file *s, void *data)
2479+
{
2480+
struct generic_pm_domain *genpd = s->private;
2481+
ktime_t delta = 0, total = 0;
2482+
unsigned int i;
2483+
int ret = 0;
2484+
2485+
ret = genpd_lock_interruptible(genpd);
2486+
if (ret)
2487+
return -ERESTARTSYS;
2488+
2489+
for (i = 0; i < genpd->state_count; i++) {
2490+
2491+
if ((genpd->status == GPD_STATE_POWER_OFF) &&
2492+
(genpd->state_idx == i))
2493+
delta = ktime_sub(ktime_get(), genpd->accounting_time);
2494+
2495+
total = ktime_add(total, genpd->states[i].idle_time);
2496+
}
2497+
total = ktime_add(total, delta);
2498+
2499+
seq_printf(s, "%lld ms\n", ktime_to_ms(total));
2500+
2501+
genpd_unlock(genpd);
2502+
return ret;
2503+
}
2504+
2505+
2506+
static int genpd_devices_show(struct seq_file *s, void *data)
2507+
{
2508+
struct generic_pm_domain *genpd = s->private;
2509+
struct pm_domain_data *pm_data;
2510+
const char *kobj_path;
2511+
int ret = 0;
2512+
2513+
ret = genpd_lock_interruptible(genpd);
2514+
if (ret)
2515+
return -ERESTARTSYS;
2516+
2517+
list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
2518+
kobj_path = kobject_get_path(&pm_data->dev->kobj,
2519+
genpd_is_irq_safe(genpd) ?
2520+
GFP_ATOMIC : GFP_KERNEL);
2521+
if (kobj_path == NULL)
2522+
continue;
2523+
2524+
seq_printf(s, "%s\n", kobj_path);
2525+
kfree(kobj_path);
2526+
}
2527+
2528+
genpd_unlock(genpd);
2529+
return ret;
2530+
}
2531+
2532+
#define define_genpd_open_function(name) \
2533+
static int genpd_##name##_open(struct inode *inode, struct file *file) \
2534+
{ \
2535+
return single_open(file, genpd_##name##_show, inode->i_private); \
2536+
}
2537+
2538+
define_genpd_open_function(summary);
2539+
define_genpd_open_function(status);
2540+
define_genpd_open_function(sub_domains);
2541+
define_genpd_open_function(idle_states);
2542+
define_genpd_open_function(active_time);
2543+
define_genpd_open_function(total_idle_time);
2544+
define_genpd_open_function(devices);
2545+
2546+
#define define_genpd_debugfs_fops(name) \
2547+
static const struct file_operations genpd_##name##_fops = { \
2548+
.open = genpd_##name##_open, \
2549+
.read = seq_read, \
2550+
.llseek = seq_lseek, \
2551+
.release = single_release, \
2552+
}
2553+
2554+
define_genpd_debugfs_fops(summary);
2555+
define_genpd_debugfs_fops(status);
2556+
define_genpd_debugfs_fops(sub_domains);
2557+
define_genpd_debugfs_fops(idle_states);
2558+
define_genpd_debugfs_fops(active_time);
2559+
define_genpd_debugfs_fops(total_idle_time);
2560+
define_genpd_debugfs_fops(devices);
23962561

23972562
static int __init pm_genpd_debug_init(void)
23982563
{
23992564
struct dentry *d;
2565+
struct generic_pm_domain *genpd;
24002566

24012567
pm_genpd_debugfs_dir = debugfs_create_dir("pm_genpd", NULL);
24022568

24032569
if (!pm_genpd_debugfs_dir)
24042570
return -ENOMEM;
24052571

24062572
d = debugfs_create_file("pm_genpd_summary", S_IRUGO,
2407-
pm_genpd_debugfs_dir, NULL, &pm_genpd_summary_fops);
2573+
pm_genpd_debugfs_dir, NULL, &genpd_summary_fops);
24082574
if (!d)
24092575
return -ENOMEM;
24102576

2577+
list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
2578+
d = debugfs_create_dir(genpd->name, pm_genpd_debugfs_dir);
2579+
if (!d)
2580+
return -ENOMEM;
2581+
2582+
debugfs_create_file("current_state", 0444,
2583+
d, genpd, &genpd_status_fops);
2584+
debugfs_create_file("sub_domains", 0444,
2585+
d, genpd, &genpd_sub_domains_fops);
2586+
debugfs_create_file("idle_states", 0444,
2587+
d, genpd, &genpd_idle_states_fops);
2588+
debugfs_create_file("active_time", 0444,
2589+
d, genpd, &genpd_active_time_fops);
2590+
debugfs_create_file("total_idle_time", 0444,
2591+
d, genpd, &genpd_total_idle_time_fops);
2592+
debugfs_create_file("devices", 0444,
2593+
d, genpd, &genpd_devices_fops);
2594+
}
2595+
24112596
return 0;
24122597
}
24132598
late_initcall(pm_genpd_debug_init);

0 commit comments

Comments
 (0)