[PATCH] ARM/sp810: introduce API to change system mode

Russell King - ARM Linux linux at arm.linux.org.uk
Thu Feb 23 05:03:44 EST 2012


On Thu, Feb 23, 2012 at 02:43:44PM +0530, Viresh Kumar wrote:
> From: Shiraz Hashim <shiraz.hashim at st.com>
> 
> sp810 controller can change system's working mode to various power save
> states. Introduce an API to accomplish the same.

Where is the documentation for this peripheral?  I've never seen any
documentation on ARMs website for it.

> 
> Signed-off-by: Shiraz Hashim <shiraz.hashim at st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar at st.com>
> ---
>  arch/arm/include/asm/hardware/sp810.h |   57 +++++++++++++++++++++++++++++++++
>  1 files changed, 57 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
> index e0d1c0c..df0960a 100644
> --- a/arch/arm/include/asm/hardware/sp810.h
> +++ b/arch/arm/include/asm/hardware/sp810.h
> @@ -14,10 +14,25 @@
>  #ifndef __ASM_ARM_SP810_H
>  #define __ASM_ARM_SP810_H
>  
> +#include <linux/err.h>
>  #include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/jiffies.h>
>  
>  /* sysctl registers offset */
>  #define SCCTRL			0x000
> +	#define SYS_MODE_STS_MASK		(0xF << 3)
> +	#define SYS_MODE_STS_SLEEP		(0x0 << 3)
> +	#define SYS_MODE_STS_DOZE		(0x1 << 3)
> +	#define SYS_MODE_STS_SLOW		(0x2 << 3)
> +	#define SYS_MODE_STS_NORMAL		(0x4 << 3)
> +
> +	#define SYS_MODE_MASK			(0x7 << 0)
> +	#define SYS_MODE_SLEEP			(0x0 << 0)
> +	#define SYS_MODE_DOZE			(0x1 << 0)
> +	#define SYS_MODE_SLOW			(0x2 << 0)
> +	#define SYS_MODE_NORMAL			(0x4 << 0)
> +
>  #define SCSYSSTAT		0x004
>  #define SCIMCTRL		0x008
>  #define SCIMSTAT		0x00C
> @@ -65,4 +80,46 @@ static inline void sysctl_soft_reset(void __iomem *base)
>  	writel(0, base + SCSYSSTAT);
>  }
>  
> +static inline int sysctl_change_mode(void __iomem *base, int mode)
> +{
> +	u32 val, mode_sts;
> +	unsigned long finish;
> +
> +	switch (mode) {
> +	case SYS_MODE_SLEEP:
> +		mode_sts = SYS_MODE_STS_SLEEP;
> +		break;
> +	case SYS_MODE_DOZE:
> +		mode_sts = SYS_MODE_STS_DOZE;
> +		break;
> +	case SYS_MODE_SLOW:
> +		mode_sts = SYS_MODE_STS_SLOW;
> +		break;
> +	case SYS_MODE_NORMAL:
> +		mode_sts = SYS_MODE_STS_NORMAL;
> +		break;
> +	default:
> +		pr_err("Wrong system mode\n");
> +		return -EINVAL;
> +	}
> +
> +	val = readl(base + SCCTRL);
> +	if ((val & SYS_MODE_STS_MASK) == mode_sts)
> +		return 0;
> +
> +	val &= ~SYS_MODE_MASK;
> +	val |= mode;
> +	writel(val, base + SCCTRL);
> +
> +	/* read back if mode is set */
> +	finish = jiffies + 2 * HZ;
> +	do {
> +		val = readl(base + SCCTRL);
> +		if ((val & SYS_MODE_STS_MASK) == mode_sts)
> +			return 0;
> +		udelay(1000);
> +	} while (!time_after_eq(jiffies, finish));
> +
> +	return -EFAULT;
> +}
>  #endif	/* __ASM_ARM_SP810_H */
> -- 
> 1.7.8.110.g4cb5d
> 



More information about the linux-arm-kernel mailing list