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