public inbox for linux-sh@vger.kernel.org
 help / color / mirror / Atom feed
From: Francesco VIRLINZI <francesco.virlinzi@st.com>
To: linux-sh@vger.kernel.org
Subject: Re: [PATCH] stm: pm: Rework the suspend SOC code
Date: Mon, 18 May 2009 13:19:26 +0000	[thread overview]
Message-ID: <4A11605E.50004@st.com> (raw)
In-Reply-To: <1242652698-12170-1-git-send-email-francesco.virlinzi@st.com>

Sorry!
I sent the patch on the wrong mail-list
Regards
 Francesco
Francesco VIRLINZI ha scritto:
> Changed the suspend SOC code based on the registration mechanism
>
> Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
> ---
>  arch/sh/kernel/cpu/sh4/clock-stx7200.c   |    5 +-
>  arch/sh/kernel/cpu/sh4/soc-stb7100.h     |    7 ++
>  arch/sh/kernel/cpu/sh4/soc-stx5197.h     |   17 ++--
>  arch/sh/kernel/cpu/sh4/soc-stx7141.h     |    2 +-
>  arch/sh/kernel/cpu/sh4/soc-stx7200.h     |   34 +++++----
>  arch/sh/kernel/cpu/sh4/suspend-stb7100.c |  102 ++++++++++----------------
>  arch/sh/kernel/cpu/sh4/suspend-stx5197.c |  119 ++++++++++++-----------------
>  arch/sh/kernel/cpu/sh4/suspend-stx7105.c |  112 +++++++++++-----------------
>  arch/sh/kernel/cpu/sh4/suspend-stx7111.c |   98 ++++++++++--------------
>  arch/sh/kernel/cpu/sh4/suspend-stx7141.c |  102 +++++++++++---------------
>  arch/sh/kernel/cpu/sh4/suspend-stx7200.c |   94 ++++++++++--------------
>  11 files changed, 294 insertions(+), 398 deletions(-)
>
> diff --git a/arch/sh/kernel/cpu/sh4/clock-stx7200.c b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> index cf03964..ce6a92d 100644
> --- a/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> +++ b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> @@ -620,8 +620,9 @@ int clk_pm_state(pm_message_t state)
>  		tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
>  		writel(tmp & ~CLKB_PLL0_OFF,
>  			CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
> -
> -		mdelay(10); /* wait for stable signal */
> +		/* Wait PllB lock */
> +		while ((readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG)
> +			& CLKB_PLL0_LOCK) != 0);
>  		tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
>  		writel(tmp & ~CLKB_PLL0_BYPASS,
>  			CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stb7100.h b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> index 8f75fd8..20fa102 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> @@ -22,6 +22,10 @@
>    #define CLKA_PLL0_ENABLE		(1 << 19)
>    #define CLKA_PLL0_SUSPEND		((5 << 16) | (100 << 8) | \
>  	(CONFIG_SH_EXTERNAL_CLOCK / 1000000))
> +
> +#define CLKA_PLL0_LOCK			0x10
> +  #define CLKA_PLL0_LOCK_LOCKED		0x01
> +
>  #define CLKA_ST40			0x14
>  #define CLKA_ST40_IC			0x18
>  #define CLKA_ST40_PER			0x1c
> @@ -30,6 +34,9 @@
>    #define CLKA_PLL1_ENABLE		(1 << 19)
>    #define CLKA_PLL1_SUSPEND		((5 << 16) | (100 << 8) | \
>  	(CONFIG_SH_EXTERNAL_CLOCK / 1000000))
> +#define CLKA_PLL1_LOCK			0x2C
> +  #define CLKA_PLL1_LOCK_LOCKED		0x01
> +
>  #define CLKA_CLK_DIV			0x30
>  #define CLKA_CLK_EN			0x34
>    #define CLKA_CLK_EN_ST231_AUD		(1 << 0)
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx5197.h b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> index 4009a76..54092e0 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> @@ -40,7 +40,8 @@ enum clocks_ID {
>  
>  #define CLK_PLL_CONFIG0(x)	((x*8)+0x0)
>  #define CLK_PLL_CONFIG1(x)	((x*8)+0x4)
> -  #define CLK_PLL_CONFIG1_POFF	(1<<13)
> +#define  CLK_PLL_CONFIG1_POFF	(1<<13)
> +#define  CLK_PLL_CONFIG1_LOCK	(1<<15)
>  
>  #define CLKDIV0_CONFIG0		0x90
>  #define CLKDIV1_4_CONFIG0(n)	(0x0a0 + ((n-1)*0xc))
> @@ -54,20 +55,20 @@ enum clocks_ID {
>  
>  
>  #define CLK_MODE_CTRL		0x110
> - #define CLK_MODE_CTRL_NULL	0x0
> - #define CLK_MODE_CTRL_X1	0x1
> - #define CLK_MODE_CTRL_PROG	0x2
> - #define CLK_MODE_CTRL_STDB	0x3
> +#define   CLK_MODE_CTRL_NULL	0x0
> +#define   CLK_MODE_CTRL_X1	0x1
> +#define   CLK_MODE_CTRL_PROG	0x2
> +#define   CLK_MODE_CTRL_STDB	0x3
>  
>  /*
>   * The REDUCED_PM is used in CLK_MODE_CTRL_PROG...
>   */
>  #define CLK_REDUCED_PM_CTRL	0x114
> - #define CLK_REDUCED_ON_XTAL_MEMSTDBY	(1<<11)
> - #define CLK_REDUCED_ON_XTAL_STDBY	(~(0x22))
> +#define   CLK_REDUCED_ON_XTAL_MEMSTDBY	(1<<11)
> +#define   CLK_REDUCED_ON_XTAL_STDBY	(~(0x22))
>  
>  #define CLK_LP_MODE_DIS0	0x118
> -  #define CLK_LP_MODE_DIS0_VALUE	((0x3 << 11) | (0x7ff & ~(1<<9)))
> +#define   CLK_LP_MODE_DIS0_VALUE	(0x3 << 11)
>  
>  #define CLK_LP_MODE_DIS2	0x11C
>  
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7141.h b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> index d98b506..5048610 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> @@ -21,7 +21,7 @@
>  #define CLOCKGENA_BASE_ADDR	0xfe213000	/* Clockgen A */
>  #define CLOCKGENB_BASE_ADDR	0xfe000000	/* Clockgen B */
>  
> -#define ckga_pll0_cfg			0x000
> +#define CKGA_PLL0_CFG			0x000
>    #define CKGA_PLL0_CFG_DIVRES		(1 << 20)
>    #define CKGA_PLL0_CFG_BYPASS		CKGA_PLL0_CFG_DIVRES
>    #define CKGA_PLL0_CFG_LOCK		(1 << 31)
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7200.h b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> index 9045b16..5933506 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> @@ -24,38 +24,42 @@
>  #define CLOCKGENC_BASE_ADDR	0xfd601000	/* Clockgen C */
>  
>  #define CLKA_PLL0			0x00
> -  #define CLKA_PLL0_BYPASS		(1 << 20)
> -  #define CLKA_PLL0_ENABLE_STATUS	(1 << 19)
> -  #define CLKA_PLL0_SUSPEND		((5 << 16) | (100 << 8) | \
> +#define   CLKA_PLL0_BYPASS		(1 << 20)
> +#define   CLKA_PLL0_ENABLE_STATUS	(1 << 19)
> +#define   CLKA_PLL0_LOCK		(1 << 31)
> +#define   CLKA_PLL0_SUSPEND		((5 << 16) | (100 << 8) | \
>  	(SYSACLKIN / 1000000))
>  
>  #define CLKA_PLL1			0x04
> -  #define CLKA_PLL1_BYPASS		(1 << 20)
> -  #define CLKA_PLL1_ENABLE_STATUS	(1 << 19)
> -  #define CLKA_PLL1_SUSPEND		((100 << 8) | (SYSACLKIN / 1000000))
> +#define   CLKA_PLL1_BYPASS		(1 << 20)
> +#define   CLKA_PLL1_ENABLE_STATUS	(1 << 19)
> +#define   CLKA_PLL1_LOCK		(1 << 31)
> +#define   CLKA_PLL1_SUSPEND		((100 << 8) | (SYSACLKIN / 1000000))
>  
>  #define CLKA_PLL2			0x08
> -  #define CLKA_PLL2_BYPASS		(1 << 20)
> -  #define CLKA_PLL2_ENABLE_STATUS	(1 << 19)
> -  #define CLKA_PLL2_SUSPEND		((5 << 16) | (100 << 8) | \
> +#define   CLKA_PLL2_BYPASS		(1 << 20)
> +#define   CLKA_PLL2_ENABLE_STATUS	(1 << 19)
> +#define   CLKA_PLL2_LOCK		(1 << 31)
> +#define   CLKA_PLL2_SUSPEND		((5 << 16) | (100 << 8) | \
>  	(SYSACLKIN / 1000000))
>  
>  #define CKGA_CLKOUT_SEL			0x18
>  
>  #define CLKA_PWR_CFG			0x1C
> -  #define PWR_CFG_PLL0_OFF		0x1
> -  #define PWR_CFG_PLL1_OFF		0x2
> -  #define PWR_CFG_PLL2_OFF 		0x4
> +#define   PWR_CFG_PLL0_OFF		0x1
> +#define   PWR_CFG_PLL1_OFF		0x2
> +#define   PWR_CFG_PLL2_OFF 		0x4
>  
>  #define CLKA_DIV_CFG			0x10
>  
>  
>  #define CLKB_PLL0_CFG			0x3C
> -  #define CLKB_PLL0_BYPASS		(1 << 20)
> -  #define CLKB_PLL0_SUSPEND		((5 << 16) | (100 << 8) | \
> +#define   CLKB_PLL0_LOCK		(1 << 31)
> +#define   CLKB_PLL0_BYPASS		(1 << 20)
> +#define   CLKB_PLL0_SUSPEND		((5 << 16) | (100 << 8) | \
>  	(SYSACLKIN / 1000000))
>  
>  #define CLKB_PWR_CFG			0x58
> -  #define CLKB_PLL0_OFF			(1 << 15)
> +#define   CLKB_PLL0_OFF			(1 << 15)
>  
>  #endif
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> index e5134ec..79eab1f 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> @@ -32,11 +32,13 @@
>  #define _SYS_CFG11			(6)
>  #define _SYS_CFG11_MASK			(7)
>  
> +extern void __iomem *clkgena_base;
> +
>  /* *************************
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> -
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stb7100_standby_table[] __cacheline_aligned = {
>  /* 1. PLL0 at the minimum frequency */
>  	/* Unlock the clocks */
> @@ -51,6 +53,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
>  	/* enables the pll0 */
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> +	/* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
>  	/* removes the bypass */
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  	/* 0 4 5 - 1:4 1:6 1:8	*/
> @@ -79,6 +83,8 @@ _OR(),
>  CLK_STORE(CLKA_PLL0),
>  	/* enables the pll0 */
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> +	/* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
>  	/* removes the bypass */
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  	/* Lock the clocks */
> @@ -86,7 +92,7 @@ CLK_POKE(CLKA_LOCK, 0x0),
>  /* END. */
>  _END()
>  };
> -
> +#endif
>  /* *********************
>   * MEM INSTRUCTION TABLE
>   * *********************
> @@ -112,6 +118,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
>  	/* enables the pll0 */
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> +	/* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
>  	/* removes the bypass */
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  
> @@ -126,6 +134,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(0x7ffff)),
>  CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_SUSPEND),
>  	/* enables the pll1 */
>  CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE),
> +	/* Wait PLL1 lock */
> +CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
>  CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)),		/* removes the bypass */
>  
>  /* 4. Turn-off the LMI clocks and the ST231 clocks */
> @@ -150,6 +160,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_ENABLE)),	/* disable the pll1 */
>  DATA_LOAD(0x1),
>  CLK_STORE(CLKA_PLL1),
>  CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE),	/* enables the pll1 */
> +	/* Wait PLL1 lock */
> +CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
>  CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)),		/* removes the bypass */
>  
>  /* 4. Disables the DDR self refresh mode */
> @@ -167,6 +179,8 @@ IMMEDIATE_SRC0(CLKA_PLL0_BYPASS),
>  _OR(),
>  CLK_STORE(CLKA_PLL0),				/* save the r2 in PLL0 */
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),	/* enables the pll0 */
> +	/* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),	/* removes the bypass */
>  CLK_POKE(CLKA_LOCK, 0x0),
>  
> @@ -182,46 +196,8 @@ static unsigned long stb7100_wrt_table[8] __cacheline_aligned;
>  
>  static int stb7100_suspend_prepare(suspend_state_t state)
>  {
> -	int ret = -EINVAL;
> -	pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pms);
> -/*	clk_pm_state(pms);*/
> -	sysconf_pm_state(pms);
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -		stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> -		ret = 0;
> -	break;
> -	case PM_SUSPEND_MEM:
> -		stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> -		stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
> -		ret = 0;
> -	break;
> -	}
> -	return ret;
> -}
> -
> -static int stb7100_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
> -	return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stb7100_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pms = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pms);
> -/*	clk_pm_state(pms);*/
> -	emi_pm_state(pms);
> +	stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> +	stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
>  	return 0;
>  }
>  
> @@ -234,31 +210,29 @@ static unsigned long stb7100_iomem[2] __cacheline_aligned = {
>  	stb7100_wrt_table,
>  };
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stb7100_iomem,
> +	.ops.prepare = stb7100_suspend_prepare,
> +	.evt_to_irq = stb7100_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stb7100_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
> +#endif
> +	.mem_tbl = (unsigned long)stb7100_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stb7100_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
>  {
>  	struct sysconf_field* sc;
>  
>  	stb7100_iomem[1] = (unsigned long) clkgena_base;
>  
> -	st40data->iobase = stb7100_iomem;
> -	st40data->ops.valid  = stb7100_suspend_valid;
> -	st40data->ops.finish = stb7100_suspend_finish;
> -	st40data->ops.prepare = stb7100_suspend_prepare;
> -
> -	st40data->evt_to_irq = stb7100_evttoirq;
> -
> -	st40data->stby_tbl = (unsigned long)stb7100_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stb7100_standby_table)*sizeof(long), L1_CACHE_BYTES);;
> -
> -	st40data->mem_tbl = (unsigned long)stb7100_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stb7100_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stb7100_wrt_table;
> -	st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stb7100_wrt_table)*sizeof(long), L1_CACHE_BYTES);
> -
>  	sc = sysconf_claim(SYS_STA, 12, 28, 28, "pm");
>  	stb7100_wrt_table[_SYS_STA12] = (unsigned long)sysconf_address(sc);
>  	stb7100_wrt_table[_SYS_STA12_MASK] = sysconf_mask(sc);
> @@ -273,5 +247,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	sc = sysconf_claim(SYS_CFG, 11, 30, 30, "pm");
>  	stb7100_wrt_table[_SYS_CFG11_MASK] |= sysconf_mask(sc);
>  
> -	return 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> index 69aa3f3..ee793ad 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> @@ -31,10 +31,25 @@
>  #define _SYS_CFG_H                      (2)
>  #define _SYS_CFG_H_MASK                 (3)
>  
> +
> +
> +/*
> + * System Service Finite State Machine
> + *	+-------+   +------+    +------+
> + *	| reset |-->|  X1  |<-->| Prog |
> + *	+-------+   +------+    +------+
> + *	    	       /\	   |
> + *	    		|	   \/
> + *		wakeup	|       +-------+
> + *		event	+-------|Standby|
> + *			        +-------+
> + */
> +
>  /* *************************
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stx5197_standby_table[] __cacheline_aligned = {
>  CLK_POKE(CLK_LOCK_CFG, 0xf0),
>  CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
> @@ -54,6 +69,7 @@ CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
>  CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
>  CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_STDBY),
>  CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
>  CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
>  CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
>  _DELAY(),
> @@ -61,6 +77,7 @@ _DELAY(),
>  _DELAY(),
>  _END()
>  };
> +#endif
>  
>  /* *********************
>   * MEM INSTRUCTION TABLE
> @@ -73,22 +90,19 @@ DATA_WHILE_NEQ(_SYS_MON_J, _SYS_MON_J_MASK, _SYS_MON_J_MASK),
>  CLK_POKE(CLK_LOCK_CFG, 0xf0),
>  CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
>  
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
> -/* on exetrnal Xtal */
> -CLK_OR_LONG(CLK_REDUCED_PM_CTRL, CLK_REDUCED_ON_XTAL_MEMSTDBY),
> -CLK_OR_LONG(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_POFF),
> -CLK_OR_LONG(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_POFF),
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
> -CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
> +/* disable PLLs in standby */
> +CLK_OR_LONG(CLK_LP_MODE_DIS0, CLK_LP_MODE_DIS0_VALUE),
> +CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_STDB), /* IN STANDBY */
>  
> -_END(),
> -
> -CLK_POKE(CLK_LOCK_CFG, 0xf0),
> -CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
> +_END_NO_SLEEP(),
> +/*
> + * On a wakeup Event the System Service goes directly in X1 mode */
>  CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
>  CLK_AND_LONG(CLK_PLL_CONFIG1(1), ~CLK_PLL_CONFIG1_POFF),
> -CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_MEMSTDBY), /* on PLLs */
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
> +
>  CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
>  CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
>  
> @@ -109,42 +123,6 @@ static unsigned long stx5197_wrt_table[8] __cacheline_aligned;
>  
>  static int stx5197_suspend_prepare(suspend_state_t state)
>  {
> -	int ret = -EINVAL;
> -	pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pms);
> -/*	clk_pm_state(pms);*/
> -	sysconf_pm_state(pms);
> -
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		ret = 0;
> -		break;
> -	}
> -	return ret;
> -}
> -
> -static int stx5197_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
> -	return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx5197_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pms = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pms);
> -/*	clk_pm_state(pms);*/
> -	emi_pm_state(pms);
>  	return 0;
>  }
>  
> @@ -154,31 +132,30 @@ static unsigned long stx5197_iomem[2] __cacheline_aligned = {
>  
>  static int stx5197_evt_to_irq(unsigned long evt)
>  {
> -	return ilc2irq(evt);
> +	return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
>  }
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stx5197_iomem,
> +	.ops.prepare = stx5197_suspend_prepare,
> +	.evt_to_irq = stx5197_evt_to_irq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stx5197_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
> +#endif
> +	.mem_tbl = (unsigned long)stx5197_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stx5197_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup(void)
>  {
>  
>  	struct sysconf_field* sc;
> -	st40data->iobase = stx5197_iomem;
> -	st40data->ops.valid = stx5197_suspend_valid;
> -	st40data->ops.finish = stx5197_suspend_finish;
> -	st40data->ops.prepare = stx5197_suspend_prepare;
> -
> -	st40data->evt_to_irq = stx5197_evt_to_irq;
> -
> -	st40data->stby_tbl = (unsigned long)stx5197_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx5197_standby_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->mem_tbl = (unsigned long)stx5197_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx5197_mem_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stx5197_wrt_table;
> -	st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx5197_wrt_table) * sizeof(long), L1_CACHE_BYTES);
>  
>  	sc = sysconf_claim(SYS_DEV, CFG_MONITOR_J, 24, 24, "LMI pwd ack");
>  	stx5197_wrt_table[_SYS_MON_J] = (unsigned long)sysconf_address(sc);
> @@ -188,5 +165,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	stx5197_wrt_table[_SYS_CFG_H] = (unsigned long)sysconf_address(sc);
>  	stx5197_wrt_table[_SYS_CFG_H_MASK] = sysconf_mask(sc);
>  
> -	return 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> index b9b88a2..e5e0329 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> @@ -27,6 +27,10 @@
>  
>  #define _SYS_STA4		(7)
>  #define _SYS_STA4_MASK		(8)
> +#define _SYS_STA3		(11)
> +#define _SYS_STA3_MASK		(12)
> +#define _SYS_STA3_VALUE		(13)
> +
>  #define _SYS_CFG11		(9)
>  #define _SYS_CFG11_MASK		(10)
>  #define _SYS_CFG38		(5)
> @@ -35,6 +39,7 @@
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stx7105_standby_table[] __cacheline_aligned = {
>  /* 1. Move all the clock on OSC */
>  CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
> @@ -57,7 +62,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
>  /* END. */
>  _END()
>  };
> -
> +#endif
>  /* *********************
>   * MEM INSTRUCTION TABLE
>   * *********************
> @@ -91,8 +96,15 @@ _END(),
>  
>  /* Turn-on the PLLs */
>  CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLS lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
> +
>  /* 1. Turn-on the LMI ClocksGenD */
>  DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
>  /* 2. Disables the DDR self refresh mode */
>  DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
>  /* waits until the ack bit is zero */
> @@ -100,6 +112,7 @@ DATA_WHILE_EQ(_SYS_STA4, _SYS_STA4_MASK, _SYS_STA4_MASK),
>  
>  IMMEDIATE_DEST(0x10000),
>  CLK_STORE(CKGA_PLL0LS_DIV_CFG(4)),
> +
>  /* 3. Restore the previous clocks setting */
>  DATA_LOAD(0x0),
>  CLK_STORE(CKGA_CLKOPSRC_SWITCH_CFG(0x0)),
> @@ -111,6 +124,7 @@ DATA_LOAD(0x2),
>  CLK_STORE(CKGA_OSC_DIV_CFG(0x0)),
>  DATA_LOAD(0x4),
>  CLK_STORE(CKGA_OSC_DIV_CFG(17)),
> +
>  _DELAY(),
>  _DELAY(),
>  _DELAY(),
> @@ -121,23 +135,17 @@ static unsigned long stx7105_wrt_table[16] __cacheline_aligned;
>  
>  static int stx7105_suspend_prepare(suspend_state_t state)
>  {
> -	int ret = -EINVAL;
> -	pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pms);
> -	clk_pm_state(pms);
> -	sysconf_pm_state(pms);
> -
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> +	if (state = PM_SUSPEND_STANDBY) {
>  		stx7105_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7105_wrt_table[1] = /* clk_STNoc */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
>  		stx7105_wrt_table[2] = /* clk_ic_if_100 */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> -		ret = 0;
> -	break;
> -	case PM_SUSPEND_MEM:
> +	} else
> +#endif
> +	{
>  		stx7105_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7105_wrt_table[1] = /* swith config 1 */
> @@ -148,33 +156,7 @@ static int stx7105_suspend_prepare(suspend_state_t state)
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
>  		stx7105_wrt_table[4] = /* clk_ic_if_200 */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> -		ret = 0;
> -		break;
>  	}
> -	return ret;
> -}
> -
> -static int stx7105_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
> -	return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7105_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pms = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pms);
> -	clk_pm_state(pms);
> -	emi_pm_state(pms);
>  	return 0;
>  }
>  
> @@ -187,41 +169,27 @@ static int stx7105_evt_to_irq(unsigned long evt)
>  	return evt2irq(evt);
>  }
>  
> -#if 0
> -#define GPLMI_BASEADDRESS		0xfe901000
> -#define GPLMI_SCR_APPD			0x14
> -static void stx7105_sleep_on_idle(void)
> -{
> -	iowrite32(0x10 << 16 | 0x10, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
> -	asm volatile ("sleep    \n":::"memory");
> -	iowrite32(0x0, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
> -}
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stx7105_iomem,
> +	.ops.prepare = stx7105_suspend_prepare,
> +	.evt_to_irq = stx7105_evt_to_irq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stx7105_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
>  #endif
> +	.mem_tbl = (unsigned long)stx7105_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stx7105_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static int __init suspend_platform_setup(void)
>  {
>  
>  	struct sysconf_field* sc;
> -	st40data->iobase = stx7105_iomem;
> -	st40data->ops.valid = stx7105_suspend_valid;
> -	st40data->ops.finish = stx7105_suspend_finish;
> -	st40data->ops.prepare = stx7105_suspend_prepare;
> -
> -	st40data->evt_to_irq = stx7105_evt_to_irq;
> -
> -	st40data->stby_tbl = (unsigned long)stx7105_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7105_standby_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->mem_tbl = (unsigned long)stx7105_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7105_mem_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stx7105_wrt_table;
> -	st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7105_wrt_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -/*	pm_idle = stx7105_sleep_on_idle;	*/
>  	sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
>  	stx7105_wrt_table[_SYS_CFG38]      = (unsigned long)sysconf_address(sc);
>  	stx7105_wrt_table[_SYS_CFG38_MASK] = sysconf_mask(sc);
> @@ -234,5 +202,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	stx7105_wrt_table[_SYS_STA4]      = (unsigned long)sysconf_address(sc);
>  	stx7105_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>  
> -	return 0;
> +	sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> +	stx7105_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> +	stx7105_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> +	stx7105_wrt_table[_SYS_STA3_VALUE] = 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> index a0b2104..8203184 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> @@ -27,6 +27,9 @@
>  
>  #define _SYS_STA4			(5)
>  #define _SYS_STA4_MASK			(6)
> +#define _SYS_STA3			(11)
> +#define _SYS_STA3_MASK			(12)
> +#define _SYS_STA3_VALUE			(13)
>  
>  #define _SYS_CFG11			(7)
>  #define _SYS_CFG11_MASK			(8)
> @@ -38,6 +41,7 @@
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stx7111_standby_table[] __cacheline_aligned = {
>  /* 1. Move all the clock on OSC */
>  CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
> @@ -64,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
>   /* END. */
>  _END()
>  };
> +#endif
>  
>  /* *********************
>   * MEM INSTRUCTION TABLE
> @@ -96,9 +101,15 @@ _END(),
>  
>  /* Turn-on the PLLs */
>  CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
>  
>  /* 1. Turn-on the LMI ClocksGenD */
>  DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
>  /* 2. Disables the DDR self refresh mode */
>  DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
>  /* waits until the ack bit is zero */
> @@ -129,23 +140,17 @@ static unsigned long stx7111_wrt_table[16] __cacheline_aligned;
>  
>  static int stx7111_suspend_prepare(suspend_state_t state)
>  {
> -	int ret = -EINVAL;
> -	pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pms);
> -	clk_pm_state(pms);
> -	sysconf_pm_state(pms);
> -
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> +	if (state = PM_SUSPEND_STANDBY) {
>  		stx7111_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7111_wrt_table[1] = /* clk_STNoc_ic */
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
>  		stx7111_wrt_table[2] = /* clk_ic_if_100 */
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> -		ret = 0;
> -	break;
> -	case PM_SUSPEND_MEM:
> +	} else
> +#endif
> +	{
>  		stx7111_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7111_wrt_table[1] = /* swith config 1 */
> @@ -156,33 +161,7 @@ static int stx7111_suspend_prepare(suspend_state_t state)
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
>  		stx7111_wrt_table[4] = /* clk_ic_if_200 */
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> -		ret = 0;
> -		break;
>  	}
> -	return ret;
> -}
> -
> -static int stx7111_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
> -	return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7111_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pms = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pms);
> -	clk_pm_state(pms);
> -	emi_pm_state(pms);
>  	return 0;
>  }
>  
> @@ -195,31 +174,30 @@ static int stx7111_evttoirq(unsigned long evt)
>  	return evt2irq(evt);
>  }
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stx7111_iomem,
> +	.ops.prepare = stx7111_suspend_prepare,
> +	.evt_to_irq = stx7111_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stx7111_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
> +#endif
> +	.mem_tbl = (unsigned long)stx7111_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stx7111_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
>  {
>  	struct sysconf_field* sc;
>  #ifdef CONFIG_PM_DEBUG
>  /* route the sh4/2 clock frequenfy */
>  	iowrite32(0xc, CLOCKGENA_BASE_ADDR + CKGA_CLKOBS_MUX1_CFG);
>  #endif
> -	st40data->iobase = stx7111_iomem;
> -	st40data->ops.valid = stx7111_suspend_valid;
> -	st40data->ops.finish = stx7111_suspend_finish;
> -	st40data->ops.prepare = stx7111_suspend_prepare;
> -
> -	st40data->evt_to_irq = stx7111_evttoirq;
> -
> -	st40data->stby_tbl = (unsigned long)stx7111_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7111_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->mem_tbl = (unsigned long)stx7111_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7111_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stx7111_wrt_table;
> -	st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7111_wrt_table)*sizeof(long), L1_CACHE_BYTES);
>  
>  	sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
>  	stx7111_wrt_table[_SYS_CFG38]      = (unsigned long)sysconf_address(sc);
> @@ -233,5 +211,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	stx7111_wrt_table[_SYS_STA4]      = (unsigned long)sysconf_address(sc);
>  	stx7111_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>  
> -	return 0;
> +	sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> +	stx7111_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> +	stx7111_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> +	stx7111_wrt_table[_SYS_STA3_VALUE] = 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> index f2d131c..3dffc3a 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> @@ -31,6 +31,10 @@
>  
>  #define _SYS_STA4		(7)
>  #define _SYS_STA4_MASK		(8)
> +#define _SYS_STA3		(11)
> +#define _SYS_STA3_MASK		(12)
> +#define _SYS_STA3_VALUE		(13)
> +
>  #define _SYS_CFG11		(9)
>  #define _SYS_CFG11_MASK		(10)
>  #define _SYS_CFG38		(5)
> @@ -40,6 +44,7 @@
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stx7141_standby_table[] __cacheline_aligned = {
>  IMMEDIATE_DEST(0x1f),
>  /* reduces the st40 frequency */
> @@ -63,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(10)),
>   /* END. */
>  _END()
>  };
> +#endif
>  
>  /* *********************
>   * MEM INSTRUCTION TABLE
> @@ -96,8 +102,15 @@ _END(),
>  
>  /* Turn-on the PLLs */
>  CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
> +
>  /* 1. Turn-on the LMI ClocksGenD */
>  DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
>  /* 2. Disables the DDR self refresh mode */
>  DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
>  /* waits until the ack bit is zero */
> @@ -126,23 +139,17 @@ static unsigned long stx7141_wrt_table[16] __cacheline_aligned;
>  
>  static int stx7141_suspend_prepare(suspend_state_t state)
>  {
> -	int ret = -EINVAL;
> -	pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pms);
> -	clk_pm_state(pms);
> -	sysconf_pm_state(pms);
> -
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> +	if (state = PM_SUSPEND_STANDBY) {
>  		stx7141_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7141_wrt_table[1] = /* clk_ic */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
>  		stx7141_wrt_table[2] = /* clk_ic_if_100 */
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
> -		ret = 0;
> -		break;
> -	case PM_SUSPEND_MEM:
> +	} else
> +#endif
> +	{
>  		stx7141_wrt_table[0] = /* swith config */
>  		   ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
>  		stx7141_wrt_table[1] = /* swith config */
> @@ -153,33 +160,7 @@ static int stx7141_suspend_prepare(suspend_state_t state)
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
>  		stx7141_wrt_table[4] = /* clk_ic_if_200 */
>  		    ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> -		ret = 0;
> -		break;
>  	}
> -	return ret;
> -}
> -
> -static int stx7141_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
> -	return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7141_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pms = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pms);
> -	clk_pm_state(pms);
> -	emi_pm_state(pms);
>  	return 0;
>  }
>  
> @@ -189,10 +170,27 @@ static unsigned long stx7141_iomem[2] __cacheline_aligned = {
>  
>  static int stx7141_evttoirq(unsigned long evt)
>  {
> -	return ilc2irq(evt);
> +	return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
>  }
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stx7141_iomem,
> +	.ops.prepare = stx7141_suspend_prepare,
> +	.evt_to_irq = stx7141_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stx7141_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
> +#endif
> +	.mem_tbl = (unsigned long)stx7141_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stx7141_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
>  {
>  	struct sysconf_field *sc;
>  #ifdef CONFIG_PM_DEBUG
> @@ -202,24 +200,6 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	sc = sysconf_claim(SYS_CFG, 19, 22, 23, "clkA dbg");
>  	sysconf_write(sc, 11);
>  #endif
> -	st40data->iobase = stx7141_iomem;
> -	st40data->ops.valid = stx7141_suspend_valid;
> -	st40data->ops.finish = stx7141_suspend_finish;
> -	st40data->ops.prepare = stx7141_suspend_prepare;
> -
> -	st40data->evt_to_irq = stx7141_evttoirq;
> -
> -	st40data->stby_tbl = (unsigned long)stx7141_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7141_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->mem_tbl = (unsigned long)stx7141_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7141_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stx7141_wrt_table;
> -        st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7141_wrt_table) * sizeof(long), L1_CACHE_BYTES);
>  
>  	sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
>  	stx7141_wrt_table[_SYS_CFG38]      = (unsigned long)sysconf_address(sc);
> @@ -233,5 +213,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	stx7141_wrt_table[_SYS_STA4]      = (unsigned long)sysconf_address(sc);
>  	stx7141_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>  
> -	return 0;
> +	sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> +	stx7141_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> +	stx7141_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> +	stx7141_wrt_table[_SYS_STA3_VALUE] = 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> index 320b660..23201b1 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> @@ -40,6 +40,7 @@
>   * STANDBY INSTRUCTION TABLE
>   * *************************
>   */
> +#ifdef CONFIG_PM_DEBUG
>  static unsigned long stx7200_standby_table[] __cacheline_aligned = {
>  /* Down scale the GenA.Pll0 and GenA.Pll2*/
>  CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_BYPASS),
> @@ -79,6 +80,8 @@ _OR(),
>  CLK_STORE(CLKA_PLL2),
>  #endif
>  CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL2_OFF)),
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
>  
> @@ -86,6 +89,7 @@ _DELAY(),
>  /* END. */
>  _END()
>  };
> +#endif
>  
>  /* *********************
>   * MEM INSTRUCTION TABLE
> @@ -118,6 +122,10 @@ CLK_OR_LONG(CLKA_PLL2, CLKA_PLL2_SUSPEND),
>  
>  CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
>  
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
> +
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
>  CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
> @@ -149,6 +157,10 @@ _OR(),
>  CLK_STORE(CLKA_PLL2),
>  #endif
>  CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
>  
>  CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>  CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
> @@ -172,53 +184,25 @@ static unsigned long stx7200_wrt_table[16] __cacheline_aligned;
>  
>  static int stx7200_suspend_prepare(suspend_state_t state)
>  {
> -	pm_message_t pm = {.event = PM_EVENT_SUSPEND, };
> -	emi_pm_state(pm);
> -	clk_pm_state(pm);
> -	sysconf_pm_state(pm);
> -
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> +	if (state = PM_SUSPEND_STANDBY) {
>  		stx7200_wrt_table[0] >  			readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
>  		stx7200_wrt_table[1] >  			readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
> -		return 0;
> -	case PM_SUSPEND_MEM:
> +	} else
> +#endif
> +	{
>  		stx7200_wrt_table[0] >  			readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
>  		stx7200_wrt_table[1] >  			readl(CLOCKGEN_BASE_ADDR + CLKA_PLL1) & 0x7ffff;
>  		stx7200_wrt_table[2] >  			readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
> -	   return 0;
>  	}
> -	return -EINVAL;
> -}
> -
> -static int stx7200_suspend_valid(suspend_state_t state)
> -{
> -	switch (state) {
> -	case PM_SUSPEND_STANDBY:
> -	case PM_SUSPEND_MEM:
> -		return 1;
> -	};
>  	return 0;
>  }
>  
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7200_suspend_finish(suspend_state_t state)
> -{
> -	pm_message_t pm = {.event = PM_EVENT_ON, };
> -	sysconf_pm_state(pm);
> -	clk_pm_state(pm);
> -	emi_pm_state(pm);
> -	return 0;
> -}
>  
>  static unsigned long stx7200_iomem[2] __cacheline_aligned = {
>  		stx7200_wrt_table,	/* To access Sysconf    */
> @@ -226,32 +210,30 @@ static unsigned long stx7200_iomem[2] __cacheline_aligned = {
>  
>  static int stx7200_evttoirq(unsigned long evt)
>  {
> -	return ilc2irq(evt);
> +	return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
>  }
>  
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> +	.iobase = stx7200_iomem,
> +	.ops.prepare = stx7200_suspend_prepare,
> +	.evt_to_irq = stx7200_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> +	.stby_tbl = (unsigned long)stx7200_standby_table,
> +	.stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_standby_table) *
> +			sizeof(long), L1_CACHE_BYTES),
> +#endif
> +	.mem_tbl = (unsigned long)stx7200_mem_table,
> +	.mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_mem_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +	.wrt_tbl = (unsigned long)stx7200_wrt_table,
> +	.wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_wrt_table) * sizeof(long),
> +			L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
>  {
>  	struct sysconf_field* sc;
>  
> -	st40data->iobase = stx7200_iomem;
> -	st40data->ops.valid = stx7200_suspend_valid;
> -	st40data->ops.finish = stx7200_suspend_finish;
> -	st40data->ops.prepare = stx7200_suspend_prepare;
> -
> -	st40data->evt_to_irq = stx7200_evttoirq;
> -
> -	st40data->stby_tbl = (unsigned long)stx7200_standby_table;
> -	st40data->stby_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7200_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->mem_tbl = (unsigned long)stx7200_mem_table;
> -	st40data->mem_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7200_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> -	st40data->wrt_tbl = (unsigned long)stx7200_wrt_table;
> -	st40data->wrt_size = DIV_ROUND_UP(
> -		ARRAY_SIZE(stx7200_wrt_table) * sizeof(long), L1_CACHE_BYTES);
> -
>  	sc = sysconf_claim(SYS_STA, 4, 0, 0, "pm");
>  	stx7200_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
>  	stx7200_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
> @@ -272,5 +254,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
>  	ctrl_outl(0xc, CKGA_CLKOUT_SEL +
>  		CLOCKGEN_BASE_ADDR); /* sh4:2 routed on SYSCLK_OUT */
>  #endif
> -	return 0;
> +	return sh4_suspend_register(&st40data);
>  }
> +
> +late_initcall(suspend_platform_setup);
>   


      reply	other threads:[~2009-05-18 13:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-18 13:18 [PATCH] stm: pm: Rework the suspend SOC code Francesco VIRLINZI
2009-05-18 13:19 ` Francesco VIRLINZI [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A11605E.50004@st.com \
    --to=francesco.virlinzi@st.com \
    --cc=linux-sh@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox