aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSungjun Bae <june.bae@samsung.com>2010-08-02 17:26:36 +0900
committerArve Hjønnevåg <arve@android.com>2011-11-16 21:48:19 -0800
commit1d4656a3eae8d54151a86005a442dd9597616477 (patch)
tree1d2cf88b720fe83b90103d3bb310ba9aebddac59 /arch
parent55eb8a0e26dc8d59aeb5fa1cae62d0703fbfba63 (diff)
downloadkernel_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')
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h5
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h30
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-gpio.h90
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-irq.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-mem.h28
-rw-r--r--arch/arm/mach-s5pv210/mach-herring.c3
-rw-r--r--arch/arm/plat-s5p/Makefile4
-rw-r--r--arch/arm/plat-s5p/include/plat/pm.h217
-rw-r--r--arch/arm/plat-s5p/irq-pm.c18
-rw-r--r--arch/arm/plat-s5p/pm.c256
-rw-r--r--arch/arm/plat-s5p/sleep.S319
11 files changed, 904 insertions, 72 deletions
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 4f7894e..c14f594 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -78,6 +78,11 @@
#define S5PV210_PA_DMC0 0xF0000000
#define S5PV210_PA_DMC1 0xF1400000
+#define S5P_VA_VIC0 (S3C_VA_IRQ + 0x0)
+#define S5P_VA_VIC1 (S3C_VA_IRQ + 0x10000)
+#define S5P_VA_VIC2 (S3C_VA_IRQ + 0x20000)
+#define S5P_VA_VIC3 (S3C_VA_IRQ + 0x30000)
+
#define S5PV210_PA_LCD (0xF8000000)
#define S5P_PA_LCD S5PV210_PA_LCD
#define S5PV210_SZ_LCD SZ_1M
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
index e8d394f..a93c1a2 100644
--- a/arch/arm/mach-s5pv210/include/mach/pm-core.h
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -1,14 +1,11 @@
/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
+ * http://www.samsung.com/
*
- * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c
+ * Based on arch/arm/plat-s3c24xx/include/plat/pm-core.h,
+ * Copyright 2008-2009 Simtec Electronics Ben Dooks <ben@simtec.co.uk>
+ * S5P series driver for power management
*
* 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
@@ -17,27 +14,38 @@
static inline void s3c_pm_debug_init_uart(void)
{
- /* nothing here yet */
}
static inline void s3c_pm_arch_prepare_irqs(void)
{
__raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
__raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+
+ /* ack any outstanding external interrupts before we go to sleep */
+
}
static inline void s3c_pm_arch_stop_clocks(void)
{
- /* nothing here yet */
}
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask);
+
static inline void s3c_pm_arch_show_resume_irqs(void)
{
- /* nothing here yet */
}
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+/* 2009.04.27 by icarus : don't use this definition, use extern var */
+#if 0
+#define s3c_irqwake_eintallow (0xFFFFFFFF)
+#define s3c_irqwake_intallow (0)
+#endif
+
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
- /* nothing here yet */
}
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
index 5c786a9..1669549 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
@@ -75,155 +75,155 @@
#define S5PV210_ETC4_BASE (S5P_VA_GPIO + 0x660)
#define S5PV210_GPA0_INT_CON (S5P_VA_GPIO + 0x700)
-#define S5PV210_GPA0_INTFLTCON0 (S5P_VA_GPIO + 0x800)
-#define S5PV210_GPA0_INTFLTCON1 (S5P_VA_GPIO + 0x804)
+#define S5PV210_GPA0_INT_FLTCON0 (S5P_VA_GPIO + 0x800)
+#define S5PV210_GPA0_INT_FLTCON1 (S5P_VA_GPIO + 0x804)
#define S5PV210_GPA0_INT_MASK (S5P_VA_GPIO + 0x900)
#define S5PV210_GPA0_INT_PEND (S5P_VA_GPIO + 0xA00)
#define S5PV210_GPA0_INT_FIXPRI (S5P_VA_GPIO + 0xB14)
#define S5PV210_GPA1_INT_CON (S5P_VA_GPIO + 0x704)
-#define S5PV210_GPA1_INTFLTCON0 (S5P_VA_GPIO + 0x808)
-#define S5PV210_GPA1_INTFLTCON1 (S5P_VA_GPIO + 0x80C)
+#define S5PV210_GPA1_INT_FLTCON0 (S5P_VA_GPIO + 0x808)
+#define S5PV210_GPA1_INT_FLTCON1 (S5P_VA_GPIO + 0x80C)
#define S5PV210_GPA1_INT_MASK (S5P_VA_GPIO + 0x904)
#define S5PV210_GPA1_INT_PEND (S5P_VA_GPIO + 0xA04)
#define S5PV210_GPA1_INT_FIXPRI (S5P_VA_GPIO + 0xB18)
#define S5PV210_GPB_INT_CON (S5P_VA_GPIO + 0x708)
-#define S5PV210_GPB_INTFLTCON0 (S5P_VA_GPIO + 0x810)
-#define S5PV210_GPB_INTFLTCON1 (S5P_VA_GPIO + 0x814)
+#define S5PV210_GPB_INT_FLTCON0 (S5P_VA_GPIO + 0x810)
+#define S5PV210_GPB_INT_FLTCON1 (S5P_VA_GPIO + 0x814)
#define S5PV210_GPB_INT_MASK (S5P_VA_GPIO + 0x908)
#define S5PV210_GPB_INT_PEND (S5P_VA_GPIO + 0xA08)
#define S5PV210_GPB_INT_FIXPRI (S5P_VA_GPIO + 0xB1C)
#define S5PV210_GPC0_INT_CON (S5P_VA_GPIO + 0x70C)
-#define S5PV210_GPC0_INTFLTCON0 (S5P_VA_GPIO + 0x818)
-#define S5PV210_GPC0_INTFLTCON1 (S5P_VA_GPIO + 0x81C)
+#define S5PV210_GPC0_INT_FLTCON0 (S5P_VA_GPIO + 0x818)
+#define S5PV210_GPC0_INT_FLTCON1 (S5P_VA_GPIO + 0x81C)
#define S5PV210_GPC0_INT_MASK (S5P_VA_GPIO + 0x90C)
#define S5PV210_GPC0_INT_PEND (S5P_VA_GPIO + 0xA0C)
#define S5PV210_GPC0_INT_FIXPRI (S5P_VA_GPIO + 0xB20)
#define S5PV210_GPC1_INT_CON (S5P_VA_GPIO + 0x710)
-#define S5PV210_GPC1_INTFLTCON0 (S5P_VA_GPIO + 0x820)
-#define S5PV210_GPC1_INTFLTCON1 (S5P_VA_GPIO + 0x824)
+#define S5PV210_GPC1_INT_FLTCON0 (S5P_VA_GPIO + 0x820)
+#define S5PV210_GPC1_INT_FLTCON1 (S5P_VA_GPIO + 0x824)
#define S5PV210_GPC1_INT_MASK (S5P_VA_GPIO + 0x910)
#define S5PV210_GPC1_INT_PEND (S5P_VA_GPIO + 0xA10)
#define S5PV210_GPC1_INT_FIXPRI (S5P_VA_GPIO + 0xB24)
#define S5PV210_GPD0_INT_CON (S5P_VA_GPIO + 0x714)
-#define S5PV210_GPD0_INTFLTCON0 (S5P_VA_GPIO + 0x828)
-#define S5PV210_GPD0_INTFLTCON1 (S5P_VA_GPIO + 0x82C)
+#define S5PV210_GPD0_INT_FLTCON0 (S5P_VA_GPIO + 0x828)
+#define S5PV210_GPD0_INT_FLTCON1 (S5P_VA_GPIO + 0x82C)
#define S5PV210_GPD0_INT_MASK (S5P_VA_GPIO + 0x914)
#define S5PV210_GPD0_INT_PEND (S5P_VA_GPIO + 0xA14)
#define S5PV210_GPD0_INT_FIXPRI (S5P_VA_GPIO + 0xB28)
#define S5PV210_GPD1_INT_CON (S5P_VA_GPIO + 0x718)
-#define S5PV210_GPD1_INTFLTCON0 (S5P_VA_GPIO + 0x830)
-#define S5PV210_GPD1_INTFLTCON1 (S5P_VA_GPIO + 0x834)
+#define S5PV210_GPD1_INT_FLTCON0 (S5P_VA_GPIO + 0x830)
+#define S5PV210_GPD1_INT_FLTCON1 (S5P_VA_GPIO + 0x834)
#define S5PV210_GPD1_INT_MASK (S5P_VA_GPIO + 0x918)
#define S5PV210_GPD1_INT_PEND (S5P_VA_GPIO + 0xA18)
#define S5PV210_GPD1_INT_FIXPRI (S5P_VA_GPIO + 0xB2C)
#define S5PV210_GPE0_INT_CON (S5P_VA_GPIO + 0x71C)
-#define S5PV210_GPE0_INTFLTCON0 (S5P_VA_GPIO + 0x838)
-#define S5PV210_GPE0_INTFLTCON1 (S5P_VA_GPIO + 0x83C)
+#define S5PV210_GPE0_INT_FLTCON0 (S5P_VA_GPIO + 0x838)
+#define S5PV210_GPE0_INT_FLTCON1 (S5P_VA_GPIO + 0x83C)
#define S5PV210_GPE0_INT_MASK (S5P_VA_GPIO + 0x91C)
#define S5PV210_GPE0_INT_PEND (S5P_VA_GPIO + 0xA1C)
#define S5PV210_GPE0_INT_FIXPRI (S5P_VA_GPIO + 0xB30)
#define S5PV210_GPE1_INT_CON (S5P_VA_GPIO + 0x720)
-#define S5PV210_GPE1_INTFLTCON0 (S5P_VA_GPIO + 0x840)
-#define S5PV210_GPE1_INTFLTCON1 (S5P_VA_GPIO + 0x844)
+#define S5PV210_GPE1_INT_FLTCON0 (S5P_VA_GPIO + 0x840)
+#define S5PV210_GPE1_INT_FLTCON1 (S5P_VA_GPIO + 0x844)
#define S5PV210_GPE1_INT_MASK (S5P_VA_GPIO + 0x920)
#define S5PV210_GPE1_INT_PEND (S5P_VA_GPIO + 0xA20)
#define S5PV210_GPE1_INT_FIXPRI (S5P_VA_GPIO + 0xB34)
#define S5PV210_GPF0_INT_CON (S5P_VA_GPIO + 0x724)
-#define S5PV210_GPF0_INTFLTCON0 (S5P_VA_GPIO + 0x848)
-#define S5PV210_GPF0_INTFLTCON1 (S5P_VA_GPIO + 0x84C)
+#define S5PV210_GPF0_INT_FLTCON0 (S5P_VA_GPIO + 0x848)
+#define S5PV210_GPF0_INT_FLTCON1 (S5P_VA_GPIO + 0x84C)
#define S5PV210_GPF0_INT_MASK (S5P_VA_GPIO + 0x924)
#define S5PV210_GPF0_INT_PEND (S5P_VA_GPIO + 0xA24)
#define S5PV210_GPF0_INT_FIXPRI (S5P_VA_GPIO + 0xB38)
#define S5PV210_GPF1_INT_CON (S5P_VA_GPIO + 0x728)
-#define S5PV210_GPF1_INTFLTCON0 (S5P_VA_GPIO + 0x850)
-#define S5PV210_GPF1_INTFLTCON1 (S5P_VA_GPIO + 0x854)
+#define S5PV210_GPF1_INT_FLTCON0 (S5P_VA_GPIO + 0x850)
+#define S5PV210_GPF1_INT_FLTCON1 (S5P_VA_GPIO + 0x854)
#define S5PV210_GPF1_INT_MASK (S5P_VA_GPIO + 0x928)
#define S5PV210_GPF1_INT_PEND (S5P_VA_GPIO + 0xA28)
#define S5PV210_GPF1_INT_FIXPRI (S5P_VA_GPIO + 0xB3C)
#define S5PV210_GPF2_INT_CON (S5P_VA_GPIO + 0x72C)
-#define S5PV210_GPF2_INTFLTCON0 (S5P_VA_GPIO + 0x858)
-#define S5PV210_GPF2_INTFLTCON1 (S5P_VA_GPIO + 0x85C)
+#define S5PV210_GPF2_INT_FLTCON0 (S5P_VA_GPIO + 0x858)
+#define S5PV210_GPF2_INT_FLTCON1 (S5P_VA_GPIO + 0x85C)
#define S5PV210_GPF2_INT_MASK (S5P_VA_GPIO + 0x92C)
#define S5PV210_GPF2_INT_PEND (S5P_VA_GPIO + 0xA2C)
#define S5PV210_GPF2_INT_FIXPRI (S5P_VA_GPIO + 0xB40)
#define S5PV210_GPF3_INT_CON (S5P_VA_GPIO + 0x730)
-#define S5PV210_GPF3_INTFLTCON0 (S5P_VA_GPIO + 0x860)
-#define S5PV210_GPF3_INTFLTCON1 (S5P_VA_GPIO + 0x864)
+#define S5PV210_GPF3_INT_FLTCON0 (S5P_VA_GPIO + 0x860)
+#define S5PV210_GPF3_INT_FLTCON1 (S5P_VA_GPIO + 0x864)
#define S5PV210_GPF3_INT_MASK (S5P_VA_GPIO + 0x930)
#define S5PV210_GPF3_INT_PEND (S5P_VA_GPIO + 0xA30)
#define S5PV210_GPF3_INT_FIXPRI (S5P_VA_GPIO + 0xB44)
#define S5PV210_GPG0_INT_CON (S5P_VA_GPIO + 0x734)
-#define S5PV210_GPG0_INTFLTCON0 (S5P_VA_GPIO + 0x868)
-#define S5PV210_GPG0_INTFLTCON1 (S5P_VA_GPIO + 0x86C)
+#define S5PV210_GPG0_INT_FLTCON0 (S5P_VA_GPIO + 0x868)
+#define S5PV210_GPG0_INT_FLTCON1 (S5P_VA_GPIO + 0x86C)
#define S5PV210_GPG0_INT_MASK (S5P_VA_GPIO + 0x934)
#define S5PV210_GPG0_INT_PEND (S5P_VA_GPIO + 0xA34)
#define S5PV210_GPG0_INT_FIXPRI (S5P_VA_GPIO + 0xB48)
#define S5PV210_GPG1_INT_CON (S5P_VA_GPIO + 0x738)
-#define S5PV210_GPG1_INTFLTCON0 (S5P_VA_GPIO + 0x870)
-#define S5PV210_GPG1_INTFLTCON1 (S5P_VA_GPIO + 0x874)
+#define S5PV210_GPG1_INT_FLTCON0 (S5P_VA_GPIO + 0x870)
+#define S5PV210_GPG1_INT_FLTCON1 (S5P_VA_GPIO + 0x874)
#define S5PV210_GPG1_INT_MASK (S5P_VA_GPIO + 0x938)
#define S5PV210_GPG1_INT_PEND (S5P_VA_GPIO + 0xA38)
#define S5PV210_GPG1_INT_FIXPRI (S5P_VA_GPIO + 0xB4C)
#define S5PV210_GPG2_INT_CON (S5P_VA_GPIO + 0x73C)
-#define S5PV210_GPG2_INTFLTCON0 (S5P_VA_GPIO + 0x878)
-#define S5PV210_GPG2_INTFLTCON1 (S5P_VA_GPIO + 0x87C)
+#define S5PV210_GPG2_INT_FLTCON0 (S5P_VA_GPIO + 0x878)
+#define S5PV210_GPG2_INT_FLTCON1 (S5P_VA_GPIO + 0x87C)
#define S5PV210_GPG2_INT_MASK (S5P_VA_GPIO + 0x93C)
#define S5PV210_GPG2_INT_PEND (S5P_VA_GPIO + 0xA3C)
#define S5PV210_GPG2_INT_FIXPRI (S5P_VA_GPIO + 0xB50)
#define S5PV210_GPG3_INT_CON (S5P_VA_GPIO + 0x740)
-#define S5PV210_GPG3_INTFLTCON0 (S5P_VA_GPIO + 0x880)
-#define S5PV210_GPG3_INTFLTCON1 (S5P_VA_GPIO + 0x884)
+#define S5PV210_GPG3_INT_FLTCON0 (S5P_VA_GPIO + 0x880)
+#define S5PV210_GPG3_INT_FLTCON1 (S5P_VA_GPIO + 0x884)
#define S5PV210_GPG3_INT_MASK (S5P_VA_GPIO + 0x940)
#define S5PV210_GPG3_INT_PEND (S5P_VA_GPIO + 0xA40)
#define S5PV210_GPG3_INT_FIXPRI (S5P_VA_GPIO + 0xB54)
#define S5PV210_GPJ0_INT_CON (S5P_VA_GPIO + 0x744)
-#define S5PV210_GPJ0_INTFLTCON0 (S5P_VA_GPIO + 0x888)
-#define S5PV210_GPJ0_INTFLTCON1 (S5P_VA_GPIO + 0x88C)
+#define S5PV210_GPJ0_INT_FLTCON0 (S5P_VA_GPIO + 0x888)
+#define S5PV210_GPJ0_INT_FLTCON1 (S5P_VA_GPIO + 0x88C)
#define S5PV210_GPJ0_INT_MASK (S5P_VA_GPIO + 0x944)
#define S5PV210_GPJ0_INT_PEND (S5P_VA_GPIO + 0xA44)
#define S5PV210_GPJ0_INT_FIXPRI (S5P_VA_GPIO + 0xB58)
#define S5PV210_GPJ1_INT_CON (S5P_VA_GPIO + 0x748)
-#define S5PV210_GPJ1_INTFLTCON0 (S5P_VA_GPIO + 0x890)
-#define S5PV210_GPJ1_INTFLTCON1 (S5P_VA_GPIO + 0x894)
+#define S5PV210_GPJ1_INT_FLTCON0 (S5P_VA_GPIO + 0x890)
+#define S5PV210_GPJ1_INT_FLTCON1 (S5P_VA_GPIO + 0x894)
#define S5PV210_GPJ1_INT_MASK (S5P_VA_GPIO + 0x948)
#define S5PV210_GPJ1_INT_PEND (S5P_VA_GPIO + 0xA48)
#define S5PV210_GPJ1_INT_FIXPRI (S5P_VA_GPIO + 0xB5C)
#define S5PV210_GPJ2_INT_CON (S5P_VA_GPIO + 0x74C)
-#define S5PV210_GPJ2_INTFLTCON0 (S5P_VA_GPIO + 0x898)
-#define S5PV210_GPJ2_INTFLTCON1 (S5P_VA_GPIO + 0x89C)
+#define S5PV210_GPJ2_INT_FLTCON0 (S5P_VA_GPIO + 0x898)
+#define S5PV210_GPJ2_INT_FLTCON1 (S5P_VA_GPIO + 0x89C)
#define S5PV210_GPJ2_INT_MASK (S5P_VA_GPIO + 0x94C)
#define S5PV210_GPJ2_INT_PEND (S5P_VA_GPIO + 0xA4C)
#define S5PV210_GPJ2_INT_FIXPRI (S5P_VA_GPIO + 0xB60)
#define S5PV210_GPJ3_INT_CON (S5P_VA_GPIO + 0x750)
-#define S5PV210_GPJ3_INTFLTCON0 (S5P_VA_GPIO + 0x8A0)
-#define S5PV210_GPJ3_INTFLTCON1 (S5P_VA_GPIO + 0x8A4)
+#define S5PV210_GPJ3_INT_FLTCON0 (S5P_VA_GPIO + 0x8A0)
+#define S5PV210_GPJ3_INT_FLTCON1 (S5P_VA_GPIO + 0x8A4)
#define S5PV210_GPJ3_INT_MASK (S5P_VA_GPIO + 0x950)
#define S5PV210_GPJ3_INT_PEND (S5P_VA_GPIO + 0xA50)
#define S5PV210_GPJ3_INT_FIXPRI (S5P_VA_GPIO + 0xB64)
#define S5PV210_GPJ4_INT_CON (S5P_VA_GPIO + 0x754)
-#define S5PV210_GPJ4_INTFLTCON0 (S5P_VA_GPIO + 0x8A8)
-#define S5PV210_GPJ4_INTFLTCON1 (S5P_VA_GPIO + 0x8AC)
+#define S5PV210_GPJ4_INT_FLTCON0 (S5P_VA_GPIO + 0x8A8)
+#define S5PV210_GPJ4_INT_FLTCON1 (S5P_VA_GPIO + 0x8AC)
#define S5PV210_GPJ4_INT_MASK (S5P_VA_GPIO + 0x954)
#define S5PV210_GPJ4_INT_PEND (S5P_VA_GPIO + 0xA54)
#define S5PV210_GPJ4_INT_FIXPRI (S5P_VA_GPIO + 0xB68)
@@ -238,7 +238,7 @@
#define S5P_EINT_CON(x) (S5PV210_EINT30CON + ((x) * 0x4))
#define S5PV210_EINT30FLTCON0 (S5P_VA_GPIO + 0xE80)
-#define S5P_EINT_FLTCON(x) (S5PV210_EINT30FLTCON0 + ((x) * 0x4))
+#define S5P_EINT_FLTCON(x,y) (S5PV210_EINT30FLTCON0 + ((x) * 0x8) + ((y) * 0x4))
#define S5PV210_EINT30MASK (S5P_VA_GPIO + 0xF00)
#define S5P_EINT_MASK(x) (S5PV210_EINT30MASK + ((x) * 0x4))
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-irq.h b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
index 5c3b104..e3b86f1 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-irq.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
@@ -16,4 +16,10 @@
#include <asm/hardware/vic.h>
#include <mach/map.h>
+/* interrupt controller */
+#define S5P_VIC0REG(x) ((x) + S5P_VA_VIC0)
+#define S5P_VIC1REG(x) ((x) + S5P_VA_VIC1)
+#define S5P_VIC2REG(x) ((x) + S5P_VA_VIC2)
+#define S5P_VIC3REG(x) ((x) + S5P_VA_VIC3)
+
#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-mem.h b/arch/arm/mach-s5pv210/include/mach/regs-mem.h
new file mode 100644
index 0000000..1c79d54
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-mem.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory Control register definitions
+ *
+ * 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.
+*/
+
+#ifndef __ASM_ARCH_REGS_MEM_H
+#define __ASM_ARCH_REGS_MEM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_MEMREG(x) (S5P_VA_SROMC + (x))
+
+#define S5P_SROM_BW S5P_MEMREG(0x00)
+#define S5P_SROM_BC0 S5P_MEMREG(0x04)
+#define S5P_SROM_BC1 S5P_MEMREG(0x08)
+#define S5P_SROM_BC2 S5P_MEMREG(0x0C)
+#define S5P_SROM_BC3 S5P_MEMREG(0x10)
+#define S5P_SROM_BC4 S5P_MEMREG(0x14)
+#define S5P_SROM_BC5 S5P_MEMREG(0x18)
+
+#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-s5pv210/mach-herring.c b/arch/arm/mach-s5pv210/mach-herring.c
index 70af092..849ec08 100644
--- a/arch/arm/mach-s5pv210/mach-herring.c
+++ b/arch/arm/mach-s5pv210/mach-herring.c
@@ -3045,10 +3045,13 @@ static void __init herring_machine_init(void)
s3c_adc_set_platdata(&s3c_adc_platform);
#endif
+#if 0 /* will be initialized at pm.c */
#if defined(CONFIG_PM)
s3c_pm_init();
// s5pc11x_pm_init();
#endif
+#endif
+
#ifdef CONFIG_VIDEO_FIMC
/* fimc */
s3c_fimc0_set_platdata(&fimc_plat);
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 33b6a34..b0adbfc 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -40,6 +40,10 @@ obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_PM) += sleep.o
+
ifdef CONFIG_S5P_HIGH_RES_TIMERS
ifdef CONFIG_HRT_RTC
obj-y += hr-time-rtc.o
diff --git a/arch/arm/plat-s5p/include/plat/pm.h b/arch/arm/plat-s5p/include/plat/pm.h
new file mode 100644
index 0000000..9c62446
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/pm.h
@@ -0,0 +1,217 @@
+/* linux/arch/arm/plat-s5p/include/plat/pm.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/plat-s3c/include/plat/pm.h,
+ * Copyright 2008-2009 Simtec Electronics Ben Dooks <ben@simtec.co.uk>
+ * S5P series device definition for power management
+ *
+ * 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.
+*/
+
+#ifdef CONFIG_S5P_LPAUDIO
+#include <linux/wakelock.h>
+#include <mach/cpuidle.h>
+#endif /* CONFIG_S5P_LPAUDIO */
+
+#ifdef CONFIG_PM
+
+extern __init int s3c_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+extern void printascii(const char *);
+#endif
+
+extern void s3c_pm_dbg(const char *fmt, ...);
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
+
+/* from sleep.S */
+
+extern int s3c_cpu_save(unsigned long *saveblk);
+extern void s3c_cpu_resume(void);
+
+extern void s3c2410_cpu_suspend(void);
+
+extern unsigned long s3c_sleep_save_phys;
+
+#define SLEEP_MODE 0
+#define IDLE2_MODE 1
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+#define SAVE_ITEM(x) \
+ { .reg = (x) }
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+ u32 ulcon;
+ u32 ucon;
+ u32 ufcon;
+ u32 umcon;
+ u32 ubrdiv;
+ u32 udivslot;
+};
+
+/* helper functions to save/restore lists of registers. */
+
+extern int s5p_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s5p_irq_resume(struct sys_device *dev);
+
+/* PM debug functions */
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+extern void s3c_pm_dbg(const char *msg, ...);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+#else
+#define S3C_PMDBG(fmt...) printk(KERN_INFO fmt)
+#endif
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+/**
+ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
+ * @set: set bits for the state of the LEDs
+ * @clear: clear bits for the state of the LEDs.
+ */
+extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
+
+#else
+static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
+#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
+
+/* suspend memory checking */
+
+#ifdef CONFIG_S3C2410_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+extern void s3c_pm_check_restore(void);
+extern void s3c_pm_check_cleanup(void);
+extern void s3c_pm_check_store(void);
+#else
+#define s3c_pm_check_prepare() do { } while (0)
+#define s3c_pm_check_restore() do { } while (0)
+#define s3c_pm_check_cleanup() do { } while (0)
+#define s3c_pm_check_store() do { } while (0)
+#endif
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c_irqext_wake(unsigned int irqno, unsigned int state);
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c_irqext_wake NULL
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume NULL
+#endif
+
+/**
+ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
+ *
+ * Setup all the necessary GPIO pins for waking the system on external
+ * interrupt.
+ */
+extern void s3c_pm_configure_extint(void);
+
+/**
+ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ *
+ * Restore the state of the GPIO pins after sleep, which may involve ensuring
+ * that we do not glitch the state of the pins from that the bootloader's
+ * resume code has done.
+*/
+extern void s3c_pm_restore_gpios(void);
+
+/**
+ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ */
+extern void s3c_pm_save_gpios(void);
+
+/**
+ * s3c_pm_cb_flushcache - callback for assembly code
+ *
+ * Callback to issue flush_cache_all() as this call is
+ * not a directly callable object.
+ */
+extern void s3c_pm_cb_flushcache(void);
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
+
+#if defined(CONFIG_MACH_S5PC110_P1)
+enum ENUM_PM_WAKEUP_STAT
+{
+ PM_WAKEUP_NONE,
+ PM_POWER_KEY,
+ PM_VOLUME_UP,
+ PM_VOLUME_DOWN
+};
+
+extern int s3c_pm_get_wakeup_stat(void);
+extern void s3c_pm_clear_wakeup_stat(void);
+#endif // CONFIG_MACH_S5PC110_P1
+
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
index 327acb3..5397d93 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -61,19 +61,19 @@ static struct sleep_save eint_save[] = {
SAVE_ITEM(S5P_EINT_CON(2)),
SAVE_ITEM(S5P_EINT_CON(3)),
- SAVE_ITEM(S5P_EINT_FLTCON(0)),
- SAVE_ITEM(S5P_EINT_FLTCON(1)),
- SAVE_ITEM(S5P_EINT_FLTCON(2)),
- SAVE_ITEM(S5P_EINT_FLTCON(3)),
- SAVE_ITEM(S5P_EINT_FLTCON(4)),
- SAVE_ITEM(S5P_EINT_FLTCON(5)),
- SAVE_ITEM(S5P_EINT_FLTCON(6)),
- SAVE_ITEM(S5P_EINT_FLTCON(7)),
-
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)),
};
int s3c24xx_irq_suspend(void)
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));
}
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S
new file mode 100644
index 0000000..db1b819
--- /dev/null
+++ b/arch/arm/plat-s5p/sleep.S
@@ -0,0 +1,319 @@
+/* linux/arch/arm/plat-s5p/sleep.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/asm-offsets.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-serial.h>
+
+#define NO_L2_CLEAN
+
+/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+*/
+ .text
+
+ /* s3c_cpu_save
+ *
+ * entry:
+ * r0 = save address (virtual addr of s3c_sleep_save_phys)
+ */
+
+ENTRY(s3c_cpu_save)
+
+ stmfd sp!, { r3 - r12, lr }
+
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+ mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
+ mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
+
+ ldr r2, =S5P_INFORM1
+ ldr r1, [r2]
+ cmp r1, #0x0
+ bne idle2_save
+
+ stmia r0, { r3 - r13 }
+
+ @@ write our state back to RAM
+ bl s3c_pm_cb_flushcache
+
+ @@ jump to final code to send system to sleep
+ ldr r0, =pm_cpu_sleep
+ @@ldr pc, [ r0 ]
+ ldr r0, [ r0 ]
+ mov pc, r0
+
+idle2_save:
+ /* Save CP15 registers */
+ stmia r0!, { r3 - r12}
+
+ /* Save SVC status register */
+ mrs r2, spsr
+ str r2, [r0], #4
+
+ /* Save FIQ mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+ msr cpsr_c, r1
+ mrs r2, spsr
+ stmia r0!, {r2, r8 - r12, sp, lr }
+
+ /* Save ABT mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | ABT_MODE
+ msr cpsr_c, r1
+ mrs r2, spsr
+ stmia r0!, {r2, sp, lr }
+
+ /* Save IRQ mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | IRQ_MODE
+ msr cpsr_c, r1
+ mrs r2, spsr
+ stmia r0!, {r2, sp, lr }
+
+ /* Save UND mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | UND_MODE
+ msr cpsr_c, r1
+ mrs r2, spsr
+ stmia r0!, {r2, sp, lr }
+#if 0
+ /* Save SYS mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | SYSTEM_MODE
+ msr cpsr_c, r1
+ stmia r0!, {sp, lr }
+#endif
+ /* Return to SVC mode */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r1
+
+ /* Save SVC mode stack pointer register (R13) */
+ str r13, [r0]
+
+ mov r0, #0
+ ldmfd sp, { r3 - r12, pc }
+
+ @@ return to the caller, after having the MMU
+ @@ turned on, this restores the last bits from the
+ @@ stack
+resume_with_mmu:
+#if defined(NO_L2_CLEAN)
+ ldr r0, =S5P_INFORM1
+ ldr r1, [r0]
+ cmp r1, #0x0
+ beq skip_l2_enable
+
+ mrc p15, 0, r0, c1, c0, 1 @enable L2 cache
+ orr r0, r0, #(1<<1)
+ mcr p15, 0, r0, c1, c0, 1
+#endif
+skip_l2_enable:
+ mov r0, #1
+
+ /* delete added mmu table list */
+ ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
+ add r4, r4, r9
+ str r12, [r4]
+
+ ldmfd sp!, { r3 - r12, pc }
+
+ .ltorg
+
+ @@ the next bits sit in the .data segment, even though they
+ @@ happen to be code... the s5pv210_sleep_save_phys needs to be
+ @@ accessed by the resume code before it can restore the MMU.
+ @@ This means that the variable has to be close enough for the
+ @@ code to read it... since the .text segment needs to be RO,
+ @@ the data segment can be the only place to put this code.
+
+ .data
+
+ .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
+ .word 0
+
+
+ /* sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s5pv210_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ *
+ * we must put this code here in the data segment as we have no
+ * other way of restoring the stack pointer after sleep, and we
+ * must not write to the code segment (code is read-only)
+ */
+
+ENTRY(s3c_cpu_resume)
+ mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r0
+
+ @@ load UART to allow us to print the two characters for
+ @@ resume debug
+
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @@ invalidate TLBs
+ mcr p15, 0, r1, c7, c5, 0 @@ invalidate I Cache
+
+ ldr r1, =0xe010f008 @ Read INFORM2 register
+ ldr r0, [r1] @ Load phy_regs_save value
+ ldr r1, =0xe010f004 @ Read INFORM1 register
+ ldr r1, [r1]
+ cmp r1, #0x0
+ bne idle2_restore_1
+
+ ldmia r0, { r3 - r13 }
+ b common_restore_1
+
+idle2_restore_1:
+ /* Restore CP15 registers */
+ ldmia r0!, { r3 - r12 }
+
+common_restore_1:
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+
+ mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+
+#if defined(NO_L2_CLEAN)
+ cmp r1, #0x0 @ if idle2 wakeup
+ bicne r10, r10, #(1<<1) @ disable L2cache
+ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+#endif
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ Invalidate I & D TLB
+
+ mov r1, #0 @ restore copro access controls
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+ mcr p15, 0, r1, c7, c5, 4
+
+ mcr p15, 0, r12, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r3, c10, c2, 1 @ write NMRR
+
+ ldr r1, =0xe010f004 @ Read INFORM1 register
+ ldr r1, [r1]
+ cmp r1, #0x0
+ beq common_restore_2
+
+ /* Restore SVC status register */
+ ldr r2, [r0], #4
+ msr spsr, r2
+
+ /* Restore FIQ mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+ msr cpsr_c, r1
+ ldr r2, [r0], #4
+ msr spsr, r2
+ ldmia r0!, { r8 - r12, sp, lr }
+
+ /* Restore ABT mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | ABT_MODE
+ msr cpsr_c, r1
+ ldr r2, [r0], #4
+ msr spsr, r2
+ ldmia r0!, { sp, lr }
+
+ /* Restore IRQ mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | IRQ_MODE
+ msr cpsr_c, r1
+ ldr r2, [r0], #4
+ msr spsr, r2
+ ldmia r0!, { sp, lr }
+
+ /* Restore UND mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | UND_MODE
+ msr cpsr_c, r1
+ ldr r2, [r0], #4
+ msr spsr, r2
+ ldmia r0!, { sp, lr }
+#if 0
+ /* Restore SYS mode register */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | SYSTEM_MODE
+ msr cpsr_c, r1
+ ldmia r0!, {sp, lr }
+#endif
+ /* Return to SVC mode */
+ mov r1, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r1
+
+ /* Restore SVC mode stack pointer register (R13) */
+ ldr r13, [r0]
+
+common_restore_2:
+ /* calculate first section address into r8 */
+ mov r4, r6
+ ldr r5, =0x3fff
+ bic r4, r4, r5
+ ldr r11, =0xe010f000
+ ldr r10, [r11, #0]
+ mov r10, r10 ,LSR #18
+ bic r10, r10, #0x3
+ orr r4, r4, r10
+
+ /* calculate mmu list value into r9 */
+ mov r10, r10, LSL #18
+ ldr r5, =0x40e
+ orr r10, r10, r5
+
+ /* back up originally data */
+ ldr r12, [r4]
+
+ /* Added list about mmu */
+ str r10, [r4]
+
+ ldr r2, =resume_with_mmu
+ mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
+
+ nop
+ nop
+ nop
+ nop
+ nop @ second-to-last before mmu
+
+ mov pc, r2 @ go back to virtual address
+
+ .ltorg