[ARM] 3858/1: S3C2412: power management code
Add S3C2412 power management code, and move the core register saving in from s3c2412.c Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
da56c94926
commit
4b053e7a32
@ -176,6 +176,13 @@ config CPU_S3C2412_ONLY
|
||||
!CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
|
||||
default y if CPU_S3C2412
|
||||
|
||||
config S3C2412_PM
|
||||
bool
|
||||
default y if PM
|
||||
depends on CPU_S3C2412
|
||||
help
|
||||
Internal config node to apply S3C2412 power management
|
||||
|
||||
config CPU_S3C2412
|
||||
bool
|
||||
depends on ARCH_S3C2410
|
||||
|
@ -38,6 +38,8 @@ obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o
|
||||
obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
|
||||
obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o
|
||||
|
||||
obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o
|
||||
|
||||
#
|
||||
# S3C244X support
|
||||
|
||||
|
128
arch/arm/mach-s3c2410/s3c2412-pm.c
Normal file
128
arch/arm/mach-s3c2410/s3c2412-pm.c
Normal file
@ -0,0 +1,128 @@
|
||||
/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
|
||||
*
|
||||
* Copyright (c) 2006 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* http://armlinux.simtec.co.uk/.
|
||||
*
|
||||
* 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>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/arch/regs-power.h>
|
||||
#include <asm/arch/regs-gpioj.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/regs-dsc.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "pm.h"
|
||||
|
||||
#include "s3c2412.h"
|
||||
|
||||
static void s3c2412_cpu_suspend(void)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
/* set our standby method to sleep */
|
||||
|
||||
tmp = __raw_readl(S3C2412_PWRCFG);
|
||||
tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
|
||||
__raw_writel(tmp, S3C2412_PWRCFG);
|
||||
|
||||
/* issue the standby signal into the pm unit. Note, we
|
||||
* issue a write-buffer drain just in case */
|
||||
|
||||
tmp = 0;
|
||||
|
||||
asm("b 1f\n\t"
|
||||
".align 5\n\t"
|
||||
"1:\n\t"
|
||||
"mcr p15, 0, %0, c7, c10, 4\n\t"
|
||||
"mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
|
||||
|
||||
/* we should never get past here */
|
||||
|
||||
panic("sleep resumed to originator?");
|
||||
}
|
||||
|
||||
static void s3c2412_pm_prepare(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int s3c2412_pm_add(struct sys_device *sysdev)
|
||||
{
|
||||
pm_cpu_prep = s3c2412_pm_prepare;
|
||||
pm_cpu_sleep = s3c2412_cpu_suspend;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sleep_save s3c2412_sleep[] = {
|
||||
SAVE_ITEM(S3C2412_DSC0),
|
||||
SAVE_ITEM(S3C2412_DSC1),
|
||||
SAVE_ITEM(S3C2413_GPJDAT),
|
||||
SAVE_ITEM(S3C2413_GPJCON),
|
||||
SAVE_ITEM(S3C2413_GPJUP),
|
||||
|
||||
/* save the PWRCFG to get back to original sleep method */
|
||||
|
||||
SAVE_ITEM(S3C2412_PWRCFG),
|
||||
|
||||
/* save the sleep configuration anyway, just in case these
|
||||
* get damaged during wakeup */
|
||||
|
||||
SAVE_ITEM(S3C2412_GPBSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPCSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPDSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPESLPCON),
|
||||
SAVE_ITEM(S3C2412_GPFSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPGSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPHSLPCON),
|
||||
SAVE_ITEM(S3C2413_GPJSLPCON),
|
||||
};
|
||||
|
||||
static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
|
||||
{
|
||||
s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2412_pm_resume(struct sys_device *dev)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = __raw_readl(S3C2412_PWRCFG);
|
||||
tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
|
||||
tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
|
||||
__raw_writel(tmp, S3C2412_PWRCFG);
|
||||
|
||||
s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sysdev_driver s3c2412_pm_driver = {
|
||||
.add = s3c2412_pm_add,
|
||||
.suspend = s3c2412_pm_suspend,
|
||||
.resume = s3c2412_pm_resume,
|
||||
};
|
||||
|
||||
static __init int s3c2412_pm_init(void)
|
||||
{
|
||||
return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
|
||||
}
|
||||
|
||||
arch_initcall(s3c2412_pm_init);
|
@ -158,48 +158,8 @@ void __init s3c2412_init_clocks(int xtal)
|
||||
* as a driver which may support both 2410 and 2440 may try and use it.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static struct sleep_save s3c2412_sleep[] = {
|
||||
SAVE_ITEM(S3C2412_DSC0),
|
||||
SAVE_ITEM(S3C2412_DSC1),
|
||||
SAVE_ITEM(S3C2413_GPJDAT),
|
||||
SAVE_ITEM(S3C2413_GPJCON),
|
||||
SAVE_ITEM(S3C2413_GPJUP),
|
||||
|
||||
/* save the sleep configuration anyway, just in case these
|
||||
* get damaged during wakeup */
|
||||
|
||||
SAVE_ITEM(S3C2412_GPBSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPCSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPDSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPESLPCON),
|
||||
SAVE_ITEM(S3C2412_GPFSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPGSLPCON),
|
||||
SAVE_ITEM(S3C2412_GPHSLPCON),
|
||||
SAVE_ITEM(S3C2413_GPJSLPCON),
|
||||
};
|
||||
|
||||
static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
|
||||
{
|
||||
s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2412_resume(struct sys_device *dev)
|
||||
{
|
||||
s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define s3c2412_suspend NULL
|
||||
#define s3c2412_resume NULL
|
||||
#endif
|
||||
|
||||
struct sysdev_class s3c2412_sysclass = {
|
||||
set_kset_name("s3c2412-core"),
|
||||
.suspend = s3c2412_suspend,
|
||||
.resume = s3c2412_resume
|
||||
};
|
||||
|
||||
static int __init s3c2412_core_init(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user