Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
0004 //      http://www.samsung.com
0005 //
0006 // Exynos - Suspend support
0007 //
0008 // Based on arch/arm/mach-s3c2410/pm.c
0009 // Copyright (c) 2006 Simtec Electronics
0010 //  Ben Dooks <ben@simtec.co.uk>
0011 
0012 #include <linux/init.h>
0013 #include <linux/suspend.h>
0014 #include <linux/syscore_ops.h>
0015 #include <linux/cpu_pm.h>
0016 #include <linux/io.h>
0017 #include <linux/irq.h>
0018 #include <linux/irqchip.h>
0019 #include <linux/irqdomain.h>
0020 #include <linux/of_address.h>
0021 #include <linux/err.h>
0022 #include <linux/regulator/machine.h>
0023 #include <linux/soc/samsung/exynos-pmu.h>
0024 #include <linux/soc/samsung/exynos-regs-pmu.h>
0025 
0026 #include <asm/cacheflush.h>
0027 #include <asm/hardware/cache-l2x0.h>
0028 #include <asm/firmware.h>
0029 #include <asm/mcpm.h>
0030 #include <asm/smp_scu.h>
0031 #include <asm/suspend.h>
0032 
0033 #include "common.h"
0034 #include "smc.h"
0035 
0036 #define REG_TABLE_END (-1U)
0037 
0038 #define EXYNOS5420_CPU_STATE    0x28
0039 
0040 /**
0041  * struct exynos_wkup_irq - PMU IRQ to mask mapping
0042  * @hwirq: Hardware IRQ signal of the PMU
0043  * @mask: Mask in PMU wake-up mask register
0044  */
0045 struct exynos_wkup_irq {
0046     unsigned int hwirq;
0047     u32 mask;
0048 };
0049 
0050 struct exynos_pm_data {
0051     const struct exynos_wkup_irq *wkup_irq;
0052     unsigned int wake_disable_mask;
0053 
0054     void (*pm_prepare)(void);
0055     void (*pm_resume_prepare)(void);
0056     void (*pm_resume)(void);
0057     int (*pm_suspend)(void);
0058     int (*cpu_suspend)(unsigned long);
0059 };
0060 
0061 /* Used only on Exynos542x/5800 */
0062 struct exynos_pm_state {
0063     int cpu_state;
0064     unsigned int pmu_spare3;
0065     void __iomem *sysram_base;
0066     phys_addr_t sysram_phys;
0067     bool secure_firmware;
0068 };
0069 
0070 static const struct exynos_pm_data *pm_data __ro_after_init;
0071 static struct exynos_pm_state pm_state;
0072 
0073 /*
0074  * GIC wake-up support
0075  */
0076 
0077 static u32 exynos_irqwake_intmask = 0xffffffff;
0078 
0079 static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
0080     { 73, BIT(1) }, /* RTC alarm */
0081     { 74, BIT(2) }, /* RTC tick */
0082     { /* sentinel */ },
0083 };
0084 
0085 static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
0086     { 44, BIT(1) }, /* RTC alarm */
0087     { 45, BIT(2) }, /* RTC tick */
0088     { /* sentinel */ },
0089 };
0090 
0091 static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
0092     { 43, BIT(1) }, /* RTC alarm */
0093     { 44, BIT(2) }, /* RTC tick */
0094     { /* sentinel */ },
0095 };
0096 
0097 static u32 exynos_read_eint_wakeup_mask(void)
0098 {
0099     return pmu_raw_readl(EXYNOS_EINT_WAKEUP_MASK);
0100 }
0101 
0102 static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
0103 {
0104     const struct exynos_wkup_irq *wkup_irq;
0105 
0106     if (!pm_data->wkup_irq)
0107         return -ENOENT;
0108     wkup_irq = pm_data->wkup_irq;
0109 
0110     while (wkup_irq->mask) {
0111         if (wkup_irq->hwirq == data->hwirq) {
0112             if (!state)
0113                 exynos_irqwake_intmask |= wkup_irq->mask;
0114             else
0115                 exynos_irqwake_intmask &= ~wkup_irq->mask;
0116             return 0;
0117         }
0118         ++wkup_irq;
0119     }
0120 
0121     return -ENOENT;
0122 }
0123 
0124 static struct irq_chip exynos_pmu_chip = {
0125     .name           = "PMU",
0126     .irq_eoi        = irq_chip_eoi_parent,
0127     .irq_mask       = irq_chip_mask_parent,
0128     .irq_unmask     = irq_chip_unmask_parent,
0129     .irq_retrigger      = irq_chip_retrigger_hierarchy,
0130     .irq_set_wake       = exynos_irq_set_wake,
0131 #ifdef CONFIG_SMP
0132     .irq_set_affinity   = irq_chip_set_affinity_parent,
0133 #endif
0134 };
0135 
0136 static int exynos_pmu_domain_translate(struct irq_domain *d,
0137                        struct irq_fwspec *fwspec,
0138                        unsigned long *hwirq,
0139                        unsigned int *type)
0140 {
0141     if (is_of_node(fwspec->fwnode)) {
0142         if (fwspec->param_count != 3)
0143             return -EINVAL;
0144 
0145         /* No PPI should point to this domain */
0146         if (fwspec->param[0] != 0)
0147             return -EINVAL;
0148 
0149         *hwirq = fwspec->param[1];
0150         *type = fwspec->param[2];
0151         return 0;
0152     }
0153 
0154     return -EINVAL;
0155 }
0156 
0157 static int exynos_pmu_domain_alloc(struct irq_domain *domain,
0158                    unsigned int virq,
0159                    unsigned int nr_irqs, void *data)
0160 {
0161     struct irq_fwspec *fwspec = data;
0162     struct irq_fwspec parent_fwspec;
0163     irq_hw_number_t hwirq;
0164     int i;
0165 
0166     if (fwspec->param_count != 3)
0167         return -EINVAL; /* Not GIC compliant */
0168     if (fwspec->param[0] != 0)
0169         return -EINVAL; /* No PPI should point to this domain */
0170 
0171     hwirq = fwspec->param[1];
0172 
0173     for (i = 0; i < nr_irqs; i++)
0174         irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
0175                           &exynos_pmu_chip, NULL);
0176 
0177     parent_fwspec = *fwspec;
0178     parent_fwspec.fwnode = domain->parent->fwnode;
0179     return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
0180                         &parent_fwspec);
0181 }
0182 
0183 static const struct irq_domain_ops exynos_pmu_domain_ops = {
0184     .translate  = exynos_pmu_domain_translate,
0185     .alloc      = exynos_pmu_domain_alloc,
0186     .free       = irq_domain_free_irqs_common,
0187 };
0188 
0189 static int __init exynos_pmu_irq_init(struct device_node *node,
0190                       struct device_node *parent)
0191 {
0192     struct irq_domain *parent_domain, *domain;
0193 
0194     if (!parent) {
0195         pr_err("%pOF: no parent, giving up\n", node);
0196         return -ENODEV;
0197     }
0198 
0199     parent_domain = irq_find_host(parent);
0200     if (!parent_domain) {
0201         pr_err("%pOF: unable to obtain parent domain\n", node);
0202         return -ENXIO;
0203     }
0204 
0205     pmu_base_addr = of_iomap(node, 0);
0206 
0207     if (!pmu_base_addr) {
0208         pr_err("%pOF: failed to find exynos pmu register\n", node);
0209         return -ENOMEM;
0210     }
0211 
0212     domain = irq_domain_add_hierarchy(parent_domain, 0, 0,
0213                       node, &exynos_pmu_domain_ops,
0214                       NULL);
0215     if (!domain) {
0216         iounmap(pmu_base_addr);
0217         pmu_base_addr = NULL;
0218         return -ENOMEM;
0219     }
0220 
0221     /*
0222      * Clear the OF_POPULATED flag set in of_irq_init so that
0223      * later the Exynos PMU platform device won't be skipped.
0224      */
0225     of_node_clear_flag(node, OF_POPULATED);
0226 
0227     return 0;
0228 }
0229 
0230 #define EXYNOS_PMU_IRQ(symbol, name)    IRQCHIP_DECLARE(symbol, name, exynos_pmu_irq_init)
0231 
0232 EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
0233 EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
0234 EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
0235 EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
0236 EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
0237 
0238 static int exynos_cpu_do_idle(void)
0239 {
0240     /* issue the standby signal into the pm unit. */
0241     cpu_do_idle();
0242 
0243     pr_info("Failed to suspend the system\n");
0244     return 1; /* Aborting suspend */
0245 }
0246 static void exynos_flush_cache_all(void)
0247 {
0248     flush_cache_all();
0249     outer_flush_all();
0250 }
0251 
0252 static int exynos_cpu_suspend(unsigned long arg)
0253 {
0254     exynos_flush_cache_all();
0255     return exynos_cpu_do_idle();
0256 }
0257 
0258 static int exynos3250_cpu_suspend(unsigned long arg)
0259 {
0260     flush_cache_all();
0261     return exynos_cpu_do_idle();
0262 }
0263 
0264 static int exynos5420_cpu_suspend(unsigned long arg)
0265 {
0266     /* MCPM works with HW CPU identifiers */
0267     unsigned int mpidr = read_cpuid_mpidr();
0268     unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
0269     unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
0270 
0271     if (IS_ENABLED(CONFIG_EXYNOS_MCPM)) {
0272         mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
0273         mcpm_cpu_suspend();
0274     }
0275 
0276     pr_info("Failed to suspend the system\n");
0277 
0278     /* return value != 0 means failure */
0279     return 1;
0280 }
0281 
0282 static void exynos_pm_set_wakeup_mask(void)
0283 {
0284     /*
0285      * Set wake-up mask registers
0286      * EXYNOS_EINT_WAKEUP_MASK is set by pinctrl driver in late suspend.
0287      */
0288     pmu_raw_writel(exynos_irqwake_intmask & ~BIT(31), S5P_WAKEUP_MASK);
0289 }
0290 
0291 static void exynos_pm_enter_sleep_mode(void)
0292 {
0293     /* Set value of power down register for sleep mode */
0294     exynos_sys_powerdown_conf(SYS_SLEEP);
0295     pmu_raw_writel(EXYNOS_SLEEP_MAGIC, S5P_INFORM1);
0296 }
0297 
0298 static void exynos_pm_prepare(void)
0299 {
0300     exynos_set_delayed_reset_assertion(false);
0301 
0302     /* Set wake-up mask registers */
0303     exynos_pm_set_wakeup_mask();
0304 
0305     exynos_pm_enter_sleep_mode();
0306 
0307     /* ensure at least INFORM0 has the resume address */
0308     pmu_raw_writel(__pa_symbol(exynos_cpu_resume), S5P_INFORM0);
0309 }
0310 
0311 static void exynos3250_pm_prepare(void)
0312 {
0313     unsigned int tmp;
0314 
0315     /* Set wake-up mask registers */
0316     exynos_pm_set_wakeup_mask();
0317 
0318     tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
0319     tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
0320     pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
0321 
0322     exynos_pm_enter_sleep_mode();
0323 
0324     /* ensure at least INFORM0 has the resume address */
0325     pmu_raw_writel(__pa_symbol(exynos_cpu_resume), S5P_INFORM0);
0326 }
0327 
0328 static void exynos5420_pm_prepare(void)
0329 {
0330     unsigned int tmp;
0331 
0332     /* Set wake-up mask registers */
0333     exynos_pm_set_wakeup_mask();
0334 
0335     pm_state.pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
0336     /*
0337      * The cpu state needs to be saved and restored so that the
0338      * secondary CPUs will enter low power start. Though the U-Boot
0339      * is setting the cpu state with low power flag, the kernel
0340      * needs to restore it back in case, the primary cpu fails to
0341      * suspend for any reason.
0342      */
0343     pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
0344                        EXYNOS5420_CPU_STATE);
0345     writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
0346     if (pm_state.secure_firmware)
0347         exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(pm_state.sysram_phys +
0348                              EXYNOS5420_CPU_STATE),
0349                0, 0);
0350 
0351     exynos_pm_enter_sleep_mode();
0352 
0353     /* ensure at least INFORM0 has the resume address */
0354     if (IS_ENABLED(CONFIG_EXYNOS_MCPM))
0355         pmu_raw_writel(__pa_symbol(mcpm_entry_point), S5P_INFORM0);
0356 
0357     tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0));
0358     tmp &= ~EXYNOS_L2_USE_RETENTION;
0359     pmu_raw_writel(tmp, EXYNOS_L2_OPTION(0));
0360 
0361     tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
0362     tmp |= EXYNOS5420_UFS;
0363     pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
0364 
0365     tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
0366     tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE;
0367     pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
0368 
0369     tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
0370     tmp |= EXYNOS5420_EMULATION;
0371     pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
0372 
0373     tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
0374     tmp |= EXYNOS5420_EMULATION;
0375     pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
0376 }
0377 
0378 
0379 static int exynos_pm_suspend(void)
0380 {
0381     exynos_pm_central_suspend();
0382 
0383     /* Setting SEQ_OPTION register */
0384     pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
0385                S5P_CENTRAL_SEQ_OPTION);
0386 
0387     if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
0388         exynos_cpu_save_register();
0389 
0390     return 0;
0391 }
0392 
0393 static int exynos5420_pm_suspend(void)
0394 {
0395     u32 this_cluster;
0396 
0397     exynos_pm_central_suspend();
0398 
0399     /* Setting SEQ_OPTION register */
0400 
0401     this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
0402     if (!this_cluster)
0403         pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
0404                 S5P_CENTRAL_SEQ_OPTION);
0405     else
0406         pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
0407                 S5P_CENTRAL_SEQ_OPTION);
0408     return 0;
0409 }
0410 
0411 static void exynos_pm_resume(void)
0412 {
0413     u32 cpuid = read_cpuid_part();
0414 
0415     if (exynos_pm_central_resume())
0416         goto early_wakeup;
0417 
0418     if (cpuid == ARM_CPU_PART_CORTEX_A9)
0419         exynos_scu_enable();
0420 
0421     if (call_firmware_op(resume) == -ENOSYS
0422         && cpuid == ARM_CPU_PART_CORTEX_A9)
0423         exynos_cpu_restore_register();
0424 
0425 early_wakeup:
0426 
0427     /* Clear SLEEP mode set in INFORM1 */
0428     pmu_raw_writel(0x0, S5P_INFORM1);
0429     exynos_set_delayed_reset_assertion(true);
0430 }
0431 
0432 static void exynos3250_pm_resume(void)
0433 {
0434     u32 cpuid = read_cpuid_part();
0435 
0436     if (exynos_pm_central_resume())
0437         goto early_wakeup;
0438 
0439     pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
0440 
0441     if (call_firmware_op(resume) == -ENOSYS
0442         && cpuid == ARM_CPU_PART_CORTEX_A9)
0443         exynos_cpu_restore_register();
0444 
0445 early_wakeup:
0446 
0447     /* Clear SLEEP mode set in INFORM1 */
0448     pmu_raw_writel(0x0, S5P_INFORM1);
0449 }
0450 
0451 static void exynos5420_prepare_pm_resume(void)
0452 {
0453     unsigned int mpidr, cluster;
0454 
0455     mpidr = read_cpuid_mpidr();
0456     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
0457 
0458     if (IS_ENABLED(CONFIG_EXYNOS_MCPM))
0459         WARN_ON(mcpm_cpu_powered_up());
0460 
0461     if (IS_ENABLED(CONFIG_HW_PERF_EVENTS) && cluster != 0) {
0462         /*
0463          * When system is resumed on the LITTLE/KFC core (cluster 1),
0464          * the DSCR is not properly updated until the power is turned
0465          * on also for the cluster 0. Enable it for a while to
0466          * propagate the SPNIDEN and SPIDEN signals from Secure JTAG
0467          * block and avoid undefined instruction issue on CP14 reset.
0468          */
0469         pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN,
0470                 EXYNOS_COMMON_CONFIGURATION(0));
0471         pmu_raw_writel(0,
0472                 EXYNOS_COMMON_CONFIGURATION(0));
0473     }
0474 }
0475 
0476 static void exynos5420_pm_resume(void)
0477 {
0478     unsigned long tmp;
0479 
0480     /* Restore the CPU0 low power state register */
0481     tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
0482     pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN,
0483                EXYNOS5_ARM_CORE0_SYS_PWR_REG);
0484 
0485     /* Restore the sysram cpu state register */
0486     writel_relaxed(pm_state.cpu_state,
0487                pm_state.sysram_base + EXYNOS5420_CPU_STATE);
0488     if (pm_state.secure_firmware)
0489         exynos_smc(SMC_CMD_REG,
0490                SMC_REG_ID_SFR_W(pm_state.sysram_phys +
0491                         EXYNOS5420_CPU_STATE),
0492                EXYNOS_AFTR_MAGIC, 0);
0493 
0494     pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
0495             S5P_CENTRAL_SEQ_OPTION);
0496 
0497     if (exynos_pm_central_resume())
0498         goto early_wakeup;
0499 
0500     pmu_raw_writel(pm_state.pmu_spare3, S5P_PMU_SPARE3);
0501 
0502 early_wakeup:
0503 
0504     tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
0505     tmp &= ~EXYNOS5420_UFS;
0506     pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
0507 
0508     tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
0509     tmp &= ~EXYNOS5420_EMULATION;
0510     pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
0511 
0512     tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
0513     tmp &= ~EXYNOS5420_EMULATION;
0514     pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
0515 
0516     /* Clear SLEEP mode set in INFORM1 */
0517     pmu_raw_writel(0x0, S5P_INFORM1);
0518 }
0519 
0520 /*
0521  * Suspend Ops
0522  */
0523 
0524 static int exynos_suspend_enter(suspend_state_t state)
0525 {
0526     u32 eint_wakeup_mask = exynos_read_eint_wakeup_mask();
0527     int ret;
0528 
0529     pr_debug("%s: suspending the system...\n", __func__);
0530 
0531     pr_debug("%s: wakeup masks: %08x,%08x\n", __func__,
0532           exynos_irqwake_intmask, eint_wakeup_mask);
0533 
0534     if (exynos_irqwake_intmask == -1U
0535         && eint_wakeup_mask == EXYNOS_EINT_WAKEUP_MASK_DISABLED) {
0536         pr_err("%s: No wake-up sources!\n", __func__);
0537         pr_err("%s: Aborting sleep\n", __func__);
0538         return -EINVAL;
0539     }
0540 
0541     if (pm_data->pm_prepare)
0542         pm_data->pm_prepare();
0543     flush_cache_all();
0544 
0545     ret = call_firmware_op(suspend);
0546     if (ret == -ENOSYS)
0547         ret = cpu_suspend(0, pm_data->cpu_suspend);
0548     if (ret)
0549         return ret;
0550 
0551     if (pm_data->pm_resume_prepare)
0552         pm_data->pm_resume_prepare();
0553 
0554     pr_debug("%s: wakeup stat: %08x\n", __func__,
0555             pmu_raw_readl(S5P_WAKEUP_STAT));
0556 
0557     pr_debug("%s: resuming the system...\n", __func__);
0558 
0559     return 0;
0560 }
0561 
0562 static int exynos_suspend_prepare(void)
0563 {
0564     int ret;
0565 
0566     /*
0567      * REVISIT: It would be better if struct platform_suspend_ops
0568      * .prepare handler get the suspend_state_t as a parameter to
0569      * avoid hard-coding the suspend to mem state. It's safe to do
0570      * it now only because the suspend_valid_only_mem function is
0571      * used as the .valid callback used to check if a given state
0572      * is supported by the platform anyways.
0573      */
0574     ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
0575     if (ret) {
0576         pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
0577         return ret;
0578     }
0579 
0580     return 0;
0581 }
0582 
0583 static void exynos_suspend_finish(void)
0584 {
0585     int ret;
0586 
0587     ret = regulator_suspend_finish();
0588     if (ret)
0589         pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
0590 }
0591 
0592 static const struct platform_suspend_ops exynos_suspend_ops = {
0593     .enter      = exynos_suspend_enter,
0594     .prepare    = exynos_suspend_prepare,
0595     .finish     = exynos_suspend_finish,
0596     .valid      = suspend_valid_only_mem,
0597 };
0598 
0599 static const struct exynos_pm_data exynos3250_pm_data = {
0600     .wkup_irq   = exynos3250_wkup_irq,
0601     .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
0602     .pm_suspend = exynos_pm_suspend,
0603     .pm_resume  = exynos3250_pm_resume,
0604     .pm_prepare = exynos3250_pm_prepare,
0605     .cpu_suspend    = exynos3250_cpu_suspend,
0606 };
0607 
0608 static const struct exynos_pm_data exynos4_pm_data = {
0609     .wkup_irq   = exynos4_wkup_irq,
0610     .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
0611     .pm_suspend = exynos_pm_suspend,
0612     .pm_resume  = exynos_pm_resume,
0613     .pm_prepare = exynos_pm_prepare,
0614     .cpu_suspend    = exynos_cpu_suspend,
0615 };
0616 
0617 static const struct exynos_pm_data exynos5250_pm_data = {
0618     .wkup_irq   = exynos5250_wkup_irq,
0619     .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
0620     .pm_suspend = exynos_pm_suspend,
0621     .pm_resume  = exynos_pm_resume,
0622     .pm_prepare = exynos_pm_prepare,
0623     .cpu_suspend    = exynos_cpu_suspend,
0624 };
0625 
0626 static const struct exynos_pm_data exynos5420_pm_data = {
0627     .wkup_irq   = exynos5250_wkup_irq,
0628     .wake_disable_mask = (0x7F << 7) | (0x1F << 1),
0629     .pm_resume_prepare = exynos5420_prepare_pm_resume,
0630     .pm_resume  = exynos5420_pm_resume,
0631     .pm_suspend = exynos5420_pm_suspend,
0632     .pm_prepare = exynos5420_pm_prepare,
0633     .cpu_suspend    = exynos5420_cpu_suspend,
0634 };
0635 
0636 static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
0637     {
0638         .compatible = "samsung,exynos3250-pmu",
0639         .data = &exynos3250_pm_data,
0640     }, {
0641         .compatible = "samsung,exynos4210-pmu",
0642         .data = &exynos4_pm_data,
0643     }, {
0644         .compatible = "samsung,exynos4412-pmu",
0645         .data = &exynos4_pm_data,
0646     }, {
0647         .compatible = "samsung,exynos5250-pmu",
0648         .data = &exynos5250_pm_data,
0649     }, {
0650         .compatible = "samsung,exynos5420-pmu",
0651         .data = &exynos5420_pm_data,
0652     },
0653     { /*sentinel*/ },
0654 };
0655 
0656 static struct syscore_ops exynos_pm_syscore_ops;
0657 
0658 void __init exynos_pm_init(void)
0659 {
0660     const struct of_device_id *match;
0661     struct device_node *np;
0662     u32 tmp;
0663 
0664     np = of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
0665     if (!np) {
0666         pr_err("Failed to find PMU node\n");
0667         return;
0668     }
0669 
0670     if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
0671         pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
0672         of_node_put(np);
0673         return;
0674     }
0675     of_node_put(np);
0676 
0677     pm_data = (const struct exynos_pm_data *) match->data;
0678 
0679     /* All wakeup disable */
0680     tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
0681     tmp |= pm_data->wake_disable_mask;
0682     pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
0683 
0684     exynos_pm_syscore_ops.suspend   = pm_data->pm_suspend;
0685     exynos_pm_syscore_ops.resume    = pm_data->pm_resume;
0686 
0687     register_syscore_ops(&exynos_pm_syscore_ops);
0688     suspend_set_ops(&exynos_suspend_ops);
0689 
0690     /*
0691      * Applicable as of now only to Exynos542x. If booted under secure
0692      * firmware, the non-secure region of sysram should be used.
0693      */
0694     if (exynos_secure_firmware_available()) {
0695         pm_state.sysram_phys = sysram_base_phys;
0696         pm_state.sysram_base = sysram_ns_base_addr;
0697         pm_state.secure_firmware = true;
0698     } else {
0699         pm_state.sysram_base = sysram_base_addr;
0700     }
0701 }