aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm-debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm-debug.c')
-rw-r--r--arch/arm/mach-omap2/pm-debug.c178
1 files changed, 177 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index da3a53f8ccc8..7383e85eac26 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -20,13 +20,15 @@
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/timer.h> 23#include <linux/sched.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/io.h> 26#include <linux/io.h>
27 27
28#include <mach/clock.h> 28#include <mach/clock.h>
29#include <mach/board.h> 29#include <mach/board.h>
30#include <mach/powerdomain.h>
31#include <mach/clockdomain.h>
30 32
31#include "prm.h" 33#include "prm.h"
32#include "cm.h" 34#include "cm.h"
@@ -150,3 +152,177 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
150 for (i = 0; i < reg_count; i++) 152 for (i = 0; i < reg_count; i++)
151 printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); 153 printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
152} 154}
155
156#ifdef CONFIG_DEBUG_FS
157#include <linux/debugfs.h>
158#include <linux/seq_file.h>
159
160struct dentry *pm_dbg_dir;
161
162static int pm_dbg_init_done;
163
164enum {
165 DEBUG_FILE_COUNTERS = 0,
166 DEBUG_FILE_TIMERS,
167};
168
169static const char pwrdm_state_names[][4] = {
170 "OFF",
171 "RET",
172 "INA",
173 "ON"
174};
175
176void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
177{
178 s64 t;
179
180 if (!pm_dbg_init_done)
181 return ;
182
183 /* Update timer for previous state */
184 t = sched_clock();
185
186 pwrdm->state_timer[prev] += t - pwrdm->timer;
187
188 pwrdm->timer = t;
189}
190
191static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
192{
193 struct seq_file *s = (struct seq_file *)user;
194
195 if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
196 strcmp(clkdm->name, "wkup_clkdm") == 0 ||
197 strncmp(clkdm->name, "dpll", 4) == 0)
198 return 0;
199
200 seq_printf(s, "%s->%s (%d)", clkdm->name,
201 clkdm->pwrdm.ptr->name,
202 atomic_read(&clkdm->usecount));
203 seq_printf(s, "\n");
204
205 return 0;
206}
207
208static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
209{
210 struct seq_file *s = (struct seq_file *)user;
211 int i;
212
213 if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
214 strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
215 strncmp(pwrdm->name, "dpll", 4) == 0)
216 return 0;
217
218 if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
219 printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
220 pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
221
222 seq_printf(s, "%s (%s)", pwrdm->name,
223 pwrdm_state_names[pwrdm->state]);
224 for (i = 0; i < 4; i++)
225 seq_printf(s, ",%s:%d", pwrdm_state_names[i],
226 pwrdm->state_counter[i]);
227
228 seq_printf(s, "\n");
229
230 return 0;
231}
232
233static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
234{
235 struct seq_file *s = (struct seq_file *)user;
236 int i;
237
238 if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
239 strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
240 strncmp(pwrdm->name, "dpll", 4) == 0)
241 return 0;
242
243 pwrdm_state_switch(pwrdm);
244
245 seq_printf(s, "%s (%s)", pwrdm->name,
246 pwrdm_state_names[pwrdm->state]);
247
248 for (i = 0; i < 4; i++)
249 seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
250 pwrdm->state_timer[i]);
251
252 seq_printf(s, "\n");
253 return 0;
254}
255
256static int pm_dbg_show_counters(struct seq_file *s, void *unused)
257{
258 pwrdm_for_each(pwrdm_dbg_show_counter, s);
259 clkdm_for_each(clkdm_dbg_show_counter, s);
260
261 return 0;
262}
263
264static int pm_dbg_show_timers(struct seq_file *s, void *unused)
265{
266 pwrdm_for_each(pwrdm_dbg_show_timer, s);
267 return 0;
268}
269
270static int pm_dbg_open(struct inode *inode, struct file *file)
271{
272 switch ((int)inode->i_private) {
273 case DEBUG_FILE_COUNTERS:
274 return single_open(file, pm_dbg_show_counters,
275 &inode->i_private);
276 case DEBUG_FILE_TIMERS:
277 default:
278 return single_open(file, pm_dbg_show_timers,
279 &inode->i_private);
280 };
281}
282
283static const struct file_operations debug_fops = {
284 .open = pm_dbg_open,
285 .read = seq_read,
286 .llseek = seq_lseek,
287 .release = single_release,
288};
289
290static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
291{
292 int i;
293 s64 t;
294
295 t = sched_clock();
296
297 for (i = 0; i < 4; i++)
298 pwrdm->state_timer[i] = 0;
299
300 pwrdm->timer = t;
301
302 return 0;
303}
304
305static int __init pm_dbg_init(void)
306{
307 struct dentry *d;
308
309 d = debugfs_create_dir("pm_debug", NULL);
310 if (IS_ERR(d))
311 return PTR_ERR(d);
312
313 (void) debugfs_create_file("count", S_IRUGO,
314 d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
315 (void) debugfs_create_file("time", S_IRUGO,
316 d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
317
318 pwrdm_for_each(pwrdms_setup, NULL);
319
320 pm_dbg_init_done = 1;
321
322 return 0;
323}
324late_initcall(pm_dbg_init);
325
326#else
327void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {}
328#endif