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