2009-05-28 21:56:16 +04:00
/*
* OMAP Power Management debug routines
*
* Copyright ( C ) 2005 Texas Instruments , Inc .
* Copyright ( C ) 2006 - 2008 Nokia Corporation
*
* Written by :
* Richard Woodruff < r - woodruff2 @ ti . com >
* Tony Lindgren
* Juha Yrjola
* Amit Kucheria < amit . kucheria @ nokia . com >
* Igor Stoppa < igor . stoppa @ nokia . com >
* Jouni Hogander
*
* Based on pm . c for omap2
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
2008-10-15 19:13:48 +04:00
# include <linux/sched.h>
2009-05-28 21:56:16 +04:00
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/io.h>
2008-11-26 13:26:24 +03:00
# include <linux/module.h>
2009-05-28 21:56:16 +04:00
2009-10-20 20:40:47 +04:00
# include <plat/clock.h>
# include <plat/board.h>
# include <plat/powerdomain.h>
# include <plat/clockdomain.h>
2009-05-28 21:56:16 +04:00
# include "prm.h"
# include "cm.h"
# include "pm.h"
int omap2_pm_debug ;
# define DUMP_PRM_MOD_REG(mod, reg) \
regs [ reg_count ] . name = # mod " . " # reg ; \
regs [ reg_count + + ] . val = prm_read_mod_reg ( mod , reg )
# define DUMP_CM_MOD_REG(mod, reg) \
regs [ reg_count ] . name = # mod " . " # reg ; \
regs [ reg_count + + ] . val = cm_read_mod_reg ( mod , reg )
# define DUMP_PRM_REG(reg) \
regs [ reg_count ] . name = # reg ; \
regs [ reg_count + + ] . val = __raw_readl ( reg )
# define DUMP_CM_REG(reg) \
regs [ reg_count ] . name = # reg ; \
regs [ reg_count + + ] . val = __raw_readl ( reg )
# define DUMP_INTC_REG(reg, off) \
regs [ reg_count ] . name = # reg ; \
2009-10-20 02:25:31 +04:00
regs [ reg_count + + ] . val = \
__raw_readl ( OMAP2_L4_IO_ADDRESS ( 0x480fe000 + ( off ) ) )
2009-05-28 21:56:16 +04:00
void omap2_pm_dump ( int mode , int resume , unsigned int us )
{
struct reg {
const char * name ;
u32 val ;
} regs [ 32 ] ;
int reg_count = 0 , i ;
const char * s1 = NULL , * s2 = NULL ;
if ( ! resume ) {
#if 0
/* MPU */
DUMP_PRM_MOD_REG ( OCP_MOD , OMAP2_PRM_IRQENABLE_MPU_OFFSET ) ;
DUMP_CM_MOD_REG ( MPU_MOD , CM_CLKSTCTRL ) ;
2010-01-27 06:12:51 +03:00
DUMP_PRM_MOD_REG ( MPU_MOD , OMAP2_PM_PWSTCTRL ) ;
DUMP_PRM_MOD_REG ( MPU_MOD , OMAP2_PM_PWSTST ) ;
2009-05-28 21:56:16 +04:00
DUMP_PRM_MOD_REG ( MPU_MOD , PM_WKDEP ) ;
# endif
#if 0
/* INTC */
DUMP_INTC_REG ( INTC_MIR0 , 0x0084 ) ;
DUMP_INTC_REG ( INTC_MIR1 , 0x00a4 ) ;
DUMP_INTC_REG ( INTC_MIR2 , 0x00c4 ) ;
# endif
#if 0
DUMP_CM_MOD_REG ( CORE_MOD , CM_FCLKEN1 ) ;
if ( cpu_is_omap24xx ( ) ) {
DUMP_CM_MOD_REG ( CORE_MOD , OMAP24XX_CM_FCLKEN2 ) ;
DUMP_PRM_MOD_REG ( OMAP24XX_GR_MOD ,
OMAP2_PRCM_CLKEMUL_CTRL_OFFSET ) ;
DUMP_PRM_MOD_REG ( OMAP24XX_GR_MOD ,
OMAP2_PRCM_CLKSRC_CTRL_OFFSET ) ;
}
DUMP_CM_MOD_REG ( WKUP_MOD , CM_FCLKEN ) ;
DUMP_CM_MOD_REG ( CORE_MOD , CM_ICLKEN1 ) ;
DUMP_CM_MOD_REG ( CORE_MOD , CM_ICLKEN2 ) ;
DUMP_CM_MOD_REG ( WKUP_MOD , CM_ICLKEN ) ;
DUMP_CM_MOD_REG ( PLL_MOD , CM_CLKEN ) ;
DUMP_CM_MOD_REG ( PLL_MOD , CM_AUTOIDLE ) ;
2010-01-27 06:12:51 +03:00
DUMP_PRM_MOD_REG ( CORE_MOD , OMAP2_PM_PWSTST ) ;
2009-05-28 21:56:16 +04:00
# endif
#if 0
/* DSP */
if ( cpu_is_omap24xx ( ) ) {
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_FCLKEN ) ;
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_ICLKEN ) ;
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_IDLEST ) ;
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_AUTOIDLE ) ;
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_CLKSEL ) ;
DUMP_CM_MOD_REG ( OMAP24XX_DSP_MOD , CM_CLKSTCTRL ) ;
2010-01-27 06:12:51 +03:00
DUMP_PRM_MOD_REG ( OMAP24XX_DSP_MOD , OMAP2_RM_RSTCTRL ) ;
DUMP_PRM_MOD_REG ( OMAP24XX_DSP_MOD , OMAP2_RM_RSTST ) ;
DUMP_PRM_MOD_REG ( OMAP24XX_DSP_MOD , OMAP2_PM_PWSTCTRL ) ;
DUMP_PRM_MOD_REG ( OMAP24XX_DSP_MOD , OMAP2_PM_PWSTST ) ;
2009-05-28 21:56:16 +04:00
}
# endif
} else {
DUMP_PRM_MOD_REG ( CORE_MOD , PM_WKST1 ) ;
if ( cpu_is_omap24xx ( ) )
DUMP_PRM_MOD_REG ( CORE_MOD , OMAP24XX_PM_WKST2 ) ;
DUMP_PRM_MOD_REG ( WKUP_MOD , PM_WKST ) ;
DUMP_PRM_MOD_REG ( OCP_MOD , OMAP2_PRCM_IRQSTATUS_MPU_OFFSET ) ;
# if 1
DUMP_INTC_REG ( INTC_PENDING_IRQ0 , 0x0098 ) ;
DUMP_INTC_REG ( INTC_PENDING_IRQ1 , 0x00b8 ) ;
DUMP_INTC_REG ( INTC_PENDING_IRQ2 , 0x00d8 ) ;
# endif
}
switch ( mode ) {
case 0 :
s1 = " full " ;
s2 = " retention " ;
break ;
case 1 :
s1 = " MPU " ;
s2 = " retention " ;
break ;
case 2 :
s1 = " MPU " ;
s2 = " idle " ;
break ;
}
if ( ! resume )
# ifdef CONFIG_NO_HZ
printk ( KERN_INFO
" --- Going to %s %s (next timer after %u ms) \n " , s1 , s2 ,
jiffies_to_msecs ( get_next_timer_interrupt ( jiffies ) -
jiffies ) ) ;
# else
printk ( KERN_INFO " --- Going to %s %s \n " , s1 , s2 ) ;
# endif
else
printk ( KERN_INFO " --- Woke up (slept for %u.%03u ms) \n " ,
us / 1000 , us % 1000 ) ;
for ( i = 0 ; i < reg_count ; i + + )
printk ( KERN_INFO " %-20s: 0x%08x \n " , regs [ i ] . name , regs [ i ] . val ) ;
}
2008-10-15 19:13:48 +04:00
# ifdef CONFIG_DEBUG_FS
# include <linux/debugfs.h>
# include <linux/seq_file.h>
2008-10-29 14:31:24 +03:00
static void pm_dbg_regset_store ( u32 * ptr ) ;
2008-10-15 19:13:48 +04:00
struct dentry * pm_dbg_dir ;
static int pm_dbg_init_done ;
2010-01-14 20:01:15 +03:00
static int __init pm_dbg_init ( void ) ;
2008-10-15 19:13:48 +04:00
enum {
DEBUG_FILE_COUNTERS = 0 ,
DEBUG_FILE_TIMERS ,
} ;
2008-10-29 14:31:24 +03:00
struct pm_module_def {
char name [ 8 ] ; /* Name of the module */
short type ; /* CM or PRM */
unsigned short offset ;
int low ; /* First register address on this module */
int high ; /* Last register address on this module */
} ;
# define MOD_CM 0
# define MOD_PRM 1
static const struct pm_module_def * pm_dbg_reg_modules ;
static const struct pm_module_def omap3_pm_reg_modules [ ] = {
{ " IVA2 " , MOD_CM , OMAP3430_IVA2_MOD , 0 , 0x4c } ,
{ " OCP " , MOD_CM , OCP_MOD , 0 , 0x10 } ,
{ " MPU " , MOD_CM , MPU_MOD , 4 , 0x4c } ,
{ " CORE " , MOD_CM , CORE_MOD , 0 , 0x4c } ,
{ " SGX " , MOD_CM , OMAP3430ES2_SGX_MOD , 0 , 0x4c } ,
{ " WKUP " , MOD_CM , WKUP_MOD , 0 , 0x40 } ,
{ " CCR " , MOD_CM , PLL_MOD , 0 , 0x70 } ,
{ " DSS " , MOD_CM , OMAP3430_DSS_MOD , 0 , 0x4c } ,
{ " CAM " , MOD_CM , OMAP3430_CAM_MOD , 0 , 0x4c } ,
{ " PER " , MOD_CM , OMAP3430_PER_MOD , 0 , 0x4c } ,
{ " EMU " , MOD_CM , OMAP3430_EMU_MOD , 0x40 , 0x54 } ,
{ " NEON " , MOD_CM , OMAP3430_NEON_MOD , 0x20 , 0x48 } ,
{ " USB " , MOD_CM , OMAP3430ES2_USBHOST_MOD , 0 , 0x4c } ,
{ " IVA2 " , MOD_PRM , OMAP3430_IVA2_MOD , 0x50 , 0xfc } ,
{ " OCP " , MOD_PRM , OCP_MOD , 4 , 0x1c } ,
{ " MPU " , MOD_PRM , MPU_MOD , 0x58 , 0xe8 } ,
{ " CORE " , MOD_PRM , CORE_MOD , 0x58 , 0xf8 } ,
{ " SGX " , MOD_PRM , OMAP3430ES2_SGX_MOD , 0x58 , 0xe8 } ,
{ " WKUP " , MOD_PRM , WKUP_MOD , 0xa0 , 0xb0 } ,
{ " CCR " , MOD_PRM , PLL_MOD , 0x40 , 0x70 } ,
{ " DSS " , MOD_PRM , OMAP3430_DSS_MOD , 0x58 , 0xe8 } ,
{ " CAM " , MOD_PRM , OMAP3430_CAM_MOD , 0x58 , 0xe8 } ,
{ " PER " , MOD_PRM , OMAP3430_PER_MOD , 0x58 , 0xe8 } ,
{ " EMU " , MOD_PRM , OMAP3430_EMU_MOD , 0x58 , 0xe4 } ,
{ " GLBL " , MOD_PRM , OMAP3430_GR_MOD , 0x20 , 0xe4 } ,
{ " NEON " , MOD_PRM , OMAP3430_NEON_MOD , 0x58 , 0xe8 } ,
{ " USB " , MOD_PRM , OMAP3430ES2_USBHOST_MOD , 0x58 , 0xe8 } ,
{ " " , 0 , 0 , 0 , 0 } ,
} ;
# define PM_DBG_MAX_REG_SETS 4
static void * pm_dbg_reg_set [ PM_DBG_MAX_REG_SETS ] ;
static int pm_dbg_get_regset_size ( void )
{
static int regset_size ;
if ( regset_size = = 0 ) {
int i = 0 ;
while ( pm_dbg_reg_modules [ i ] . name [ 0 ] ! = 0 ) {
regset_size + = pm_dbg_reg_modules [ i ] . high +
4 - pm_dbg_reg_modules [ i ] . low ;
i + + ;
}
}
return regset_size ;
}
static int pm_dbg_show_regs ( struct seq_file * s , void * unused )
{
int i , j ;
unsigned long val ;
int reg_set = ( int ) s - > private ;
u32 * ptr ;
void * store = NULL ;
int regs ;
int linefeed ;
if ( reg_set = = 0 ) {
store = kmalloc ( pm_dbg_get_regset_size ( ) , GFP_KERNEL ) ;
ptr = store ;
pm_dbg_regset_store ( ptr ) ;
} else {
ptr = pm_dbg_reg_set [ reg_set - 1 ] ;
}
i = 0 ;
while ( pm_dbg_reg_modules [ i ] . name [ 0 ] ! = 0 ) {
regs = 0 ;
linefeed = 0 ;
if ( pm_dbg_reg_modules [ i ] . type = = MOD_CM )
seq_printf ( s , " MOD: CM_%s (%08x) \n " ,
pm_dbg_reg_modules [ i ] . name ,
( u32 ) ( OMAP3430_CM_BASE +
pm_dbg_reg_modules [ i ] . offset ) ) ;
else
seq_printf ( s , " MOD: PRM_%s (%08x) \n " ,
pm_dbg_reg_modules [ i ] . name ,
( u32 ) ( OMAP3430_PRM_BASE +
pm_dbg_reg_modules [ i ] . offset ) ) ;
for ( j = pm_dbg_reg_modules [ i ] . low ;
j < = pm_dbg_reg_modules [ i ] . high ; j + = 4 ) {
val = * ( ptr + + ) ;
if ( val ! = 0 ) {
regs + + ;
if ( linefeed ) {
seq_printf ( s , " \n " ) ;
linefeed = 0 ;
}
seq_printf ( s , " %02x => %08lx " , j , val ) ;
if ( regs % 4 = = 0 )
linefeed = 1 ;
}
}
seq_printf ( s , " \n " ) ;
i + + ;
}
if ( store ! = NULL )
kfree ( store ) ;
return 0 ;
}
static void pm_dbg_regset_store ( u32 * ptr )
{
int i , j ;
u32 val ;
i = 0 ;
while ( pm_dbg_reg_modules [ i ] . name [ 0 ] ! = 0 ) {
for ( j = pm_dbg_reg_modules [ i ] . low ;
j < = pm_dbg_reg_modules [ i ] . high ; j + = 4 ) {
if ( pm_dbg_reg_modules [ i ] . type = = MOD_CM )
val = cm_read_mod_reg (
pm_dbg_reg_modules [ i ] . offset , j ) ;
else
val = prm_read_mod_reg (
pm_dbg_reg_modules [ i ] . offset , j ) ;
* ( ptr + + ) = val ;
}
i + + ;
}
}
int pm_dbg_regset_save ( int reg_set )
{
if ( pm_dbg_reg_set [ reg_set - 1 ] = = NULL )
return - EINVAL ;
pm_dbg_regset_store ( pm_dbg_reg_set [ reg_set - 1 ] ) ;
return 0 ;
}
2009-12-09 02:33:12 +03:00
static const char pwrdm_state_names [ ] [ PWRDM_MAX_PWRSTS ] = {
2008-10-15 19:13:48 +04:00
" 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 ] ) ;
2009-12-09 02:33:12 +03:00
for ( i = 0 ; i < PWRDM_MAX_PWRSTS ; i + + )
2008-10-15 19:13:48 +04:00
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 ) ;
} ;
}
2008-10-29 14:31:24 +03:00
static int pm_dbg_reg_open ( struct inode * inode , struct file * file )
{
return single_open ( file , pm_dbg_show_regs , inode - > i_private ) ;
}
2008-10-15 19:13:48 +04:00
static const struct file_operations debug_fops = {
. open = pm_dbg_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
2008-10-29 14:31:24 +03:00
static const struct file_operations debug_reg_fops = {
. open = pm_dbg_reg_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
int pm_dbg_regset_init ( int reg_set )
{
char name [ 2 ] ;
if ( ! pm_dbg_init_done )
pm_dbg_init ( ) ;
if ( reg_set < 1 | | reg_set > PM_DBG_MAX_REG_SETS | |
pm_dbg_reg_set [ reg_set - 1 ] ! = NULL )
return - EINVAL ;
pm_dbg_reg_set [ reg_set - 1 ] =
kmalloc ( pm_dbg_get_regset_size ( ) , GFP_KERNEL ) ;
if ( pm_dbg_reg_set [ reg_set - 1 ] = = NULL )
return - ENOMEM ;
if ( pm_dbg_dir ! = NULL ) {
sprintf ( name , " %d " , reg_set ) ;
( void ) debugfs_create_file ( name , S_IRUGO ,
pm_dbg_dir , ( void * ) reg_set , & debug_reg_fops ) ;
}
return 0 ;
}
2008-11-26 13:26:24 +03:00
static int pwrdm_suspend_get ( void * data , u64 * val )
{
2009-12-16 19:22:04 +03:00
int ret ;
ret = omap3_pm_get_suspend_state ( ( struct powerdomain * ) data ) ;
* val = ret ;
2008-11-26 13:26:24 +03:00
2009-12-16 19:22:04 +03:00
if ( ret > = 0 )
2008-11-26 13:26:24 +03:00
return 0 ;
return * val ;
}
static int pwrdm_suspend_set ( void * data , u64 val )
{
return omap3_pm_set_suspend_state ( ( struct powerdomain * ) data , ( int ) val ) ;
}
DEFINE_SIMPLE_ATTRIBUTE ( pwrdm_suspend_fops , pwrdm_suspend_get ,
pwrdm_suspend_set , " %llu \n " ) ;
static int __init pwrdms_setup ( struct powerdomain * pwrdm , void * dir )
2008-10-15 19:13:48 +04:00
{
int i ;
s64 t ;
2008-11-26 13:26:24 +03:00
struct dentry * d ;
2008-10-15 19:13:48 +04:00
t = sched_clock ( ) ;
for ( i = 0 ; i < 4 ; i + + )
pwrdm - > state_timer [ i ] = 0 ;
pwrdm - > timer = t ;
2008-11-26 13:26:24 +03:00
if ( strncmp ( pwrdm - > name , " dpll " , 4 ) = = 0 )
return 0 ;
d = debugfs_create_dir ( pwrdm - > name , ( struct dentry * ) dir ) ;
( void ) debugfs_create_file ( " suspend " , S_IRUGO | S_IWUSR , d ,
( void * ) pwrdm , & pwrdm_suspend_fops ) ;
2008-10-15 19:13:48 +04:00
return 0 ;
}
2009-10-07 01:25:09 +04:00
static int option_get ( void * data , u64 * val )
{
u32 * option = data ;
* val = * option ;
return 0 ;
}
static int option_set ( void * data , u64 val )
{
u32 * option = data ;
* option = val ;
if ( option = = & enable_off_mode )
omap3_pm_off_mode_enable ( val ) ;
return 0 ;
}
DEFINE_SIMPLE_ATTRIBUTE ( pm_dbg_option_fops , option_get , option_set , " %llu \n " ) ;
2008-10-15 19:13:48 +04:00
static int __init pm_dbg_init ( void )
{
2008-10-29 14:31:24 +03:00
int i ;
2008-10-15 19:13:48 +04:00
struct dentry * d ;
2008-10-29 14:31:24 +03:00
char name [ 2 ] ;
2008-10-15 19:13:48 +04:00
2008-10-29 14:31:24 +03:00
if ( pm_dbg_init_done )
return 0 ;
if ( cpu_is_omap34xx ( ) )
pm_dbg_reg_modules = omap3_pm_reg_modules ;
else {
printk ( KERN_ERR " %s: only OMAP3 supported \n " , __func__ ) ;
return - ENODEV ;
}
2009-10-01 11:01:55 +04:00
2008-10-15 19:13:48 +04:00
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 ) ;
2009-10-01 11:01:55 +04:00
pwrdm_for_each_nolock ( pwrdms_setup , ( void * ) d ) ;
2008-10-15 19:13:48 +04:00
2008-10-29 14:31:24 +03:00
pm_dbg_dir = debugfs_create_dir ( " registers " , d ) ;
if ( IS_ERR ( pm_dbg_dir ) )
return PTR_ERR ( pm_dbg_dir ) ;
( void ) debugfs_create_file ( " current " , S_IRUGO ,
pm_dbg_dir , ( void * ) 0 , & debug_reg_fops ) ;
for ( i = 0 ; i < PM_DBG_MAX_REG_SETS ; i + + )
if ( pm_dbg_reg_set [ i ] ! = NULL ) {
sprintf ( name , " %d " , i + 1 ) ;
( void ) debugfs_create_file ( name , S_IRUGO ,
pm_dbg_dir , ( void * ) ( i + 1 ) , & debug_reg_fops ) ;
}
2009-10-07 01:25:09 +04:00
( void ) debugfs_create_file ( " enable_off_mode " , S_IRUGO | S_IWUGO , d ,
& enable_off_mode , & pm_dbg_option_fops ) ;
( void ) debugfs_create_file ( " sleep_while_idle " , S_IRUGO | S_IWUGO , d ,
& sleep_while_idle , & pm_dbg_option_fops ) ;
2009-10-07 01:30:23 +04:00
( void ) debugfs_create_file ( " wakeup_timer_seconds " , S_IRUGO | S_IWUGO , d ,
& wakeup_timer_seconds , & pm_dbg_option_fops ) ;
2008-10-15 19:13:48 +04:00
pm_dbg_init_done = 1 ;
return 0 ;
}
2008-10-29 14:31:24 +03:00
arch_initcall ( pm_dbg_init ) ;
2008-10-15 19:13:48 +04:00
# endif