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