1 /* linux/arch/arm/mach-s5pv210/pm.c
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * S5PV210 - Power Management support
8 * Based on arch/arm/mach-s3c2410/pm.c
9 * Copyright (c) 2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
17 #include <linux/init.h>
18 #include <linux/suspend.h>
19 #include <linux/syscore_ops.h>
25 #include <mach/regs-irq.h>
26 #include <mach/regs-clock.h>
28 static struct sleep_save s5pv210_core_save
[] = {
30 SAVE_ITEM(S5P_MDNIE_SEL
),
33 static int s5pv210_cpu_suspend(unsigned long arg
)
37 /* issue the standby signal into the pm unit. Note, we
38 * issue a write-buffer drain just in case */
45 "mcr p15, 0, %0, c7, c10, 5\n\t"
46 "mcr p15, 0, %0, c7, c10, 4\n\t"
49 pr_info("Failed to suspend the system\n");
50 return 1; /* Aborting suspend */
53 static void s5pv210_pm_prepare(void)
57 /* ensure at least INFORM0 has the resume address */
58 __raw_writel(virt_to_phys(s3c_cpu_resume
), S5P_INFORM0
);
60 tmp
= __raw_readl(S5P_SLEEP_CFG
);
61 tmp
&= ~(S5P_SLEEP_CFG_OSC_EN
| S5P_SLEEP_CFG_USBOSC_EN
);
62 __raw_writel(tmp
, S5P_SLEEP_CFG
);
64 /* WFI for SLEEP mode configuration by SYSCON */
65 tmp
= __raw_readl(S5P_PWR_CFG
);
66 tmp
&= S5P_CFG_WFI_CLEAN
;
67 tmp
|= S5P_CFG_WFI_SLEEP
;
68 __raw_writel(tmp
, S5P_PWR_CFG
);
70 /* SYSCON interrupt handling disable */
71 tmp
= __raw_readl(S5P_OTHERS
);
72 tmp
|= S5P_OTHER_SYSC_INTOFF
;
73 __raw_writel(tmp
, S5P_OTHERS
);
75 s3c_pm_do_save(s5pv210_core_save
, ARRAY_SIZE(s5pv210_core_save
));
78 static void s5pv210_pm_resume(void)
82 tmp
= __raw_readl(S5P_OTHERS
);
83 tmp
|= (S5P_OTHERS_RET_IO
| S5P_OTHERS_RET_CF
|\
84 S5P_OTHERS_RET_MMC
| S5P_OTHERS_RET_UART
);
85 __raw_writel(tmp
, S5P_OTHERS
);
87 s3c_pm_do_restore_core(s5pv210_core_save
, ARRAY_SIZE(s5pv210_core_save
));
90 static struct syscore_ops s5pv210_pm_syscore_ops
= {
91 .resume
= s5pv210_pm_resume
,
94 static __init
int s5pv210_pm_syscore_init(void)
96 register_syscore_ops(&s5pv210_pm_syscore_ops
);
98 pm_cpu_prep
= s5pv210_pm_prepare
;
99 pm_cpu_sleep
= s5pv210_cpu_suspend
;
103 arch_initcall(s5pv210_pm_syscore_init
);