diff options
author | Sungjun Bae <june.bae@samsung.com> | 2010-08-02 17:26:36 +0900 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-11-16 21:48:19 -0800 |
commit | 1d4656a3eae8d54151a86005a442dd9597616477 (patch) | |
tree | 1d2cf88b720fe83b90103d3bb310ba9aebddac59 /arch/arm/plat-s5p/pm.c | |
parent | 55eb8a0e26dc8d59aeb5fa1cae62d0703fbfba63 (diff) | |
download | kernel_samsung_crespo-1d4656a3eae8d54151a86005a442dd9597616477.zip kernel_samsung_crespo-1d4656a3eae8d54151a86005a442dd9597616477.tar.gz kernel_samsung_crespo-1d4656a3eae8d54151a86005a442dd9597616477.tar.bz2 |
S5PC110: HERRING: PM: S5P Power manager
S5P Power Manager (Suspend-To-RAM) support
Diffstat (limited to 'arch/arm/plat-s5p/pm.c')
-rw-r--r-- | arch/arm/plat-s5p/pm.c | 256 |
1 files changed, 249 insertions, 7 deletions
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c index d15dc47..242c16b 100644 --- a/arch/arm/plat-s5p/pm.c +++ b/arch/arm/plat-s5p/pm.c @@ -1,24 +1,252 @@ /* linux/arch/arm/plat-s5p/pm.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com + * http://www.samsung.com/ * * S5P Power Manager (Suspend-To-RAM) support * - * Based on arch/arm/plat-s3c24xx/pm.c - * Copyright (c) 2004,2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> + * Based on arch/arm/mach-pxa/pm.c * * 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/init.h> #include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/crc32.h> +#include <linux/ioport.h> +#include <linux/delay.h> +#include <linux/serial_core.h> +#include <linux/io.h> +#include <linux/platform_device.h> + +#include <asm/cacheflush.h> +#include <mach/hardware.h> + +#include <plat/map-base.h> +#include <plat/regs-serial.h> +#include <plat/regs-timer.h> +#include <mach/regs-clock.h> +#include <plat/gpio-cfg.h> +#include <mach/regs-mem.h> +#include <mach/regs-irq.h> +#include <mach/regs-gpio.h> +#include <linux/gpio.h> +#include <asm/mach/time.h> + #include <plat/pm.h> +#include <mach/irqs.h> #define PFX "s5p pm: " +static struct sleep_save core_save[] = { +/* PLL Control */ + SAVE_ITEM(S5P_APLL_CON), + SAVE_ITEM(S5P_MPLL_CON), + SAVE_ITEM(S5P_EPLL_CON), + SAVE_ITEM(S5P_VPLL_CON), +/* Clock source */ + SAVE_ITEM(S5P_CLK_SRC0), + SAVE_ITEM(S5P_CLK_SRC1), + SAVE_ITEM(S5P_CLK_SRC2), + SAVE_ITEM(S5P_CLK_SRC3), + SAVE_ITEM(S5P_CLK_SRC4), + SAVE_ITEM(S5P_CLK_SRC5), + SAVE_ITEM(S5P_CLK_SRC6), +/* Clock source Mask */ + SAVE_ITEM(S5P_CLK_SRC_MASK0), + SAVE_ITEM(S5P_CLK_SRC_MASK1), +/* Clock Divider */ + SAVE_ITEM(S5P_CLK_DIV0), + SAVE_ITEM(S5P_CLK_DIV1), + SAVE_ITEM(S5P_CLK_DIV2), + SAVE_ITEM(S5P_CLK_DIV3), + SAVE_ITEM(S5P_CLK_DIV4), + SAVE_ITEM(S5P_CLK_DIV5), + SAVE_ITEM(S5P_CLK_DIV6), + SAVE_ITEM(S5P_CLK_DIV7), +/* Clock Main Main Gate */ + SAVE_ITEM(S5P_CLKGATE_MAIN0), + SAVE_ITEM(S5P_CLKGATE_MAIN1), + SAVE_ITEM(S5P_CLKGATE_MAIN2), +/* Clock source Peri Gate */ + SAVE_ITEM(S5P_CLKGATE_PERI0), + SAVE_ITEM(S5P_CLKGATE_PERI1), +/* Clock source SCLK Gate */ + SAVE_ITEM(S5P_CLKGATE_SCLK0), + SAVE_ITEM(S5P_CLKGATE_SCLK1), +/* Clock IP Clock gate */ + SAVE_ITEM(S5P_CLKGATE_IP0), + SAVE_ITEM(S5P_CLKGATE_IP1), + SAVE_ITEM(S5P_CLKGATE_IP2), + SAVE_ITEM(S5P_CLKGATE_IP3), + SAVE_ITEM(S5P_CLKGATE_IP4), +/* Clock Blcok and Bus gate */ + SAVE_ITEM(S5P_CLKGATE_BLOCK), + SAVE_ITEM(S5P_CLKGATE_BUS0), +/* Clock ETC */ + SAVE_ITEM(S5P_CLK_OUT), + SAVE_ITEM(S5P_MDNIE_SEL), +/* PWM Register */ + SAVE_ITEM(S3C2410_TCFG0), + SAVE_ITEM(S3C2410_TCFG1), + SAVE_ITEM(S3C64XX_TINT_CSTAT), + SAVE_ITEM(S3C2410_TCON), + SAVE_ITEM(S3C2410_TCNTB(0)), + SAVE_ITEM(S3C2410_TCMPB(0)), + SAVE_ITEM(S3C2410_TCNTO(0)), +}; + +static struct sleep_save sromc_save[] = { + SAVE_ITEM(S5P_SROM_BW), + SAVE_ITEM(S5P_SROM_BC0), + SAVE_ITEM(S5P_SROM_BC1), + SAVE_ITEM(S5P_SROM_BC2), + SAVE_ITEM(S5P_SROM_BC3), + SAVE_ITEM(S5P_SROM_BC4), + SAVE_ITEM(S5P_SROM_BC5), +}; + +static struct sleep_save gpio_save_ext[] = { + + SAVE_ITEM(S5P_EINT_CON(0)), + SAVE_ITEM(S5P_EINT_CON(1)), + SAVE_ITEM(S5P_EINT_CON(2)), + SAVE_ITEM(S5P_EINT_CON(3)), + + SAVE_ITEM(S5P_EINT_MASK(0)), + SAVE_ITEM(S5P_EINT_MASK(1)), + SAVE_ITEM(S5P_EINT_MASK(2)), + SAVE_ITEM(S5P_EINT_MASK(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0,0)), + SAVE_ITEM(S5P_EINT_FLTCON(0,1)), + SAVE_ITEM(S5P_EINT_FLTCON(1,0)), + SAVE_ITEM(S5P_EINT_FLTCON(1,1)), + SAVE_ITEM(S5P_EINT_FLTCON(2,0)), + SAVE_ITEM(S5P_EINT_FLTCON(2,1)), + SAVE_ITEM(S5P_EINT_FLTCON(3,0)), + SAVE_ITEM(S5P_EINT_FLTCON(3,1)), +}; + +/*gpio group interrupt*/ +static struct sleep_save gpio_save_gpio_int[] = { + + SAVE_ITEM(S5PV210_GPA0_INT_CON), + SAVE_ITEM(S5PV210_GPA1_INT_CON), + SAVE_ITEM(S5PV210_GPB_INT_CON), + SAVE_ITEM(S5PV210_GPC0_INT_CON), + SAVE_ITEM(S5PV210_GPC1_INT_CON), + SAVE_ITEM(S5PV210_GPD0_INT_CON), + SAVE_ITEM(S5PV210_GPD1_INT_CON), + SAVE_ITEM(S5PV210_GPE0_INT_CON), + SAVE_ITEM(S5PV210_GPE1_INT_CON), + SAVE_ITEM(S5PV210_GPF0_INT_CON), + SAVE_ITEM(S5PV210_GPF1_INT_CON), + SAVE_ITEM(S5PV210_GPF2_INT_CON), + SAVE_ITEM(S5PV210_GPF3_INT_CON), + SAVE_ITEM(S5PV210_GPG0_INT_CON), + SAVE_ITEM(S5PV210_GPG1_INT_CON), + SAVE_ITEM(S5PV210_GPG2_INT_CON), + SAVE_ITEM(S5PV210_GPG3_INT_CON), + SAVE_ITEM(S5PV210_GPJ0_INT_CON), + SAVE_ITEM(S5PV210_GPJ1_INT_CON), + SAVE_ITEM(S5PV210_GPJ2_INT_CON), + SAVE_ITEM(S5PV210_GPJ3_INT_CON), + SAVE_ITEM(S5PV210_GPJ4_INT_CON), + + SAVE_ITEM(S5PV210_GPA0_INT_MASK), + SAVE_ITEM(S5PV210_GPA1_INT_MASK), + SAVE_ITEM(S5PV210_GPB_INT_MASK), + SAVE_ITEM(S5PV210_GPC0_INT_MASK), + SAVE_ITEM(S5PV210_GPC1_INT_MASK), + SAVE_ITEM(S5PV210_GPD0_INT_MASK), + SAVE_ITEM(S5PV210_GPD1_INT_MASK), + SAVE_ITEM(S5PV210_GPE0_INT_MASK), + SAVE_ITEM(S5PV210_GPE1_INT_MASK), + SAVE_ITEM(S5PV210_GPF0_INT_MASK), + SAVE_ITEM(S5PV210_GPF1_INT_MASK), + SAVE_ITEM(S5PV210_GPF2_INT_MASK), + SAVE_ITEM(S5PV210_GPF3_INT_MASK), + SAVE_ITEM(S5PV210_GPG0_INT_MASK), + SAVE_ITEM(S5PV210_GPG1_INT_MASK), + SAVE_ITEM(S5PV210_GPG2_INT_MASK), + SAVE_ITEM(S5PV210_GPG3_INT_MASK), + SAVE_ITEM(S5PV210_GPJ0_INT_MASK), + SAVE_ITEM(S5PV210_GPJ1_INT_MASK), + SAVE_ITEM(S5PV210_GPJ2_INT_MASK), + SAVE_ITEM(S5PV210_GPJ3_INT_MASK), + SAVE_ITEM(S5PV210_GPJ4_INT_MASK), + + SAVE_ITEM(S5PV210_GPA0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPA0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPA1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPA1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPB_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPB_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPC0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPC0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPC1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPC1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPD0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPD0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPD1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPD1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPE0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPE0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPE1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPE1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ4_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ4_INT_FLTCON1), + +}; + +/* this lot should be really saved by the IRQ code */ +/* VICXADDRESSXX initilaization to be needed */ +static struct sleep_save irq_save[] = { + SAVE_ITEM(S5P_VIC0REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC0REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC0REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_SOFT)), +}; + /* s3c_pm_configure_extint * * configure all external interrupt pins @@ -26,16 +254,30 @@ void s3c_pm_configure_extint(void) { - /* nothing here yet */ + + /* for each of the external interrupts (EINT0..EINT15) we + * need to check wether it is an external interrupt source, + * and then configure it as an input if it is not + */ + __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); } + void s3c_pm_restore_core(void) { - /* nothing here yet */ + s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); + s3c_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); + s3c_pm_do_restore(gpio_save_ext, ARRAY_SIZE(gpio_save_ext)); + s3c_pm_do_restore(gpio_save_gpio_int, ARRAY_SIZE(gpio_save_gpio_int)); + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); } void s3c_pm_save_core(void) { - /* nothing here yet */ + s3c_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); + s3c_pm_do_save(core_save, ARRAY_SIZE(core_save)); + s3c_pm_do_save(gpio_save_ext, ARRAY_SIZE(gpio_save_ext)); + s3c_pm_do_save(gpio_save_gpio_int, ARRAY_SIZE(gpio_save_gpio_int)); + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); } |