diff options
-rw-r--r-- | arch/arm/mach-s5pv210/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/common.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/pm.c | 101 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/s5pv210.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/sleep.S | 36 |
6 files changed, 141 insertions, 15 deletions
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index d6d0f9268935..ffc777dfa8a0 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig | |||
@@ -14,8 +14,6 @@ config CPU_S5PV210 | |||
14 | select ARM_AMBA | 14 | select ARM_AMBA |
15 | select PL330_DMA if DMADEVICES | 15 | select PL330_DMA if DMADEVICES |
16 | select S5P_EXT_INT | 16 | select S5P_EXT_INT |
17 | select S5P_PM if PM | ||
18 | select S5P_SLEEP if PM | ||
19 | help | 17 | help |
20 | Enable S5PV210 CPU support | 18 | Enable S5PV210 CPU support |
21 | 19 | ||
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 83993fc87d87..5308225dfdee 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile | |||
@@ -12,7 +12,7 @@ obj- := | |||
12 | 12 | ||
13 | # Core | 13 | # Core |
14 | 14 | ||
15 | obj-$(CONFIG_PM) += pm.o | 15 | obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o |
16 | 16 | ||
17 | # machine support | 17 | # machine support |
18 | 18 | ||
diff --git a/arch/arm/mach-s5pv210/common.h b/arch/arm/mach-s5pv210/common.h index 0b694c798ad1..2ad387c1ecf0 100644 --- a/arch/arm/mach-s5pv210/common.h +++ b/arch/arm/mach-s5pv210/common.h | |||
@@ -12,5 +12,12 @@ | |||
12 | #ifndef __ARCH_ARM_MACH_S5PV210_COMMON_H | 12 | #ifndef __ARCH_ARM_MACH_S5PV210_COMMON_H |
13 | #define __ARCH_ARM_MACH_S5PV210_COMMON_H | 13 | #define __ARCH_ARM_MACH_S5PV210_COMMON_H |
14 | 14 | ||
15 | #ifdef CONFIG_PM_SLEEP | ||
16 | u32 exynos_get_eint_wake_mask(void); | ||
17 | void s5pv210_cpu_resume(void); | ||
18 | void s5pv210_pm_init(void); | ||
19 | #else | ||
20 | static inline void s5pv210_pm_init(void) {} | ||
21 | #endif | ||
15 | 22 | ||
16 | #endif /* __ARCH_ARM_MACH_S5PV210_COMMON_H */ | 23 | #endif /* __ARCH_ARM_MACH_S5PV210_COMMON_H */ |
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 00d1523284da..123163dd2ab0 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/pm.c | 1 | /* linux/arch/arm/mach-s5pv210/pm.c |
2 | * | 2 | * |
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | 3 | * Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com | 4 | * http://www.samsung.com |
5 | * | 5 | * |
6 | * S5PV210 - Power Management support | 6 | * S5PV210 - Power Management support |
@@ -19,17 +19,28 @@ | |||
19 | #include <linux/syscore_ops.h> | 19 | #include <linux/syscore_ops.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | 21 | ||
22 | #include <plat/cpu.h> | 22 | #include <asm/cacheflush.h> |
23 | #include <plat/pm.h> | 23 | #include <asm/suspend.h> |
24 | |||
25 | #include <plat/pm-common.h> | ||
24 | 26 | ||
25 | #include <mach/regs-irq.h> | ||
26 | #include <mach/regs-clock.h> | 27 | #include <mach/regs-clock.h> |
27 | 28 | ||
29 | #include "common.h" | ||
30 | |||
28 | static struct sleep_save s5pv210_core_save[] = { | 31 | static struct sleep_save s5pv210_core_save[] = { |
29 | /* Clock ETC */ | 32 | /* Clock ETC */ |
30 | SAVE_ITEM(S5P_MDNIE_SEL), | 33 | SAVE_ITEM(S5P_MDNIE_SEL), |
31 | }; | 34 | }; |
32 | 35 | ||
36 | /* | ||
37 | * VIC wake-up support (TODO) | ||
38 | */ | ||
39 | static u32 s5pv210_irqwake_intmask = 0xffffffff; | ||
40 | |||
41 | /* | ||
42 | * Suspend helpers. | ||
43 | */ | ||
33 | static int s5pv210_cpu_suspend(unsigned long arg) | 44 | static int s5pv210_cpu_suspend(unsigned long arg) |
34 | { | 45 | { |
35 | unsigned long tmp; | 46 | unsigned long tmp; |
@@ -54,8 +65,12 @@ static void s5pv210_pm_prepare(void) | |||
54 | { | 65 | { |
55 | unsigned int tmp; | 66 | unsigned int tmp; |
56 | 67 | ||
68 | /* Set wake-up mask registers */ | ||
69 | __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK); | ||
70 | __raw_writel(s5pv210_irqwake_intmask, S5P_WAKEUP_MASK); | ||
71 | |||
57 | /* ensure at least INFORM0 has the resume address */ | 72 | /* ensure at least INFORM0 has the resume address */ |
58 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); | 73 | __raw_writel(virt_to_phys(s5pv210_cpu_resume), S5P_INFORM0); |
59 | 74 | ||
60 | tmp = __raw_readl(S5P_SLEEP_CFG); | 75 | tmp = __raw_readl(S5P_SLEEP_CFG); |
61 | tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); | 76 | tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); |
@@ -75,6 +90,70 @@ static void s5pv210_pm_prepare(void) | |||
75 | s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); | 90 | s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); |
76 | } | 91 | } |
77 | 92 | ||
93 | /* | ||
94 | * Suspend operations. | ||
95 | */ | ||
96 | static int s5pv210_suspend_enter(suspend_state_t state) | ||
97 | { | ||
98 | int ret; | ||
99 | |||
100 | s3c_pm_debug_init(); | ||
101 | |||
102 | S3C_PMDBG("%s: suspending the system...\n", __func__); | ||
103 | |||
104 | S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__, | ||
105 | s5pv210_irqwake_intmask, exynos_get_eint_wake_mask()); | ||
106 | |||
107 | if (s5pv210_irqwake_intmask == -1U | ||
108 | && exynos_get_eint_wake_mask() == -1U) { | ||
109 | pr_err("%s: No wake-up sources!\n", __func__); | ||
110 | pr_err("%s: Aborting sleep\n", __func__); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | s3c_pm_save_uarts(); | ||
115 | s5pv210_pm_prepare(); | ||
116 | flush_cache_all(); | ||
117 | s3c_pm_check_store(); | ||
118 | |||
119 | ret = cpu_suspend(0, s5pv210_cpu_suspend); | ||
120 | if (ret) | ||
121 | return ret; | ||
122 | |||
123 | s3c_pm_restore_uarts(); | ||
124 | |||
125 | S3C_PMDBG("%s: wakeup stat: %08x\n", __func__, | ||
126 | __raw_readl(S5P_WAKEUP_STAT)); | ||
127 | |||
128 | s3c_pm_check_restore(); | ||
129 | |||
130 | S3C_PMDBG("%s: resuming the system...\n", __func__); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int s5pv210_suspend_prepare(void) | ||
136 | { | ||
137 | s3c_pm_check_prepare(); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static void s5pv210_suspend_finish(void) | ||
143 | { | ||
144 | s3c_pm_check_cleanup(); | ||
145 | } | ||
146 | |||
147 | static const struct platform_suspend_ops s5pv210_suspend_ops = { | ||
148 | .enter = s5pv210_suspend_enter, | ||
149 | .prepare = s5pv210_suspend_prepare, | ||
150 | .finish = s5pv210_suspend_finish, | ||
151 | .valid = suspend_valid_only_mem, | ||
152 | }; | ||
153 | |||
154 | /* | ||
155 | * Syscore operations used to delay restore of certain registers. | ||
156 | */ | ||
78 | static void s5pv210_pm_resume(void) | 157 | static void s5pv210_pm_resume(void) |
79 | { | 158 | { |
80 | u32 tmp; | 159 | u32 tmp; |
@@ -91,13 +170,11 @@ static struct syscore_ops s5pv210_pm_syscore_ops = { | |||
91 | .resume = s5pv210_pm_resume, | 170 | .resume = s5pv210_pm_resume, |
92 | }; | 171 | }; |
93 | 172 | ||
94 | static __init int s5pv210_pm_syscore_init(void) | 173 | /* |
174 | * Initialization entry point. | ||
175 | */ | ||
176 | void __init s5pv210_pm_init(void) | ||
95 | { | 177 | { |
96 | register_syscore_ops(&s5pv210_pm_syscore_ops); | 178 | register_syscore_ops(&s5pv210_pm_syscore_ops); |
97 | 179 | suspend_set_ops(&s5pv210_suspend_ops); | |
98 | pm_cpu_prep = s5pv210_pm_prepare; | ||
99 | pm_cpu_sleep = s5pv210_cpu_suspend; | ||
100 | |||
101 | return 0; | ||
102 | } | 180 | } |
103 | arch_initcall(s5pv210_pm_syscore_init); | ||
diff --git a/arch/arm/mach-s5pv210/s5pv210.c b/arch/arm/mach-s5pv210/s5pv210.c index c244ccb6b236..35db1ce9e11c 100644 --- a/arch/arm/mach-s5pv210/s5pv210.c +++ b/arch/arm/mach-s5pv210/s5pv210.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <plat/map-base.h> | 20 | #include <plat/map-base.h> |
21 | #include <mach/regs-clock.h> | 21 | #include <mach/regs-clock.h> |
22 | 22 | ||
23 | #include "common.h" | ||
24 | |||
23 | static int __init s5pv210_fdt_map_sys(unsigned long node, const char *uname, | 25 | static int __init s5pv210_fdt_map_sys(unsigned long node, const char *uname, |
24 | int depth, void *data) | 26 | int depth, void *data) |
25 | { | 27 | { |
@@ -55,6 +57,11 @@ static void s5pv210_dt_restart(enum reboot_mode mode, const char *cmd) | |||
55 | __raw_writel(0x1, S5P_SWRESET); | 57 | __raw_writel(0x1, S5P_SWRESET); |
56 | } | 58 | } |
57 | 59 | ||
60 | static void __init s5pv210_dt_init_late(void) | ||
61 | { | ||
62 | s5pv210_pm_init(); | ||
63 | } | ||
64 | |||
58 | static char const *s5pv210_dt_compat[] __initconst = { | 65 | static char const *s5pv210_dt_compat[] __initconst = { |
59 | "samsung,s5pc110", | 66 | "samsung,s5pc110", |
60 | "samsung,s5pv210", | 67 | "samsung,s5pv210", |
@@ -65,4 +72,5 @@ DT_MACHINE_START(S5PV210_DT, "Samsung S5PC110/S5PV210-based board") | |||
65 | .dt_compat = s5pv210_dt_compat, | 72 | .dt_compat = s5pv210_dt_compat, |
66 | .map_io = s5pv210_dt_map_io, | 73 | .map_io = s5pv210_dt_map_io, |
67 | .restart = s5pv210_dt_restart, | 74 | .restart = s5pv210_dt_restart, |
75 | .init_late = s5pv210_dt_init_late, | ||
68 | MACHINE_END | 76 | MACHINE_END |
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S new file mode 100644 index 000000000000..7c43ddd33ba8 --- /dev/null +++ b/arch/arm/mach-s5pv210/sleep.S | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * S5PV210 Sleep Code | ||
6 | * Based on S3C64XX sleep code by: | ||
7 | * Ben Dooks, (c) 2008 Simtec Electronics | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/linkage.h> | ||
16 | |||
17 | .data | ||
18 | .align | ||
19 | |||
20 | /* | ||
21 | * sleep magic, to allow the bootloader to check for an valid | ||
22 | * image to resume to. Must be the first word before the | ||
23 | * s3c_cpu_resume entry. | ||
24 | */ | ||
25 | |||
26 | .word 0x2bedf00d | ||
27 | |||
28 | /* | ||
29 | * s3c_cpu_resume | ||
30 | * | ||
31 | * resume code entry for bootloader to call | ||
32 | */ | ||
33 | |||
34 | ENTRY(s5pv210_cpu_resume) | ||
35 | b cpu_resume | ||
36 | ENDPROC(s5pv210_cpu_resume) | ||