kvm tools, setup: Create private directory
[linux-2.6/next.git] / arch / arm / mach-exynos4 / pm.c
blob8755ca8dd48d2157df921a7fb5150deceb804ef1
1 /* linux/arch/arm/mach-exynos4/pm.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * EXYNOS4210 - Power Management support
8 * Based on arch/arm/mach-s3c2410/pm.c
9 * Copyright (c) 2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
17 #include <linux/init.h>
18 #include <linux/suspend.h>
19 #include <linux/syscore_ops.h>
20 #include <linux/io.h>
22 #include <asm/cacheflush.h>
23 #include <asm/hardware/cache-l2x0.h>
25 #include <plat/cpu.h>
26 #include <plat/pm.h>
28 #include <mach/regs-irq.h>
29 #include <mach/regs-gpio.h>
30 #include <mach/regs-clock.h>
31 #include <mach/regs-pmu.h>
32 #include <mach/pm-core.h>
34 static struct sleep_save exynos4_sleep[] = {
35 { .reg = S5P_ARM_CORE0_LOWPWR , .val = 0x2, },
36 { .reg = S5P_DIS_IRQ_CORE0 , .val = 0x0, },
37 { .reg = S5P_DIS_IRQ_CENTRAL0 , .val = 0x0, },
38 { .reg = S5P_ARM_CORE1_LOWPWR , .val = 0x2, },
39 { .reg = S5P_DIS_IRQ_CORE1 , .val = 0x0, },
40 { .reg = S5P_DIS_IRQ_CENTRAL1 , .val = 0x0, },
41 { .reg = S5P_ARM_COMMON_LOWPWR , .val = 0x2, },
42 { .reg = S5P_L2_0_LOWPWR , .val = 0x3, },
43 { .reg = S5P_L2_1_LOWPWR , .val = 0x3, },
44 { .reg = S5P_CMU_ACLKSTOP_LOWPWR , .val = 0x0, },
45 { .reg = S5P_CMU_SCLKSTOP_LOWPWR , .val = 0x0, },
46 { .reg = S5P_CMU_RESET_LOWPWR , .val = 0x0, },
47 { .reg = S5P_APLL_SYSCLK_LOWPWR , .val = 0x0, },
48 { .reg = S5P_MPLL_SYSCLK_LOWPWR , .val = 0x0, },
49 { .reg = S5P_VPLL_SYSCLK_LOWPWR , .val = 0x0, },
50 { .reg = S5P_EPLL_SYSCLK_LOWPWR , .val = 0x0, },
51 { .reg = S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR , .val = 0x0, },
52 { .reg = S5P_CMU_RESET_GPSALIVE_LOWPWR , .val = 0x0, },
53 { .reg = S5P_CMU_CLKSTOP_CAM_LOWPWR , .val = 0x0, },
54 { .reg = S5P_CMU_CLKSTOP_TV_LOWPWR , .val = 0x0, },
55 { .reg = S5P_CMU_CLKSTOP_MFC_LOWPWR , .val = 0x0, },
56 { .reg = S5P_CMU_CLKSTOP_G3D_LOWPWR , .val = 0x0, },
57 { .reg = S5P_CMU_CLKSTOP_LCD0_LOWPWR , .val = 0x0, },
58 { .reg = S5P_CMU_CLKSTOP_LCD1_LOWPWR , .val = 0x0, },
59 { .reg = S5P_CMU_CLKSTOP_MAUDIO_LOWPWR , .val = 0x0, },
60 { .reg = S5P_CMU_CLKSTOP_GPS_LOWPWR , .val = 0x0, },
61 { .reg = S5P_CMU_RESET_CAM_LOWPWR , .val = 0x0, },
62 { .reg = S5P_CMU_RESET_TV_LOWPWR , .val = 0x0, },
63 { .reg = S5P_CMU_RESET_MFC_LOWPWR , .val = 0x0, },
64 { .reg = S5P_CMU_RESET_G3D_LOWPWR , .val = 0x0, },
65 { .reg = S5P_CMU_RESET_LCD0_LOWPWR , .val = 0x0, },
66 { .reg = S5P_CMU_RESET_LCD1_LOWPWR , .val = 0x0, },
67 { .reg = S5P_CMU_RESET_MAUDIO_LOWPWR , .val = 0x0, },
68 { .reg = S5P_CMU_RESET_GPS_LOWPWR , .val = 0x0, },
69 { .reg = S5P_TOP_BUS_LOWPWR , .val = 0x0, },
70 { .reg = S5P_TOP_RETENTION_LOWPWR , .val = 0x1, },
71 { .reg = S5P_TOP_PWR_LOWPWR , .val = 0x3, },
72 { .reg = S5P_LOGIC_RESET_LOWPWR , .val = 0x0, },
73 { .reg = S5P_ONENAND_MEM_LOWPWR , .val = 0x0, },
74 { .reg = S5P_MODIMIF_MEM_LOWPWR , .val = 0x0, },
75 { .reg = S5P_G2D_ACP_MEM_LOWPWR , .val = 0x0, },
76 { .reg = S5P_USBOTG_MEM_LOWPWR , .val = 0x0, },
77 { .reg = S5P_HSMMC_MEM_LOWPWR , .val = 0x0, },
78 { .reg = S5P_CSSYS_MEM_LOWPWR , .val = 0x0, },
79 { .reg = S5P_SECSS_MEM_LOWPWR , .val = 0x0, },
80 { .reg = S5P_PCIE_MEM_LOWPWR , .val = 0x0, },
81 { .reg = S5P_SATA_MEM_LOWPWR , .val = 0x0, },
82 { .reg = S5P_PAD_RETENTION_DRAM_LOWPWR , .val = 0x0, },
83 { .reg = S5P_PAD_RETENTION_MAUDIO_LOWPWR , .val = 0x0, },
84 { .reg = S5P_PAD_RETENTION_GPIO_LOWPWR , .val = 0x0, },
85 { .reg = S5P_PAD_RETENTION_UART_LOWPWR , .val = 0x0, },
86 { .reg = S5P_PAD_RETENTION_MMCA_LOWPWR , .val = 0x0, },
87 { .reg = S5P_PAD_RETENTION_MMCB_LOWPWR , .val = 0x0, },
88 { .reg = S5P_PAD_RETENTION_EBIA_LOWPWR , .val = 0x0, },
89 { .reg = S5P_PAD_RETENTION_EBIB_LOWPWR , .val = 0x0, },
90 { .reg = S5P_PAD_RETENTION_ISOLATION_LOWPWR , .val = 0x0, },
91 { .reg = S5P_PAD_RETENTION_ALV_SEL_LOWPWR , .val = 0x0, },
92 { .reg = S5P_XUSBXTI_LOWPWR , .val = 0x0, },
93 { .reg = S5P_XXTI_LOWPWR , .val = 0x0, },
94 { .reg = S5P_EXT_REGULATOR_LOWPWR , .val = 0x0, },
95 { .reg = S5P_GPIO_MODE_LOWPWR , .val = 0x0, },
96 { .reg = S5P_GPIO_MODE_MAUDIO_LOWPWR , .val = 0x0, },
97 { .reg = S5P_CAM_LOWPWR , .val = 0x0, },
98 { .reg = S5P_TV_LOWPWR , .val = 0x0, },
99 { .reg = S5P_MFC_LOWPWR , .val = 0x0, },
100 { .reg = S5P_G3D_LOWPWR , .val = 0x0, },
101 { .reg = S5P_LCD0_LOWPWR , .val = 0x0, },
102 { .reg = S5P_LCD1_LOWPWR , .val = 0x0, },
103 { .reg = S5P_MAUDIO_LOWPWR , .val = 0x0, },
104 { .reg = S5P_GPS_LOWPWR , .val = 0x0, },
105 { .reg = S5P_GPS_ALIVE_LOWPWR , .val = 0x0, },
108 static struct sleep_save exynos4_set_clksrc[] = {
109 { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, },
110 { .reg = S5P_CLKSRC_MASK_CAM , .val = 0x11111111, },
111 { .reg = S5P_CLKSRC_MASK_TV , .val = 0x00000111, },
112 { .reg = S5P_CLKSRC_MASK_LCD0 , .val = 0x00001111, },
113 { .reg = S5P_CLKSRC_MASK_LCD1 , .val = 0x00001111, },
114 { .reg = S5P_CLKSRC_MASK_MAUDIO , .val = 0x00000001, },
115 { .reg = S5P_CLKSRC_MASK_FSYS , .val = 0x01011111, },
116 { .reg = S5P_CLKSRC_MASK_PERIL0 , .val = 0x01111111, },
117 { .reg = S5P_CLKSRC_MASK_PERIL1 , .val = 0x01110111, },
118 { .reg = S5P_CLKSRC_MASK_DMC , .val = 0x00010000, },
121 static struct sleep_save exynos4_core_save[] = {
122 /* CMU side */
123 SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
124 SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
125 SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
126 SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
127 SAVE_ITEM(S5P_EPLL_CON0),
128 SAVE_ITEM(S5P_EPLL_CON1),
129 SAVE_ITEM(S5P_VPLL_CON0),
130 SAVE_ITEM(S5P_VPLL_CON1),
131 SAVE_ITEM(S5P_CLKSRC_TOP0),
132 SAVE_ITEM(S5P_CLKSRC_TOP1),
133 SAVE_ITEM(S5P_CLKSRC_CAM),
134 SAVE_ITEM(S5P_CLKSRC_MFC),
135 SAVE_ITEM(S5P_CLKSRC_IMAGE),
136 SAVE_ITEM(S5P_CLKSRC_LCD0),
137 SAVE_ITEM(S5P_CLKSRC_LCD1),
138 SAVE_ITEM(S5P_CLKSRC_MAUDIO),
139 SAVE_ITEM(S5P_CLKSRC_FSYS),
140 SAVE_ITEM(S5P_CLKSRC_PERIL0),
141 SAVE_ITEM(S5P_CLKSRC_PERIL1),
142 SAVE_ITEM(S5P_CLKDIV_CAM),
143 SAVE_ITEM(S5P_CLKDIV_TV),
144 SAVE_ITEM(S5P_CLKDIV_MFC),
145 SAVE_ITEM(S5P_CLKDIV_G3D),
146 SAVE_ITEM(S5P_CLKDIV_IMAGE),
147 SAVE_ITEM(S5P_CLKDIV_LCD0),
148 SAVE_ITEM(S5P_CLKDIV_LCD1),
149 SAVE_ITEM(S5P_CLKDIV_MAUDIO),
150 SAVE_ITEM(S5P_CLKDIV_FSYS0),
151 SAVE_ITEM(S5P_CLKDIV_FSYS1),
152 SAVE_ITEM(S5P_CLKDIV_FSYS2),
153 SAVE_ITEM(S5P_CLKDIV_FSYS3),
154 SAVE_ITEM(S5P_CLKDIV_PERIL0),
155 SAVE_ITEM(S5P_CLKDIV_PERIL1),
156 SAVE_ITEM(S5P_CLKDIV_PERIL2),
157 SAVE_ITEM(S5P_CLKDIV_PERIL3),
158 SAVE_ITEM(S5P_CLKDIV_PERIL4),
159 SAVE_ITEM(S5P_CLKDIV_PERIL5),
160 SAVE_ITEM(S5P_CLKDIV_TOP),
161 SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
162 SAVE_ITEM(S5P_CLKSRC_MASK_TV),
163 SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
164 SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
165 SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
166 SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
167 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
168 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
169 SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
170 SAVE_ITEM(S5P_CLKGATE_IP_CAM),
171 SAVE_ITEM(S5P_CLKGATE_IP_TV),
172 SAVE_ITEM(S5P_CLKGATE_IP_MFC),
173 SAVE_ITEM(S5P_CLKGATE_IP_G3D),
174 SAVE_ITEM(S5P_CLKGATE_IP_IMAGE),
175 SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
176 SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
177 SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
178 SAVE_ITEM(S5P_CLKGATE_IP_GPS),
179 SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
180 SAVE_ITEM(S5P_CLKGATE_IP_PERIR),
181 SAVE_ITEM(S5P_CLKGATE_BLOCK),
182 SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
183 SAVE_ITEM(S5P_CLKSRC_DMC),
184 SAVE_ITEM(S5P_CLKDIV_DMC0),
185 SAVE_ITEM(S5P_CLKDIV_DMC1),
186 SAVE_ITEM(S5P_CLKGATE_IP_DMC),
187 SAVE_ITEM(S5P_CLKSRC_CPU),
188 SAVE_ITEM(S5P_CLKDIV_CPU),
189 SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
190 SAVE_ITEM(S5P_CLKGATE_IP_CPU),
191 /* GIC side */
192 SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
193 SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
194 SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
195 SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
196 SAVE_ITEM(S5P_VA_GIC_CPU + 0x014),
197 SAVE_ITEM(S5P_VA_GIC_CPU + 0x018),
198 SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
199 SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
200 SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
201 SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
202 SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
203 SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
204 SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
205 SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
206 SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
207 SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
208 SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
209 SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
210 SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
211 SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
212 SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
213 SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
214 SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
215 SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
216 SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
217 SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
218 SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
219 SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
220 SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
221 SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
222 SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
223 SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
224 SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
225 SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
226 SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
227 SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
228 SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
229 SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
231 SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
232 SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
233 SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
234 SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
235 SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
236 SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
237 SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
238 SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
239 SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
240 SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
241 SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
242 SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
243 SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
244 SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
245 SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
246 SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
247 SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
248 SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
249 SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
250 SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
251 SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
252 SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
253 SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
254 SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
256 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
257 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
258 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
259 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
260 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
261 SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
263 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
264 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
265 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
266 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
267 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
268 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
269 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
270 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
271 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
272 SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
275 static struct sleep_save exynos4_l2cc_save[] = {
276 SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
277 SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
278 SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
279 SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
280 SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
283 void exynos4_cpu_suspend(void)
285 unsigned long tmp;
286 unsigned long mask = 0xFFFFFFFF;
288 /* Setting Central Sequence Register for power down mode */
290 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
291 tmp &= ~(S5P_CENTRAL_LOWPWR_CFG);
292 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
294 /* Setting Central Sequence option Register */
296 tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
297 tmp &= ~(S5P_USE_MASK);
298 tmp |= S5P_USE_STANDBY_WFI0;
299 __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
301 /* Clear all interrupt pending to avoid early wakeup */
303 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x280));
304 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x284));
305 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x288));
307 /* Disable all interrupt */
309 __raw_writel(0x0, (S5P_VA_GIC_CPU + 0x000));
310 __raw_writel(0x0, (S5P_VA_GIC_DIST + 0x000));
311 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x184));
312 __raw_writel(mask, (S5P_VA_GIC_DIST + 0x188));
314 outer_flush_all();
316 /* issue the standby signal into the pm unit. */
317 cpu_do_idle();
319 /* we should never get past here */
320 panic("sleep resumed to originator?");
323 static void exynos4_pm_prepare(void)
325 u32 tmp;
327 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
328 s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
330 tmp = __raw_readl(S5P_INFORM1);
332 /* Set value of power down register for sleep mode */
334 s3c_pm_do_restore_core(exynos4_sleep, ARRAY_SIZE(exynos4_sleep));
335 __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
337 /* ensure at least INFORM0 has the resume address */
339 __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
341 /* Before enter central sequence mode, clock src register have to set */
343 s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
347 static int exynos4_pm_add(struct sys_device *sysdev)
349 pm_cpu_prep = exynos4_pm_prepare;
350 pm_cpu_sleep = exynos4_cpu_suspend;
352 return 0;
355 /* This function copy from linux/arch/arm/kernel/smp_scu.c */
357 void exynos4_scu_enable(void __iomem *scu_base)
359 u32 scu_ctrl;
361 scu_ctrl = __raw_readl(scu_base);
362 /* already enabled? */
363 if (scu_ctrl & 1)
364 return;
366 scu_ctrl |= 1;
367 __raw_writel(scu_ctrl, scu_base);
370 * Ensure that the data accessed by CPU0 before the SCU was
371 * initialised is visible to the other CPUs.
373 flush_cache_all();
376 static struct sysdev_driver exynos4_pm_driver = {
377 .add = exynos4_pm_add,
380 static __init int exynos4_pm_drvinit(void)
382 unsigned int tmp;
384 s3c_pm_init();
386 /* All wakeup disable */
388 tmp = __raw_readl(S5P_WAKEUP_MASK);
389 tmp |= ((0xFF << 8) | (0x1F << 1));
390 __raw_writel(tmp, S5P_WAKEUP_MASK);
392 return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
394 arch_initcall(exynos4_pm_drvinit);
396 static void exynos4_pm_resume(void)
398 /* For release retention */
400 __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
401 __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
402 __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
403 __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
404 __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
405 __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
406 __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
408 s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
410 exynos4_scu_enable(S5P_VA_SCU);
412 #ifdef CONFIG_CACHE_L2X0
413 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
414 outer_inv_all();
415 /* enable L2X0*/
416 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
417 #endif
420 static struct syscore_ops exynos4_pm_syscore_ops = {
421 .resume = exynos4_pm_resume,
424 static __init int exynos4_pm_syscore_init(void)
426 register_syscore_ops(&exynos4_pm_syscore_ops);
427 return 0;
429 arch_initcall(exynos4_pm_syscore_init);