xref: /openbmc/linux/arch/arm/mach-exynos/suspend.c (revision b96fc2f3)
1 /*
2  * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
3  *		http://www.samsung.com
4  *
5  * EXYNOS - Suspend support
6  *
7  * Based on arch/arm/mach-s3c2410/pm.c
8  * Copyright (c) 2006 Simtec Electronics
9  *	Ben Dooks <ben@simtec.co.uk>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15 
16 #include <linux/init.h>
17 #include <linux/suspend.h>
18 #include <linux/syscore_ops.h>
19 #include <linux/cpu_pm.h>
20 #include <linux/io.h>
21 #include <linux/irq.h>
22 #include <linux/irqchip.h>
23 #include <linux/irqdomain.h>
24 #include <linux/of_address.h>
25 #include <linux/err.h>
26 #include <linux/regulator/machine.h>
27 
28 #include <asm/cacheflush.h>
29 #include <asm/hardware/cache-l2x0.h>
30 #include <asm/firmware.h>
31 #include <asm/mcpm.h>
32 #include <asm/smp_scu.h>
33 #include <asm/suspend.h>
34 
35 #include <plat/pm-common.h>
36 
37 #include "common.h"
38 #include "exynos-pmu.h"
39 #include "regs-pmu.h"
40 #include "regs-srom.h"
41 
42 #define REG_TABLE_END (-1U)
43 
44 #define EXYNOS5420_CPU_STATE	0x28
45 
46 /**
47  * struct exynos_wkup_irq - PMU IRQ to mask mapping
48  * @hwirq: Hardware IRQ signal of the PMU
49  * @mask: Mask in PMU wake-up mask register
50  */
51 struct exynos_wkup_irq {
52 	unsigned int hwirq;
53 	u32 mask;
54 };
55 
56 static struct sleep_save exynos_core_save[] = {
57 	/* SROM side */
58 	SAVE_ITEM(S5P_SROM_BW),
59 	SAVE_ITEM(S5P_SROM_BC0),
60 	SAVE_ITEM(S5P_SROM_BC1),
61 	SAVE_ITEM(S5P_SROM_BC2),
62 	SAVE_ITEM(S5P_SROM_BC3),
63 };
64 
65 struct exynos_pm_data {
66 	const struct exynos_wkup_irq *wkup_irq;
67 	unsigned int wake_disable_mask;
68 	unsigned int *release_ret_regs;
69 
70 	void (*pm_prepare)(void);
71 	void (*pm_resume_prepare)(void);
72 	void (*pm_resume)(void);
73 	int (*pm_suspend)(void);
74 	int (*cpu_suspend)(unsigned long);
75 };
76 
77 static const struct exynos_pm_data *pm_data;
78 
79 static int exynos5420_cpu_state;
80 static unsigned int exynos_pmu_spare3;
81 
82 /*
83  * GIC wake-up support
84  */
85 
86 static u32 exynos_irqwake_intmask = 0xffffffff;
87 
88 static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
89 	{ 73, BIT(1) }, /* RTC alarm */
90 	{ 74, BIT(2) }, /* RTC tick */
91 	{ /* sentinel */ },
92 };
93 
94 static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
95 	{ 44, BIT(1) }, /* RTC alarm */
96 	{ 45, BIT(2) }, /* RTC tick */
97 	{ /* sentinel */ },
98 };
99 
100 static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
101 	{ 43, BIT(1) }, /* RTC alarm */
102 	{ 44, BIT(2) }, /* RTC tick */
103 	{ /* sentinel */ },
104 };
105 
106 static unsigned int exynos_release_ret_regs[] = {
107 	S5P_PAD_RET_MAUDIO_OPTION,
108 	S5P_PAD_RET_GPIO_OPTION,
109 	S5P_PAD_RET_UART_OPTION,
110 	S5P_PAD_RET_MMCA_OPTION,
111 	S5P_PAD_RET_MMCB_OPTION,
112 	S5P_PAD_RET_EBIA_OPTION,
113 	S5P_PAD_RET_EBIB_OPTION,
114 	REG_TABLE_END,
115 };
116 
117 static unsigned int exynos3250_release_ret_regs[] = {
118 	S5P_PAD_RET_MAUDIO_OPTION,
119 	S5P_PAD_RET_GPIO_OPTION,
120 	S5P_PAD_RET_UART_OPTION,
121 	S5P_PAD_RET_MMCA_OPTION,
122 	S5P_PAD_RET_MMCB_OPTION,
123 	S5P_PAD_RET_EBIA_OPTION,
124 	S5P_PAD_RET_EBIB_OPTION,
125 	S5P_PAD_RET_MMC2_OPTION,
126 	S5P_PAD_RET_SPI_OPTION,
127 	REG_TABLE_END,
128 };
129 
130 static unsigned int exynos5420_release_ret_regs[] = {
131 	EXYNOS_PAD_RET_DRAM_OPTION,
132 	EXYNOS_PAD_RET_MAUDIO_OPTION,
133 	EXYNOS_PAD_RET_JTAG_OPTION,
134 	EXYNOS5420_PAD_RET_GPIO_OPTION,
135 	EXYNOS5420_PAD_RET_UART_OPTION,
136 	EXYNOS5420_PAD_RET_MMCA_OPTION,
137 	EXYNOS5420_PAD_RET_MMCB_OPTION,
138 	EXYNOS5420_PAD_RET_MMCC_OPTION,
139 	EXYNOS5420_PAD_RET_HSI_OPTION,
140 	EXYNOS_PAD_RET_EBIA_OPTION,
141 	EXYNOS_PAD_RET_EBIB_OPTION,
142 	EXYNOS5420_PAD_RET_SPI_OPTION,
143 	EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
144 	REG_TABLE_END,
145 };
146 
147 static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
148 {
149 	const struct exynos_wkup_irq *wkup_irq;
150 
151 	if (!pm_data->wkup_irq)
152 		return -ENOENT;
153 	wkup_irq = pm_data->wkup_irq;
154 
155 	while (wkup_irq->mask) {
156 		if (wkup_irq->hwirq == data->hwirq) {
157 			if (!state)
158 				exynos_irqwake_intmask |= wkup_irq->mask;
159 			else
160 				exynos_irqwake_intmask &= ~wkup_irq->mask;
161 			return 0;
162 		}
163 		++wkup_irq;
164 	}
165 
166 	return -ENOENT;
167 }
168 
169 static struct irq_chip exynos_pmu_chip = {
170 	.name			= "PMU",
171 	.irq_eoi		= irq_chip_eoi_parent,
172 	.irq_mask		= irq_chip_mask_parent,
173 	.irq_unmask		= irq_chip_unmask_parent,
174 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
175 	.irq_set_wake		= exynos_irq_set_wake,
176 #ifdef CONFIG_SMP
177 	.irq_set_affinity	= irq_chip_set_affinity_parent,
178 #endif
179 };
180 
181 static int exynos_pmu_domain_xlate(struct irq_domain *domain,
182 				   struct device_node *controller,
183 				   const u32 *intspec,
184 				   unsigned int intsize,
185 				   unsigned long *out_hwirq,
186 				   unsigned int *out_type)
187 {
188 	if (domain->of_node != controller)
189 		return -EINVAL;	/* Shouldn't happen, really... */
190 	if (intsize != 3)
191 		return -EINVAL;	/* Not GIC compliant */
192 	if (intspec[0] != 0)
193 		return -EINVAL;	/* No PPI should point to this domain */
194 
195 	*out_hwirq = intspec[1];
196 	*out_type = intspec[2];
197 	return 0;
198 }
199 
200 static int exynos_pmu_domain_alloc(struct irq_domain *domain,
201 				   unsigned int virq,
202 				   unsigned int nr_irqs, void *data)
203 {
204 	struct of_phandle_args *args = data;
205 	struct of_phandle_args parent_args;
206 	irq_hw_number_t hwirq;
207 	int i;
208 
209 	if (args->args_count != 3)
210 		return -EINVAL;	/* Not GIC compliant */
211 	if (args->args[0] != 0)
212 		return -EINVAL;	/* No PPI should point to this domain */
213 
214 	hwirq = args->args[1];
215 
216 	for (i = 0; i < nr_irqs; i++)
217 		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
218 					      &exynos_pmu_chip, NULL);
219 
220 	parent_args = *args;
221 	parent_args.np = domain->parent->of_node;
222 	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
223 }
224 
225 static const struct irq_domain_ops exynos_pmu_domain_ops = {
226 	.xlate	= exynos_pmu_domain_xlate,
227 	.alloc	= exynos_pmu_domain_alloc,
228 	.free	= irq_domain_free_irqs_common,
229 };
230 
231 static int __init exynos_pmu_irq_init(struct device_node *node,
232 				      struct device_node *parent)
233 {
234 	struct irq_domain *parent_domain, *domain;
235 
236 	if (!parent) {
237 		pr_err("%s: no parent, giving up\n", node->full_name);
238 		return -ENODEV;
239 	}
240 
241 	parent_domain = irq_find_host(parent);
242 	if (!parent_domain) {
243 		pr_err("%s: unable to obtain parent domain\n", node->full_name);
244 		return -ENXIO;
245 	}
246 
247 	pmu_base_addr = of_iomap(node, 0);
248 
249 	if (!pmu_base_addr) {
250 		pr_err("%s: failed to find exynos pmu register\n",
251 		       node->full_name);
252 		return -ENOMEM;
253 	}
254 
255 	domain = irq_domain_add_hierarchy(parent_domain, 0, 0,
256 					  node, &exynos_pmu_domain_ops,
257 					  NULL);
258 	if (!domain) {
259 		iounmap(pmu_base_addr);
260 		return -ENOMEM;
261 	}
262 
263 	return 0;
264 }
265 
266 #define EXYNOS_PMU_IRQ(symbol, name)	IRQCHIP_DECLARE(symbol, name, exynos_pmu_irq_init)
267 
268 EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
269 EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
270 EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
271 EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
272 EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
273 EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
274 EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
275 
276 static int exynos_cpu_do_idle(void)
277 {
278 	/* issue the standby signal into the pm unit. */
279 	cpu_do_idle();
280 
281 	pr_info("Failed to suspend the system\n");
282 	return 1; /* Aborting suspend */
283 }
284 static void exynos_flush_cache_all(void)
285 {
286 	flush_cache_all();
287 	outer_flush_all();
288 }
289 
290 static int exynos_cpu_suspend(unsigned long arg)
291 {
292 	exynos_flush_cache_all();
293 	return exynos_cpu_do_idle();
294 }
295 
296 static int exynos3250_cpu_suspend(unsigned long arg)
297 {
298 	flush_cache_all();
299 	return exynos_cpu_do_idle();
300 }
301 
302 static int exynos5420_cpu_suspend(unsigned long arg)
303 {
304 	/* MCPM works with HW CPU identifiers */
305 	unsigned int mpidr = read_cpuid_mpidr();
306 	unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
307 	unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
308 
309 	__raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
310 
311 	if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
312 		mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
313 		mcpm_cpu_suspend();
314 	}
315 
316 	pr_info("Failed to suspend the system\n");
317 
318 	/* return value != 0 means failure */
319 	return 1;
320 }
321 
322 static void exynos_pm_set_wakeup_mask(void)
323 {
324 	/* Set wake-up mask registers */
325 	pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
326 	pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
327 }
328 
329 static void exynos_pm_enter_sleep_mode(void)
330 {
331 	/* Set value of power down register for sleep mode */
332 	exynos_sys_powerdown_conf(SYS_SLEEP);
333 	pmu_raw_writel(EXYNOS_SLEEP_MAGIC, S5P_INFORM1);
334 }
335 
336 static void exynos_pm_prepare(void)
337 {
338 	exynos_set_delayed_reset_assertion(false);
339 
340 	/* Set wake-up mask registers */
341 	exynos_pm_set_wakeup_mask();
342 
343 	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
344 
345 	exynos_pm_enter_sleep_mode();
346 
347 	/* ensure at least INFORM0 has the resume address */
348 	pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
349 }
350 
351 static void exynos3250_pm_prepare(void)
352 {
353 	unsigned int tmp;
354 
355 	/* Set wake-up mask registers */
356 	exynos_pm_set_wakeup_mask();
357 
358 	tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
359 	tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
360 	pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
361 
362 	exynos_pm_enter_sleep_mode();
363 
364 	/* ensure at least INFORM0 has the resume address */
365 	pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
366 }
367 
368 static void exynos5420_pm_prepare(void)
369 {
370 	unsigned int tmp;
371 
372 	/* Set wake-up mask registers */
373 	exynos_pm_set_wakeup_mask();
374 
375 	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
376 
377 	exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
378 	/*
379 	 * The cpu state needs to be saved and restored so that the
380 	 * secondary CPUs will enter low power start. Though the U-Boot
381 	 * is setting the cpu state with low power flag, the kernel
382 	 * needs to restore it back in case, the primary cpu fails to
383 	 * suspend for any reason.
384 	 */
385 	exynos5420_cpu_state = __raw_readl(sysram_base_addr +
386 						EXYNOS5420_CPU_STATE);
387 
388 	exynos_pm_enter_sleep_mode();
389 
390 	/* ensure at least INFORM0 has the resume address */
391 	if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
392 		pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
393 
394 	tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
395 	tmp &= ~EXYNOS5_USE_RETENTION;
396 	pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
397 
398 	tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
399 	tmp |= EXYNOS5420_UFS;
400 	pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
401 
402 	tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
403 	tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE;
404 	pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
405 
406 	tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
407 	tmp |= EXYNOS5420_EMULATION;
408 	pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
409 
410 	tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
411 	tmp |= EXYNOS5420_EMULATION;
412 	pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
413 }
414 
415 
416 static int exynos_pm_suspend(void)
417 {
418 	exynos_pm_central_suspend();
419 
420 	/* Setting SEQ_OPTION register */
421 	pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
422 		       S5P_CENTRAL_SEQ_OPTION);
423 
424 	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
425 		exynos_cpu_save_register();
426 
427 	return 0;
428 }
429 
430 static int exynos5420_pm_suspend(void)
431 {
432 	u32 this_cluster;
433 
434 	exynos_pm_central_suspend();
435 
436 	/* Setting SEQ_OPTION register */
437 
438 	this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
439 	if (!this_cluster)
440 		pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
441 				S5P_CENTRAL_SEQ_OPTION);
442 	else
443 		pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
444 				S5P_CENTRAL_SEQ_OPTION);
445 	return 0;
446 }
447 
448 static void exynos_pm_release_retention(void)
449 {
450 	unsigned int i;
451 
452 	for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
453 		pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
454 				pm_data->release_ret_regs[i]);
455 }
456 
457 static void exynos_pm_resume(void)
458 {
459 	u32 cpuid = read_cpuid_part();
460 
461 	if (exynos_pm_central_resume())
462 		goto early_wakeup;
463 
464 	/* For release retention */
465 	exynos_pm_release_retention();
466 
467 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
468 
469 	if (cpuid == ARM_CPU_PART_CORTEX_A9)
470 		scu_enable(S5P_VA_SCU);
471 
472 	if (call_firmware_op(resume) == -ENOSYS
473 	    && cpuid == ARM_CPU_PART_CORTEX_A9)
474 		exynos_cpu_restore_register();
475 
476 early_wakeup:
477 
478 	/* Clear SLEEP mode set in INFORM1 */
479 	pmu_raw_writel(0x0, S5P_INFORM1);
480 	exynos_set_delayed_reset_assertion(true);
481 }
482 
483 static void exynos3250_pm_resume(void)
484 {
485 	u32 cpuid = read_cpuid_part();
486 
487 	if (exynos_pm_central_resume())
488 		goto early_wakeup;
489 
490 	/* For release retention */
491 	exynos_pm_release_retention();
492 
493 	pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
494 
495 	if (call_firmware_op(resume) == -ENOSYS
496 	    && cpuid == ARM_CPU_PART_CORTEX_A9)
497 		exynos_cpu_restore_register();
498 
499 early_wakeup:
500 
501 	/* Clear SLEEP mode set in INFORM1 */
502 	pmu_raw_writel(0x0, S5P_INFORM1);
503 }
504 
505 static void exynos5420_prepare_pm_resume(void)
506 {
507 	if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
508 		WARN_ON(mcpm_cpu_powered_up());
509 }
510 
511 static void exynos5420_pm_resume(void)
512 {
513 	unsigned long tmp;
514 
515 	/* Restore the CPU0 low power state register */
516 	tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
517 	pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN,
518 		EXYNOS5_ARM_CORE0_SYS_PWR_REG);
519 
520 	/* Restore the sysram cpu state register */
521 	__raw_writel(exynos5420_cpu_state,
522 		sysram_base_addr + EXYNOS5420_CPU_STATE);
523 
524 	pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
525 			S5P_CENTRAL_SEQ_OPTION);
526 
527 	if (exynos_pm_central_resume())
528 		goto early_wakeup;
529 
530 	/* For release retention */
531 	exynos_pm_release_retention();
532 
533 	pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
534 
535 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
536 
537 early_wakeup:
538 
539 	tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
540 	tmp &= ~EXYNOS5420_UFS;
541 	pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
542 
543 	tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
544 	tmp &= ~EXYNOS5420_EMULATION;
545 	pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
546 
547 	tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
548 	tmp &= ~EXYNOS5420_EMULATION;
549 	pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
550 
551 	/* Clear SLEEP mode set in INFORM1 */
552 	pmu_raw_writel(0x0, S5P_INFORM1);
553 }
554 
555 /*
556  * Suspend Ops
557  */
558 
559 static int exynos_suspend_enter(suspend_state_t state)
560 {
561 	int ret;
562 
563 	s3c_pm_debug_init();
564 
565 	S3C_PMDBG("%s: suspending the system...\n", __func__);
566 
567 	S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
568 			exynos_irqwake_intmask, exynos_get_eint_wake_mask());
569 
570 	if (exynos_irqwake_intmask == -1U
571 	    && exynos_get_eint_wake_mask() == -1U) {
572 		pr_err("%s: No wake-up sources!\n", __func__);
573 		pr_err("%s: Aborting sleep\n", __func__);
574 		return -EINVAL;
575 	}
576 
577 	s3c_pm_save_uarts();
578 	if (pm_data->pm_prepare)
579 		pm_data->pm_prepare();
580 	flush_cache_all();
581 	s3c_pm_check_store();
582 
583 	ret = call_firmware_op(suspend);
584 	if (ret == -ENOSYS)
585 		ret = cpu_suspend(0, pm_data->cpu_suspend);
586 	if (ret)
587 		return ret;
588 
589 	if (pm_data->pm_resume_prepare)
590 		pm_data->pm_resume_prepare();
591 	s3c_pm_restore_uarts();
592 
593 	S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
594 			pmu_raw_readl(S5P_WAKEUP_STAT));
595 
596 	s3c_pm_check_restore();
597 
598 	S3C_PMDBG("%s: resuming the system...\n", __func__);
599 
600 	return 0;
601 }
602 
603 static int exynos_suspend_prepare(void)
604 {
605 	int ret;
606 
607 	/*
608 	 * REVISIT: It would be better if struct platform_suspend_ops
609 	 * .prepare handler get the suspend_state_t as a parameter to
610 	 * avoid hard-coding the suspend to mem state. It's safe to do
611 	 * it now only because the suspend_valid_only_mem function is
612 	 * used as the .valid callback used to check if a given state
613 	 * is supported by the platform anyways.
614 	 */
615 	ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
616 	if (ret) {
617 		pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
618 		return ret;
619 	}
620 
621 	s3c_pm_check_prepare();
622 
623 	return 0;
624 }
625 
626 static void exynos_suspend_finish(void)
627 {
628 	int ret;
629 
630 	s3c_pm_check_cleanup();
631 
632 	ret = regulator_suspend_finish();
633 	if (ret)
634 		pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
635 }
636 
637 static const struct platform_suspend_ops exynos_suspend_ops = {
638 	.enter		= exynos_suspend_enter,
639 	.prepare	= exynos_suspend_prepare,
640 	.finish		= exynos_suspend_finish,
641 	.valid		= suspend_valid_only_mem,
642 };
643 
644 static const struct exynos_pm_data exynos3250_pm_data = {
645 	.wkup_irq	= exynos3250_wkup_irq,
646 	.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
647 	.release_ret_regs = exynos3250_release_ret_regs,
648 	.pm_suspend	= exynos_pm_suspend,
649 	.pm_resume	= exynos3250_pm_resume,
650 	.pm_prepare	= exynos3250_pm_prepare,
651 	.cpu_suspend	= exynos3250_cpu_suspend,
652 };
653 
654 static const struct exynos_pm_data exynos4_pm_data = {
655 	.wkup_irq	= exynos4_wkup_irq,
656 	.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
657 	.release_ret_regs = exynos_release_ret_regs,
658 	.pm_suspend	= exynos_pm_suspend,
659 	.pm_resume	= exynos_pm_resume,
660 	.pm_prepare	= exynos_pm_prepare,
661 	.cpu_suspend	= exynos_cpu_suspend,
662 };
663 
664 static const struct exynos_pm_data exynos5250_pm_data = {
665 	.wkup_irq	= exynos5250_wkup_irq,
666 	.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
667 	.release_ret_regs = exynos_release_ret_regs,
668 	.pm_suspend	= exynos_pm_suspend,
669 	.pm_resume	= exynos_pm_resume,
670 	.pm_prepare	= exynos_pm_prepare,
671 	.cpu_suspend	= exynos_cpu_suspend,
672 };
673 
674 static const struct exynos_pm_data exynos5420_pm_data = {
675 	.wkup_irq	= exynos5250_wkup_irq,
676 	.wake_disable_mask = (0x7F << 7) | (0x1F << 1),
677 	.release_ret_regs = exynos5420_release_ret_regs,
678 	.pm_resume_prepare = exynos5420_prepare_pm_resume,
679 	.pm_resume	= exynos5420_pm_resume,
680 	.pm_suspend	= exynos5420_pm_suspend,
681 	.pm_prepare	= exynos5420_pm_prepare,
682 	.cpu_suspend	= exynos5420_cpu_suspend,
683 };
684 
685 static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
686 	{
687 		.compatible = "samsung,exynos3250-pmu",
688 		.data = &exynos3250_pm_data,
689 	}, {
690 		.compatible = "samsung,exynos4210-pmu",
691 		.data = &exynos4_pm_data,
692 	}, {
693 		.compatible = "samsung,exynos4212-pmu",
694 		.data = &exynos4_pm_data,
695 	}, {
696 		.compatible = "samsung,exynos4412-pmu",
697 		.data = &exynos4_pm_data,
698 	}, {
699 		.compatible = "samsung,exynos5250-pmu",
700 		.data = &exynos5250_pm_data,
701 	}, {
702 		.compatible = "samsung,exynos5420-pmu",
703 		.data = &exynos5420_pm_data,
704 	},
705 	{ /*sentinel*/ },
706 };
707 
708 static struct syscore_ops exynos_pm_syscore_ops;
709 
710 void __init exynos_pm_init(void)
711 {
712 	const struct of_device_id *match;
713 	struct device_node *np;
714 	u32 tmp;
715 
716 	np = of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
717 	if (!np) {
718 		pr_err("Failed to find PMU node\n");
719 		return;
720 	}
721 
722 	if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
723 		pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
724 		return;
725 	}
726 
727 	pm_data = (const struct exynos_pm_data *) match->data;
728 
729 	/* All wakeup disable */
730 	tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
731 	tmp |= pm_data->wake_disable_mask;
732 	pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
733 
734 	exynos_pm_syscore_ops.suspend	= pm_data->pm_suspend;
735 	exynos_pm_syscore_ops.resume	= pm_data->pm_resume;
736 
737 	register_syscore_ops(&exynos_pm_syscore_ops);
738 	suspend_set_ops(&exynos_suspend_ops);
739 }
740