Merge branches 'x86-alternatives-for-linus', 'x86-fpu-for-linus', 'x86-hwmon-for...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-omap2 / pm-debug.c
CommitLineData
8bd22949
KH
1/*
2 * OMAP Power Management debug routines
3 *
4 * Copyright (C) 2005 Texas Instruments, Inc.
5 * Copyright (C) 2006-2008 Nokia Corporation
6 *
7 * Written by:
8 * Richard Woodruff <r-woodruff2@ti.com>
9 * Tony Lindgren
10 * Juha Yrjola
11 * Amit Kucheria <amit.kucheria@nokia.com>
12 * Igor Stoppa <igor.stoppa@nokia.com>
13 * Jouni Hogander
14 *
15 * Based on pm.c for omap2
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/kernel.h>
331b93f4 23#include <linux/sched.h>
8bd22949
KH
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/io.h>
68d4778c 27#include <linux/module.h>
5a0e3ad6 28#include <linux/slab.h>
8bd22949 29
ce491cf8
TL
30#include <plat/clock.h>
31#include <plat/board.h>
32#include <plat/powerdomain.h>
33#include <plat/clockdomain.h>
86b0c1e3 34#include <plat/dmtimer.h>
8bd22949
KH
35
36#include "prm.h"
37#include "cm.h"
38#include "pm.h"
39
40int omap2_pm_debug;
6cdee912
TG
41u32 enable_off_mode;
42u32 sleep_while_idle;
43u32 wakeup_timer_seconds;
44u32 wakeup_timer_milliseconds;
8bd22949
KH
45
46#define DUMP_PRM_MOD_REG(mod, reg) \
47 regs[reg_count].name = #mod "." #reg; \
48 regs[reg_count++].val = prm_read_mod_reg(mod, reg)
49#define DUMP_CM_MOD_REG(mod, reg) \
50 regs[reg_count].name = #mod "." #reg; \
51 regs[reg_count++].val = cm_read_mod_reg(mod, reg)
52#define DUMP_PRM_REG(reg) \
53 regs[reg_count].name = #reg; \
54 regs[reg_count++].val = __raw_readl(reg)
55#define DUMP_CM_REG(reg) \
56 regs[reg_count].name = #reg; \
57 regs[reg_count++].val = __raw_readl(reg)
58#define DUMP_INTC_REG(reg, off) \
59 regs[reg_count].name = #reg; \
233fd64e
SS
60 regs[reg_count++].val = \
61 __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
8bd22949
KH
62
63void omap2_pm_dump(int mode, int resume, unsigned int us)
64{
65 struct reg {
66 const char *name;
67 u32 val;
68 } regs[32];
69 int reg_count = 0, i;
70 const char *s1 = NULL, *s2 = NULL;
71
72 if (!resume) {
73#if 0
74 /* MPU */
75 DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
84c0c39a 76 DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL);
37903009
AP
77 DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL);
78 DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST);
8bd22949
KH
79 DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
80#endif
81#if 0
82 /* INTC */
83 DUMP_INTC_REG(INTC_MIR0, 0x0084);
84 DUMP_INTC_REG(INTC_MIR1, 0x00a4);
85 DUMP_INTC_REG(INTC_MIR2, 0x00c4);
86#endif
87#if 0
88 DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
89 if (cpu_is_omap24xx()) {
90 DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
91 DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
92 OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
93 DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
94 OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
95 }
96 DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
97 DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
98 DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
99 DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
100 DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
101 DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
37903009 102 DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST);
8bd22949
KH
103#endif
104#if 0
105 /* DSP */
106 if (cpu_is_omap24xx()) {
107 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
108 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
109 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
110 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
111 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
84c0c39a 112 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL);
37903009
AP
113 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTCTRL);
114 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTST);
115 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTCTRL);
116 DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTST);
8bd22949
KH
117 }
118#endif
119 } else {
120 DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
121 if (cpu_is_omap24xx())
122 DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
123 DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
124 DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
125#if 1
126 DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
127 DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
128 DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
129#endif
130 }
131
132 switch (mode) {
133 case 0:
134 s1 = "full";
135 s2 = "retention";
136 break;
137 case 1:
138 s1 = "MPU";
139 s2 = "retention";
140 break;
141 case 2:
142 s1 = "MPU";
143 s2 = "idle";
144 break;
145 }
146
147 if (!resume)
148#ifdef CONFIG_NO_HZ
149 printk(KERN_INFO
150 "--- Going to %s %s (next timer after %u ms)\n", s1, s2,
151 jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
152 jiffies));
153#else
154 printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
155#endif
156 else
157 printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
158 us / 1000, us % 1000);
159
160 for (i = 0; i < reg_count; i++)
161 printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
162}
331b93f4 163
9f5ead76
KH
164void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
165{
166 u32 tick_rate, cycles;
167
168 if (!seconds && !milliseconds)
169 return;
170
171 tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
172 cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
173 omap_dm_timer_stop(gptimer_wakeup);
174 omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
175
176 pr_info("PM: Resume timer in %u.%03u secs"
177 " (%d ticks at %d ticks/sec.)\n",
178 seconds, milliseconds, cycles, tick_rate);
179}
180
331b93f4
PDS
181#ifdef CONFIG_DEBUG_FS
182#include <linux/debugfs.h>
183#include <linux/seq_file.h>
184
2811d6b3
TK
185static void pm_dbg_regset_store(u32 *ptr);
186
38815733 187static struct dentry *pm_dbg_dir;
331b93f4
PDS
188
189static int pm_dbg_init_done;
190
6b34f9d4
SA
191static int __init pm_dbg_init(void);
192
331b93f4
PDS
193enum {
194 DEBUG_FILE_COUNTERS = 0,
195 DEBUG_FILE_TIMERS,
196};
197
2811d6b3
TK
198struct pm_module_def {
199 char name[8]; /* Name of the module */
200 short type; /* CM or PRM */
201 unsigned short offset;
202 int low; /* First register address on this module */
203 int high; /* Last register address on this module */
204};
205
206#define MOD_CM 0
207#define MOD_PRM 1
208
209static const struct pm_module_def *pm_dbg_reg_modules;
210static const struct pm_module_def omap3_pm_reg_modules[] = {
211 { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c },
212 { "OCP", MOD_CM, OCP_MOD, 0, 0x10 },
213 { "MPU", MOD_CM, MPU_MOD, 4, 0x4c },
214 { "CORE", MOD_CM, CORE_MOD, 0, 0x4c },
215 { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c },
216 { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 },
217 { "CCR", MOD_CM, PLL_MOD, 0, 0x70 },
218 { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c },
219 { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c },
220 { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c },
221 { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
222 { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
223 { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c },
224
225 { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc },
226 { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c },
227 { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 },
228 { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 },
229 { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 },
230 { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 },
231 { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 },
232 { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 },
233 { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 },
234 { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 },
235 { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
236 { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 },
237 { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
238 { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 },
239 { "", 0, 0, 0, 0 },
240};
241
242#define PM_DBG_MAX_REG_SETS 4
243
244static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS];
245
246static int pm_dbg_get_regset_size(void)
247{
248 static int regset_size;
249
250 if (regset_size == 0) {
251 int i = 0;
252
253 while (pm_dbg_reg_modules[i].name[0] != 0) {
254 regset_size += pm_dbg_reg_modules[i].high +
255 4 - pm_dbg_reg_modules[i].low;
256 i++;
257 }
258 }
259 return regset_size;
260}
261
262static int pm_dbg_show_regs(struct seq_file *s, void *unused)
263{
264 int i, j;
265 unsigned long val;
266 int reg_set = (int)s->private;
267 u32 *ptr;
268 void *store = NULL;
269 int regs;
270 int linefeed;
271
272 if (reg_set == 0) {
273 store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
274 ptr = store;
275 pm_dbg_regset_store(ptr);
276 } else {
277 ptr = pm_dbg_reg_set[reg_set - 1];
278 }
279
280 i = 0;
281
282 while (pm_dbg_reg_modules[i].name[0] != 0) {
283 regs = 0;
284 linefeed = 0;
285 if (pm_dbg_reg_modules[i].type == MOD_CM)
286 seq_printf(s, "MOD: CM_%s (%08x)\n",
287 pm_dbg_reg_modules[i].name,
288 (u32)(OMAP3430_CM_BASE +
289 pm_dbg_reg_modules[i].offset));
290 else
291 seq_printf(s, "MOD: PRM_%s (%08x)\n",
292 pm_dbg_reg_modules[i].name,
293 (u32)(OMAP3430_PRM_BASE +
294 pm_dbg_reg_modules[i].offset));
295
296 for (j = pm_dbg_reg_modules[i].low;
297 j <= pm_dbg_reg_modules[i].high; j += 4) {
298 val = *(ptr++);
299 if (val != 0) {
300 regs++;
301 if (linefeed) {
302 seq_printf(s, "\n");
303 linefeed = 0;
304 }
305 seq_printf(s, " %02x => %08lx", j, val);
306 if (regs % 4 == 0)
307 linefeed = 1;
308 }
309 }
310 seq_printf(s, "\n");
311 i++;
312 }
313
314 if (store != NULL)
315 kfree(store);
316
317 return 0;
318}
319
320static void pm_dbg_regset_store(u32 *ptr)
321{
322 int i, j;
323 u32 val;
324
325 i = 0;
326
327 while (pm_dbg_reg_modules[i].name[0] != 0) {
328 for (j = pm_dbg_reg_modules[i].low;
329 j <= pm_dbg_reg_modules[i].high; j += 4) {
330 if (pm_dbg_reg_modules[i].type == MOD_CM)
331 val = cm_read_mod_reg(
332 pm_dbg_reg_modules[i].offset, j);
333 else
334 val = prm_read_mod_reg(
335 pm_dbg_reg_modules[i].offset, j);
336 *(ptr++) = val;
337 }
338 i++;
339 }
340}
341
342int pm_dbg_regset_save(int reg_set)
343{
344 if (pm_dbg_reg_set[reg_set-1] == NULL)
345 return -EINVAL;
346
347 pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]);
348
349 return 0;
350}
351
2354eb5a 352static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
331b93f4
PDS
353 "OFF",
354 "RET",
355 "INA",
356 "ON"
357};
358
359void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
360{
361 s64 t;
362
363 if (!pm_dbg_init_done)
364 return ;
365
366 /* Update timer for previous state */
367 t = sched_clock();
368
369 pwrdm->state_timer[prev] += t - pwrdm->timer;
370
371 pwrdm->timer = t;
372}
373
374static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
375{
376 struct seq_file *s = (struct seq_file *)user;
377
378 if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
379 strcmp(clkdm->name, "wkup_clkdm") == 0 ||
380 strncmp(clkdm->name, "dpll", 4) == 0)
381 return 0;
382
383 seq_printf(s, "%s->%s (%d)", clkdm->name,
384 clkdm->pwrdm.ptr->name,
385 atomic_read(&clkdm->usecount));
386 seq_printf(s, "\n");
387
388 return 0;
389}
390
391static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
392{
393 struct seq_file *s = (struct seq_file *)user;
394 int i;
395
396 if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
397 strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
398 strncmp(pwrdm->name, "dpll", 4) == 0)
399 return 0;
400
401 if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
402 printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
403 pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
404
405 seq_printf(s, "%s (%s)", pwrdm->name,
406 pwrdm_state_names[pwrdm->state]);
2354eb5a 407 for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
331b93f4
PDS
408 seq_printf(s, ",%s:%d", pwrdm_state_names[i],
409 pwrdm->state_counter[i]);
410
cde08f81
TG
411 seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter);
412 for (i = 0; i < pwrdm->banks; i++)
413 seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
414 pwrdm->ret_mem_off_counter[i]);
415
331b93f4
PDS
416 seq_printf(s, "\n");
417
418 return 0;
419}
420
421static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
422{
423 struct seq_file *s = (struct seq_file *)user;
424 int i;
425
426 if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
427 strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
428 strncmp(pwrdm->name, "dpll", 4) == 0)
429 return 0;
430
431 pwrdm_state_switch(pwrdm);
432
433 seq_printf(s, "%s (%s)", pwrdm->name,
434 pwrdm_state_names[pwrdm->state]);
435
436 for (i = 0; i < 4; i++)
437 seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
438 pwrdm->state_timer[i]);
439
440 seq_printf(s, "\n");
441 return 0;
442}
443
444static int pm_dbg_show_counters(struct seq_file *s, void *unused)
445{
446 pwrdm_for_each(pwrdm_dbg_show_counter, s);
447 clkdm_for_each(clkdm_dbg_show_counter, s);
448
449 return 0;
450}
451
452static int pm_dbg_show_timers(struct seq_file *s, void *unused)
453{
454 pwrdm_for_each(pwrdm_dbg_show_timer, s);
455 return 0;
456}
457
458static int pm_dbg_open(struct inode *inode, struct file *file)
459{
460 switch ((int)inode->i_private) {
461 case DEBUG_FILE_COUNTERS:
462 return single_open(file, pm_dbg_show_counters,
463 &inode->i_private);
464 case DEBUG_FILE_TIMERS:
465 default:
466 return single_open(file, pm_dbg_show_timers,
467 &inode->i_private);
468 };
469}
470
2811d6b3
TK
471static int pm_dbg_reg_open(struct inode *inode, struct file *file)
472{
473 return single_open(file, pm_dbg_show_regs, inode->i_private);
474}
475
331b93f4
PDS
476static const struct file_operations debug_fops = {
477 .open = pm_dbg_open,
478 .read = seq_read,
479 .llseek = seq_lseek,
480 .release = single_release,
481};
482
2811d6b3
TK
483static const struct file_operations debug_reg_fops = {
484 .open = pm_dbg_reg_open,
485 .read = seq_read,
486 .llseek = seq_lseek,
487 .release = single_release,
488};
489
490int pm_dbg_regset_init(int reg_set)
491{
492 char name[2];
493
494 if (!pm_dbg_init_done)
495 pm_dbg_init();
496
497 if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS ||
498 pm_dbg_reg_set[reg_set-1] != NULL)
499 return -EINVAL;
500
501 pm_dbg_reg_set[reg_set-1] =
502 kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
503
504 if (pm_dbg_reg_set[reg_set-1] == NULL)
505 return -ENOMEM;
506
507 if (pm_dbg_dir != NULL) {
508 sprintf(name, "%d", reg_set);
509
510 (void) debugfs_create_file(name, S_IRUGO,
511 pm_dbg_dir, (void *)reg_set, &debug_reg_fops);
512 }
513
514 return 0;
515}
516
68d4778c
TK
517static int pwrdm_suspend_get(void *data, u64 *val)
518{
6cdee912
TG
519 int ret = -EINVAL;
520
521 if (cpu_is_omap34xx())
522 ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
61b17d97 523 *val = ret;
68d4778c 524
61b17d97 525 if (ret >= 0)
68d4778c
TK
526 return 0;
527 return *val;
528}
529
530static int pwrdm_suspend_set(void *data, u64 val)
531{
6cdee912
TG
532 if (cpu_is_omap34xx())
533 return omap3_pm_set_suspend_state(
534 (struct powerdomain *)data, (int)val);
535 return -EINVAL;
68d4778c
TK
536}
537
538DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
539 pwrdm_suspend_set, "%llu\n");
540
541static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
331b93f4
PDS
542{
543 int i;
544 s64 t;
68d4778c 545 struct dentry *d;
331b93f4
PDS
546
547 t = sched_clock();
548
549 for (i = 0; i < 4; i++)
550 pwrdm->state_timer[i] = 0;
551
552 pwrdm->timer = t;
553
68d4778c
TK
554 if (strncmp(pwrdm->name, "dpll", 4) == 0)
555 return 0;
556
557 d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir);
558
559 (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
560 (void *)pwrdm, &pwrdm_suspend_fops);
561
331b93f4
PDS
562 return 0;
563}
564
c40552bc
KH
565static int option_get(void *data, u64 *val)
566{
567 u32 *option = data;
568
569 *val = *option;
570
571 return 0;
572}
573
574static int option_set(void *data, u64 val)
575{
576 u32 *option = data;
577
8e2efde9
AK
578 if (option == &wakeup_timer_milliseconds && val >= 1000)
579 return -EINVAL;
580
c40552bc
KH
581 *option = val;
582
6cdee912
TG
583 if (option == &enable_off_mode) {
584 if (cpu_is_omap34xx())
585 omap3_pm_off_mode_enable(val);
586 }
c40552bc
KH
587
588 return 0;
589}
590
591DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
592
331b93f4
PDS
593static int __init pm_dbg_init(void)
594{
2811d6b3 595 int i;
331b93f4 596 struct dentry *d;
2811d6b3 597 char name[2];
331b93f4 598
2811d6b3
TK
599 if (pm_dbg_init_done)
600 return 0;
601
602 if (cpu_is_omap34xx())
603 pm_dbg_reg_modules = omap3_pm_reg_modules;
604 else {
605 printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
606 return -ENODEV;
607 }
ee894b18 608
331b93f4
PDS
609 d = debugfs_create_dir("pm_debug", NULL);
610 if (IS_ERR(d))
611 return PTR_ERR(d);
612
613 (void) debugfs_create_file("count", S_IRUGO,
614 d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
615 (void) debugfs_create_file("time", S_IRUGO,
616 d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
617
e909d62a 618 pwrdm_for_each(pwrdms_setup, (void *)d);
331b93f4 619
2811d6b3
TK
620 pm_dbg_dir = debugfs_create_dir("registers", d);
621 if (IS_ERR(pm_dbg_dir))
622 return PTR_ERR(pm_dbg_dir);
623
624 (void) debugfs_create_file("current", S_IRUGO,
625 pm_dbg_dir, (void *)0, &debug_reg_fops);
626
627 for (i = 0; i < PM_DBG_MAX_REG_SETS; i++)
628 if (pm_dbg_reg_set[i] != NULL) {
629 sprintf(name, "%d", i+1);
630 (void) debugfs_create_file(name, S_IRUGO,
631 pm_dbg_dir, (void *)(i+1), &debug_reg_fops);
632
633 }
634
c40552bc
KH
635 (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUGO, d,
636 &enable_off_mode, &pm_dbg_option_fops);
637 (void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUGO, d,
638 &sleep_while_idle, &pm_dbg_option_fops);
d7814e4d
KH
639 (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
640 &wakeup_timer_seconds, &pm_dbg_option_fops);
315e2556
SS
641 (void) debugfs_create_file("wakeup_timer_milliseconds",
642 S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds,
643 &pm_dbg_option_fops);
331b93f4
PDS
644 pm_dbg_init_done = 1;
645
646 return 0;
647}
2811d6b3 648arch_initcall(pm_dbg_init);
331b93f4 649
331b93f4 650#endif