blob: 6796fce923e29887c157348706991136f0160962 [file] [log] [blame]
Jongpill Leec9347102012-02-17 09:49:54 +09001/*
2 * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
Jaecheol Lee16638952011-03-10 13:33:59 +09003 * http://www.samsung.com
4 *
Jongpill Leec9347102012-02-17 09:49:54 +09005 * EXYNOS - Power Management support
Jaecheol Lee16638952011-03-10 13:33:59 +09006 *
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>
Rafael J. Wysockibb072c32011-04-22 22:03:21 +020018#include <linux/syscore_ops.h>
Daniel Lezcano85f9f902014-05-09 06:43:27 +090019#include <linux/cpu_pm.h>
Jaecheol Lee16638952011-03-10 13:33:59 +090020#include <linux/io.h>
Tomasz Figadd8ac6962014-03-18 07:28:30 +090021#include <linux/irqchip/arm-gic.h>
Jaecheol Lee56c03d92011-07-18 19:25:13 +090022#include <linux/err.h>
23#include <linux/clk.h>
Jaecheol Lee16638952011-03-10 13:33:59 +090024
25#include <asm/cacheflush.h>
Tomasz Figa2b9d9c32014-09-24 01:24:39 +090026#include <asm/firmware.h>
Jaecheol Lee16638952011-03-10 13:33:59 +090027#include <asm/hardware/cache-l2x0.h>
Shawn Guo63b870f2011-11-17 01:19:11 +090028#include <asm/smp_scu.h>
Tomasz Figad710aa32014-03-18 07:28:27 +090029#include <asm/suspend.h>
Jaecheol Lee16638952011-03-10 13:33:59 +090030
Tomasz Figad710aa32014-03-18 07:28:27 +090031#include <plat/pm-common.h>
MyungJoo Hamb93cb912011-07-21 11:25:23 +090032#include <plat/regs-srom.h>
Jaecheol Lee16638952011-03-10 13:33:59 +090033
Kukjin Kim9c9239a2013-12-19 04:19:59 +090034#include <mach/map.h>
Kukjin Kimccd458c2012-12-31 10:06:48 -080035
36#include "common.h"
Kukjin Kim65c9a852013-12-19 04:06:56 +090037#include "regs-pmu.h"
Pankaj Dubey318fd202014-07-08 07:54:08 +090038#include "regs-sys.h"
Jaecheol Lee16638952011-03-10 13:33:59 +090039
Vikas Sajjan066da1a2014-09-24 16:45:14 +090040#define REG_TABLE_END (-1U)
41
Tomasz Figadd8ac6962014-03-18 07:28:30 +090042/**
43 * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
44 * @hwirq: Hardware IRQ signal of the GIC
45 * @mask: Mask in PMU wake-up mask register
46 */
47struct exynos_wkup_irq {
48 unsigned int hwirq;
49 u32 mask;
50};
51
Abhilash Kesavan86ffb0e2012-11-20 18:20:45 +090052static struct sleep_save exynos5_sys_save[] = {
53 SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
54};
55
Jongpill Leec9347102012-02-17 09:49:54 +090056static struct sleep_save exynos_core_save[] = {
MyungJoo Hamb93cb912011-07-21 11:25:23 +090057 /* 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),
Jaecheol Lee16638952011-03-10 13:33:59 +090063};
64
Vikas Sajjan066da1a2014-09-24 16:45:14 +090065struct exynos_pm_data {
66 const struct exynos_wkup_irq *wkup_irq;
67 struct sleep_save *extra_save;
68 int num_extra_save;
69 unsigned int wake_disable_mask;
70 unsigned int *release_ret_regs;
71
72 void (*pm_prepare)(void);
73 void (*pm_resume)(void);
74 int (*pm_suspend)(void);
75 int (*cpu_suspend)(unsigned long);
76};
77
78struct exynos_pm_data *pm_data;
79
Tomasz Figadd8ac6962014-03-18 07:28:30 +090080/*
81 * GIC wake-up support
82 */
83
Tomasz Figad710aa32014-03-18 07:28:27 +090084static u32 exynos_irqwake_intmask = 0xffffffff;
Jaecheol Lee16638952011-03-10 13:33:59 +090085
Tomasz Figadd8ac6962014-03-18 07:28:30 +090086static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
87 { 76, BIT(1) }, /* RTC alarm */
88 { 77, BIT(2) }, /* RTC tick */
89 { /* sentinel */ },
90};
91
92static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
93 { 75, BIT(1) }, /* RTC alarm */
94 { 76, BIT(2) }, /* RTC tick */
95 { /* sentinel */ },
96};
97
Vikas Sajjan066da1a2014-09-24 16:45:14 +090098unsigned int exynos_release_ret_regs[] = {
99 S5P_PAD_RET_MAUDIO_OPTION,
100 S5P_PAD_RET_GPIO_OPTION,
101 S5P_PAD_RET_UART_OPTION,
102 S5P_PAD_RET_MMCA_OPTION,
103 S5P_PAD_RET_MMCB_OPTION,
104 S5P_PAD_RET_EBIA_OPTION,
105 S5P_PAD_RET_EBIB_OPTION,
106 REG_TABLE_END,
107};
108
Tomasz Figadd8ac6962014-03-18 07:28:30 +0900109static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
110{
111 const struct exynos_wkup_irq *wkup_irq;
112
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900113 if (!pm_data->wkup_irq)
114 return -ENOENT;
115 wkup_irq = pm_data->wkup_irq;
Tomasz Figadd8ac6962014-03-18 07:28:30 +0900116
117 while (wkup_irq->mask) {
118 if (wkup_irq->hwirq == data->hwirq) {
119 if (!state)
120 exynos_irqwake_intmask |= wkup_irq->mask;
121 else
122 exynos_irqwake_intmask &= ~wkup_irq->mask;
123 return 0;
124 }
125 ++wkup_irq;
126 }
127
128 return -ENOENT;
129}
130
Bartlomiej Zolnierkiewicz134abc22014-09-25 17:59:40 +0900131static inline void __iomem *exynos_boot_vector_addr(void)
132{
133 if (samsung_rev() == EXYNOS4210_REV_1_1)
134 return pmu_base_addr + S5P_INFORM7;
135 else if (samsung_rev() == EXYNOS4210_REV_1_0)
136 return sysram_base_addr + 0x24;
137 return pmu_base_addr + S5P_INFORM0;
138}
139
140static inline void __iomem *exynos_boot_vector_flag(void)
141{
142 if (samsung_rev() == EXYNOS4210_REV_1_1)
143 return pmu_base_addr + S5P_INFORM6;
144 else if (samsung_rev() == EXYNOS4210_REV_1_0)
145 return sysram_base_addr + 0x20;
146 return pmu_base_addr + S5P_INFORM1;
147}
Daniel Lezcano3681baf2014-05-09 06:53:00 +0900148
Daniel Lezcanoe30b1542014-05-09 06:56:24 +0900149#define S5P_CHECK_AFTR 0xFCBA0D10
150#define S5P_CHECK_SLEEP 0x00000BAD
Daniel Lezcano3681baf2014-05-09 06:53:00 +0900151
Jaecheol Leef4ba4b02011-07-18 19:25:03 +0900152/* For Cortex-A9 Diagnostic and Power control register */
153static unsigned int save_arm_register[2];
154
Daniel Lezcano309e08c2014-05-09 06:43:27 +0900155static void exynos_cpu_save_register(void)
156{
157 unsigned long tmp;
158
159 /* Save Power control register */
160 asm ("mrc p15, 0, %0, c15, c0, 0"
161 : "=r" (tmp) : : "cc");
162
163 save_arm_register[0] = tmp;
164
165 /* Save Diagnostic register */
166 asm ("mrc p15, 0, %0, c15, c0, 1"
167 : "=r" (tmp) : : "cc");
168
169 save_arm_register[1] = tmp;
170}
171
172static void exynos_cpu_restore_register(void)
173{
174 unsigned long tmp;
175
176 /* Restore Power control register */
177 tmp = save_arm_register[0];
178
179 asm volatile ("mcr p15, 0, %0, c15, c0, 0"
180 : : "r" (tmp)
181 : "cc");
182
183 /* Restore Diagnostic register */
184 tmp = save_arm_register[1];
185
186 asm volatile ("mcr p15, 0, %0, c15, c0, 1"
187 : : "r" (tmp)
188 : "cc");
189}
190
Tomasz Figa01601b32014-08-05 14:43:10 +0200191static void exynos_pm_central_suspend(void)
192{
193 unsigned long tmp;
194
195 /* Setting Central Sequence Register for power down mode */
196 tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
197 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
198 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
199}
200
201static int exynos_pm_central_resume(void)
202{
203 unsigned long tmp;
204
205 /*
206 * If PMU failed while entering sleep mode, WFI will be
207 * ignored by PMU and then exiting cpu_do_idle().
208 * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
209 * in this situation.
210 */
211 tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
212 if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
213 tmp |= S5P_CENTRAL_LOWPWR_CFG;
214 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
215 /* clear the wakeup state register */
216 pmu_raw_writel(0x0, S5P_WAKEUP_STAT);
217 /* No need to perform below restore code */
218 return -1;
219 }
220
221 return 0;
222}
223
224/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
225static void exynos_set_wakeupmask(long mask)
226{
227 pmu_raw_writel(mask, S5P_WAKEUP_MASK);
228}
229
230static void exynos_cpu_set_boot_vector(long flags)
231{
Bartlomiej Zolnierkiewicz134abc22014-09-25 17:59:40 +0900232 __raw_writel(virt_to_phys(exynos_cpu_resume),
233 exynos_boot_vector_addr());
234 __raw_writel(flags, exynos_boot_vector_flag());
Tomasz Figa01601b32014-08-05 14:43:10 +0200235}
236
237static int exynos_aftr_finisher(unsigned long flags)
238{
Bartlomiej Zolnierkiewicza135e202014-09-25 17:59:41 +0900239 int ret;
240
Tomasz Figa01601b32014-08-05 14:43:10 +0200241 exynos_set_wakeupmask(0x0000ff3e);
Tomasz Figa01601b32014-08-05 14:43:10 +0200242 /* Set value of power down register for aftr mode */
243 exynos_sys_powerdown_conf(SYS_AFTR);
Bartlomiej Zolnierkiewicza135e202014-09-25 17:59:41 +0900244
245 ret = call_firmware_op(do_idle, FW_DO_IDLE_AFTR);
246 if (ret == -ENOSYS) {
247 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
248 exynos_cpu_save_register();
249 exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
250 cpu_do_idle();
251 }
Tomasz Figa01601b32014-08-05 14:43:10 +0200252
253 return 1;
254}
255
256void exynos_enter_aftr(void)
257{
258 cpu_pm_enter();
259
260 exynos_pm_central_suspend();
Tomasz Figa01601b32014-08-05 14:43:10 +0200261
262 cpu_suspend(0, exynos_aftr_finisher);
263
264 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
265 scu_enable(S5P_VA_SCU);
Bartlomiej Zolnierkiewicza135e202014-09-25 17:59:41 +0900266 if (call_firmware_op(resume) == -ENOSYS)
267 exynos_cpu_restore_register();
Tomasz Figa01601b32014-08-05 14:43:10 +0200268 }
269
270 exynos_pm_central_resume();
271
272 cpu_pm_exit();
273}
274
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900275static int exynos_cpu_do_idle(void)
Jaecheol Lee16638952011-03-10 13:33:59 +0900276{
Jaecheol Lee16638952011-03-10 13:33:59 +0900277 /* issue the standby signal into the pm unit. */
278 cpu_do_idle();
279
Abhilash Kesavand3fcacf2013-01-25 10:40:19 -0800280 pr_info("Failed to suspend the system\n");
281 return 1; /* Aborting suspend */
Jaecheol Lee16638952011-03-10 13:33:59 +0900282}
283
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900284static int exynos_cpu_suspend(unsigned long arg)
Jaecheol Lee16638952011-03-10 13:33:59 +0900285{
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900286 flush_cache_all();
287 outer_flush_all();
288 return exynos_cpu_do_idle();
289}
Jaecheol Lee16638952011-03-10 13:33:59 +0900290
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900291static void exynos_pm_set_wakeup_mask(void)
292{
Tomasz Figad710aa32014-03-18 07:28:27 +0900293 /* Set wake-up mask registers */
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900294 pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
295 pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900296}
Tomasz Figad710aa32014-03-18 07:28:27 +0900297
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900298static void exynos_pm_enter_sleep_mode(void)
299{
Jaecheol Lee16638952011-03-10 13:33:59 +0900300 /* Set value of power down register for sleep mode */
Jongpill Lee7d44d2b2012-02-17 09:51:31 +0900301 exynos_sys_powerdown_conf(SYS_SLEEP);
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900302 pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
Jaecheol Lee16638952011-03-10 13:33:59 +0900303
304 /* ensure at least INFORM0 has the resume address */
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900305 pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
Jaecheol Lee16638952011-03-10 13:33:59 +0900306}
307
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900308static void exynos_pm_prepare(void)
309{
310 /* Set wake-up mask registers */
311 exynos_pm_set_wakeup_mask();
312
313 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
314
315 if (pm_data->extra_save)
316 s3c_pm_do_save(pm_data->extra_save,
317 pm_data->num_extra_save);
318
319 exynos_pm_enter_sleep_mode();
320}
321
Daniel Lezcano0ebc13e2014-05-09 06:55:12 +0900322static int exynos_pm_suspend(void)
323{
324 unsigned long tmp;
325
326 exynos_pm_central_suspend();
Jaecheol Lee12974e92011-07-18 19:21:41 +0900327
Jongpill Lee60e49ca2012-02-17 12:23:51 +0900328 /* Setting SEQ_OPTION register */
329
330 tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900331 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
Jongpill Lee60e49ca2012-02-17 12:23:51 +0900332
Russell Kingaf040ff2014-06-24 19:43:15 +0100333 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
Daniel Lezcano309e08c2014-05-09 06:43:27 +0900334 exynos_cpu_save_register();
Jongpill Lee00a351f2011-09-27 07:26:04 +0900335
Jaecheol Lee12974e92011-07-18 19:21:41 +0900336 return 0;
337}
338
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900339static void exynos_pm_release_retention(void)
340{
341 unsigned int i;
342
343 for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
344 pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
345 pm_data->release_ret_regs[i]);
346}
347
Daniel Lezcano0ebc13e2014-05-09 06:55:12 +0900348static void exynos_pm_resume(void)
349{
Tomasz Figa2b9d9c32014-09-24 01:24:39 +0900350 u32 cpuid = read_cpuid_part();
351
Daniel Lezcano0ebc13e2014-05-09 06:55:12 +0900352 if (exynos_pm_central_resume())
353 goto early_wakeup;
354
Jaecheol Lee16638952011-03-10 13:33:59 +0900355 /* For release retention */
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900356 exynos_pm_release_retention();
Jaecheol Lee16638952011-03-10 13:33:59 +0900357
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900358 if (pm_data->extra_save)
359 s3c_pm_do_restore_core(pm_data->extra_save,
360 pm_data->num_extra_save);
Abhilash Kesavan86ffb0e2012-11-20 18:20:45 +0900361
Jongpill Leec9347102012-02-17 09:49:54 +0900362 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
Jaecheol Lee16638952011-03-10 13:33:59 +0900363
Tomasz Figa2b9d9c32014-09-24 01:24:39 +0900364 if (cpuid == ARM_CPU_PART_CORTEX_A9)
Jongpill Lee60e49ca2012-02-17 12:23:51 +0900365 scu_enable(S5P_VA_SCU);
Jaecheol Lee16638952011-03-10 13:33:59 +0900366
Tomasz Figa2b9d9c32014-09-24 01:24:39 +0900367 if (call_firmware_op(resume) == -ENOSYS
368 && cpuid == ARM_CPU_PART_CORTEX_A9)
369 exynos_cpu_restore_register();
370
Jaecheol Leee240ab12011-07-18 19:21:34 +0900371early_wakeup:
Inderpal Singhebee8542012-11-22 14:46:27 +0900372
373 /* Clear SLEEP mode set in INFORM1 */
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900374 pmu_raw_writel(0x0, S5P_INFORM1);
Jaecheol Lee16638952011-03-10 13:33:59 +0900375}
376
Tomasz Figad710aa32014-03-18 07:28:27 +0900377/*
378 * Suspend Ops
379 */
380
381static int exynos_suspend_enter(suspend_state_t state)
382{
383 int ret;
384
385 s3c_pm_debug_init();
386
387 S3C_PMDBG("%s: suspending the system...\n", __func__);
388
389 S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
390 exynos_irqwake_intmask, exynos_get_eint_wake_mask());
391
392 if (exynos_irqwake_intmask == -1U
393 && exynos_get_eint_wake_mask() == -1U) {
394 pr_err("%s: No wake-up sources!\n", __func__);
395 pr_err("%s: Aborting sleep\n", __func__);
396 return -EINVAL;
397 }
398
399 s3c_pm_save_uarts();
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900400 if (pm_data->pm_prepare)
401 pm_data->pm_prepare();
Tomasz Figad710aa32014-03-18 07:28:27 +0900402 flush_cache_all();
403 s3c_pm_check_store();
404
Tomasz Figa2b9d9c32014-09-24 01:24:39 +0900405 ret = call_firmware_op(suspend);
406 if (ret == -ENOSYS)
407 ret = cpu_suspend(0, pm_data->cpu_suspend);
Tomasz Figad710aa32014-03-18 07:28:27 +0900408 if (ret)
409 return ret;
410
411 s3c_pm_restore_uarts();
412
413 S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900414 pmu_raw_readl(S5P_WAKEUP_STAT));
Tomasz Figad710aa32014-03-18 07:28:27 +0900415
416 s3c_pm_check_restore();
417
418 S3C_PMDBG("%s: resuming the system...\n", __func__);
419
420 return 0;
421}
422
423static int exynos_suspend_prepare(void)
424{
425 s3c_pm_check_prepare();
426
427 return 0;
428}
429
430static void exynos_suspend_finish(void)
431{
432 s3c_pm_check_cleanup();
433}
434
435static const struct platform_suspend_ops exynos_suspend_ops = {
436 .enter = exynos_suspend_enter,
437 .prepare = exynos_suspend_prepare,
438 .finish = exynos_suspend_finish,
439 .valid = suspend_valid_only_mem,
440};
441
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900442static const struct exynos_pm_data exynos4_pm_data = {
443 .wkup_irq = exynos4_wkup_irq,
444 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
445 .release_ret_regs = exynos_release_ret_regs,
446 .pm_suspend = exynos_pm_suspend,
447 .pm_resume = exynos_pm_resume,
448 .pm_prepare = exynos_pm_prepare,
449 .cpu_suspend = exynos_cpu_suspend,
450};
451
452static const struct exynos_pm_data exynos5250_pm_data = {
453 .wkup_irq = exynos5250_wkup_irq,
454 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
455 .release_ret_regs = exynos_release_ret_regs,
456 .extra_save = exynos5_sys_save,
457 .num_extra_save = ARRAY_SIZE(exynos5_sys_save),
458 .pm_suspend = exynos_pm_suspend,
459 .pm_resume = exynos_pm_resume,
460 .pm_prepare = exynos_pm_prepare,
461 .cpu_suspend = exynos_cpu_suspend,
462};
463
464static struct of_device_id exynos_pmu_of_device_ids[] = {
465 {
466 .compatible = "samsung,exynos4210-pmu",
467 .data = &exynos4_pm_data,
468 }, {
469 .compatible = "samsung,exynos4212-pmu",
470 .data = &exynos4_pm_data,
471 }, {
472 .compatible = "samsung,exynos4412-pmu",
473 .data = &exynos4_pm_data,
474 }, {
475 .compatible = "samsung,exynos5250-pmu",
476 .data = &exynos5250_pm_data,
477 },
478 { /*sentinel*/ },
479};
480
481static struct syscore_ops exynos_pm_syscore_ops;
482
Tomasz Figa559ba232014-03-18 07:28:22 +0900483void __init exynos_pm_init(void)
Jaecheol Lee16638952011-03-10 13:33:59 +0900484{
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900485 const struct of_device_id *match;
Tomasz Figa559ba232014-03-18 07:28:22 +0900486 u32 tmp;
487
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900488 of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
489 if (!match) {
490 pr_err("Failed to find PMU node\n");
491 return;
492 }
493 pm_data = (struct exynos_pm_data *) match->data;
494
Tomasz Figadd8ac6962014-03-18 07:28:30 +0900495 /* Platform-specific GIC callback */
496 gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
497
Tomasz Figa559ba232014-03-18 07:28:22 +0900498 /* All wakeup disable */
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900499 tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900500 tmp |= pm_data->wake_disable_mask;
Pankaj Dubey2e94ac42014-07-19 03:43:22 +0900501 pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
Kukjin Kime085cad2013-06-26 22:29:44 +0900502
Vikas Sajjan066da1a2014-09-24 16:45:14 +0900503 exynos_pm_syscore_ops.suspend = pm_data->pm_suspend;
504 exynos_pm_syscore_ops.resume = pm_data->pm_resume;
505
Jongpill Leec9347102012-02-17 09:49:54 +0900506 register_syscore_ops(&exynos_pm_syscore_ops);
Tomasz Figad710aa32014-03-18 07:28:27 +0900507 suspend_set_ops(&exynos_suspend_ops);
Jaecheol Lee16638952011-03-10 13:33:59 +0900508}