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> 23 #include <linux/sched.h> 24 #include <linux/clk.h> 25 #include <linux/err.h> 26 #include <linux/io.h> 27 #include <linux/module.h> 28 #include <linux/slab.h> 29 30 #include <plat/clock.h> 31 #include <plat/board.h> 32 #include <plat/powerdomain.h> 33 #include <plat/clockdomain.h> 34 #include <plat/dmtimer.h> 35 36 #include "prm.h" 37 #include "cm.h" 38 #include "pm.h" 39 40 int omap2_pm_debug; 41 u32 enable_off_mode; 42 u32 sleep_while_idle; 43 u32 wakeup_timer_seconds; 44 u32 wakeup_timer_milliseconds; 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; \ 60 regs[reg_count++].val = \ 61 __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off))) 62 63 void 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); 76 DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL); 77 DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL); 78 DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST); 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); 102 DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST); 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); 112 DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL); 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); 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 } 163 164 void 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 181 #ifdef CONFIG_DEBUG_FS 182 #include <linux/debugfs.h> 183 #include <linux/seq_file.h> 184 185 static void pm_dbg_regset_store(u32 *ptr); 186 187 static struct dentry *pm_dbg_dir; 188 189 static int pm_dbg_init_done; 190 191 static int __init pm_dbg_init(void); 192 193 enum { 194 DEBUG_FILE_COUNTERS = 0, 195 DEBUG_FILE_TIMERS, 196 }; 197 198 struct 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 209 static const struct pm_module_def *pm_dbg_reg_modules; 210 static 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 244 static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS]; 245 246 static 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 262 static 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 320 static 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 342 int 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 352 static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = { 353 "OFF", 354 "RET", 355 "INA", 356 "ON" 357 }; 358 359 void 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 374 static 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 391 static 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]); 407 for (i = 0; i < PWRDM_MAX_PWRSTS; i++) 408 seq_printf(s, ",%s:%d", pwrdm_state_names[i], 409 pwrdm->state_counter[i]); 410 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 416 seq_printf(s, "\n"); 417 418 return 0; 419 } 420 421 static 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 444 static 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 452 static 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 458 static 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 471 static 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 476 static 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 483 static 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 490 int 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 517 static int pwrdm_suspend_get(void *data, u64 *val) 518 { 519 int ret = -EINVAL; 520 521 if (cpu_is_omap34xx()) 522 ret = omap3_pm_get_suspend_state((struct powerdomain *)data); 523 *val = ret; 524 525 if (ret >= 0) 526 return 0; 527 return *val; 528 } 529 530 static int pwrdm_suspend_set(void *data, u64 val) 531 { 532 if (cpu_is_omap34xx()) 533 return omap3_pm_set_suspend_state( 534 (struct powerdomain *)data, (int)val); 535 return -EINVAL; 536 } 537 538 DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get, 539 pwrdm_suspend_set, "%llu\n"); 540 541 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) 542 { 543 int i; 544 s64 t; 545 struct dentry *d; 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 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 562 return 0; 563 } 564 565 static int option_get(void *data, u64 *val) 566 { 567 u32 *option = data; 568 569 *val = *option; 570 571 return 0; 572 } 573 574 static int option_set(void *data, u64 val) 575 { 576 u32 *option = data; 577 578 if (option == &wakeup_timer_milliseconds && val >= 1000) 579 return -EINVAL; 580 581 *option = val; 582 583 if (option == &enable_off_mode) { 584 if (cpu_is_omap34xx()) 585 omap3_pm_off_mode_enable(val); 586 } 587 588 return 0; 589 } 590 591 DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n"); 592 593 static int __init pm_dbg_init(void) 594 { 595 int i; 596 struct dentry *d; 597 char name[2]; 598 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 } 608 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 618 pwrdm_for_each(pwrdms_setup, (void *)d); 619 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 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); 639 (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d, 640 &wakeup_timer_seconds, &pm_dbg_option_fops); 641 (void) debugfs_create_file("wakeup_timer_milliseconds", 642 S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds, 643 &pm_dbg_option_fops); 644 pm_dbg_init_done = 1; 645 646 return 0; 647 } 648 arch_initcall(pm_dbg_init); 649 650 #endif 651