Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163144
b: refs/heads/master
c: 331b93f
h: refs/heads/master
v: v3
  • Loading branch information
Peter 'p2' De Schrijver authored and Kevin Hilman committed Sep 2, 2009
1 parent d4c6b85 commit fbf01cc
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a23456e9b02b3fae0fc78cb33fad69803a50e5bc
refs/heads/master: 331b93f41dff21c8f95709032cb184fb82bf2003
178 changes: 177 additions & 1 deletion trunk/arch/arm/mach-omap2/pm-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
*/

#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>

#include <mach/clock.h>
#include <mach/board.h>
#include <mach/powerdomain.h>
#include <mach/clockdomain.h>

#include "prm.h"
#include "cm.h"
Expand Down Expand Up @@ -150,3 +152,177 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
for (i = 0; i < reg_count; i++)
printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
}

#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>

struct dentry *pm_dbg_dir;

static int pm_dbg_init_done;

enum {
DEBUG_FILE_COUNTERS = 0,
DEBUG_FILE_TIMERS,
};

static const char pwrdm_state_names[][4] = {
"OFF",
"RET",
"INA",
"ON"
};

void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
{
s64 t;

if (!pm_dbg_init_done)
return ;

/* Update timer for previous state */
t = sched_clock();

pwrdm->state_timer[prev] += t - pwrdm->timer;

pwrdm->timer = t;
}

static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;

if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
strcmp(clkdm->name, "wkup_clkdm") == 0 ||
strncmp(clkdm->name, "dpll", 4) == 0)
return 0;

seq_printf(s, "%s->%s (%d)", clkdm->name,
clkdm->pwrdm.ptr->name,
atomic_read(&clkdm->usecount));
seq_printf(s, "\n");

return 0;
}

static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
int i;

if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
strncmp(pwrdm->name, "dpll", 4) == 0)
return 0;

if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));

seq_printf(s, "%s (%s)", pwrdm->name,
pwrdm_state_names[pwrdm->state]);
for (i = 0; i < 4; i++)
seq_printf(s, ",%s:%d", pwrdm_state_names[i],
pwrdm->state_counter[i]);

seq_printf(s, "\n");

return 0;
}

static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
int i;

if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
strncmp(pwrdm->name, "dpll", 4) == 0)
return 0;

pwrdm_state_switch(pwrdm);

seq_printf(s, "%s (%s)", pwrdm->name,
pwrdm_state_names[pwrdm->state]);

for (i = 0; i < 4; i++)
seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
pwrdm->state_timer[i]);

seq_printf(s, "\n");
return 0;
}

static int pm_dbg_show_counters(struct seq_file *s, void *unused)
{
pwrdm_for_each(pwrdm_dbg_show_counter, s);
clkdm_for_each(clkdm_dbg_show_counter, s);

return 0;
}

static int pm_dbg_show_timers(struct seq_file *s, void *unused)
{
pwrdm_for_each(pwrdm_dbg_show_timer, s);
return 0;
}

static int pm_dbg_open(struct inode *inode, struct file *file)
{
switch ((int)inode->i_private) {
case DEBUG_FILE_COUNTERS:
return single_open(file, pm_dbg_show_counters,
&inode->i_private);
case DEBUG_FILE_TIMERS:
default:
return single_open(file, pm_dbg_show_timers,
&inode->i_private);
};
}

static const struct file_operations debug_fops = {
.open = pm_dbg_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
{
int i;
s64 t;

t = sched_clock();

for (i = 0; i < 4; i++)
pwrdm->state_timer[i] = 0;

pwrdm->timer = t;

return 0;
}

static int __init pm_dbg_init(void)
{
struct dentry *d;

d = debugfs_create_dir("pm_debug", NULL);
if (IS_ERR(d))
return PTR_ERR(d);

(void) debugfs_create_file("count", S_IRUGO,
d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
(void) debugfs_create_file("time", S_IRUGO,
d, (void *)DEBUG_FILE_TIMERS, &debug_fops);

pwrdm_for_each(pwrdms_setup, NULL);

pm_dbg_init_done = 1;

return 0;
}
late_initcall(pm_dbg_init);

#else
void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {}
#endif
4 changes: 4 additions & 0 deletions trunk/arch/arm/mach-omap2/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
#define __ARCH_ARM_MACH_OMAP2_PM_H

#include <mach/powerdomain.h>

#ifdef CONFIG_PM_DEBUG
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
extern int omap2_pm_debug;
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
#else
#define omap2_pm_dump(mode, resume, us) do {} while (0);
#define omap2_pm_debug 0
#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
#endif /* CONFIG_PM_DEBUG */

extern void omap24xx_idle_loop_suspend(void);
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/arm/plat-omap/include/mach/powerdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ struct powerdomain {

int state;
unsigned state_counter[4];

#ifdef CONFIG_PM_DEBUG
s64 timer;
s64 state_timer[4];
#endif
};


Expand Down

0 comments on commit fbf01cc

Please sign in to comment.