1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (c) 2006 Simtec Electronics
4 // Ben Dooks <ben@simtec.co.uk>
6 // http://armlinux.simtec.co.uk/.
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/interrupt.h>
11 #include <linux/list.h>
12 #include <linux/timer.h>
13 #include <linux/init.h>
14 #include <linux/device.h>
15 #include <linux/syscore_ops.h>
16 #include <linux/platform_device.h>
19 #include <asm/cacheflush.h>
22 #include <mach/hardware.h>
23 #include <mach/regs-gpio.h>
27 #include <plat/wakeup-mask.h>
30 #include "s3c2412-power.h"
32 extern void s3c2412_sleep_enter(void);
34 static int s3c2412_cpu_suspend(unsigned long arg
)
38 /* set our standby method to sleep */
40 tmp
= __raw_readl(S3C2412_PWRCFG
);
41 tmp
|= S3C2412_PWRCFG_STANDBYWFI_SLEEP
;
42 __raw_writel(tmp
, S3C2412_PWRCFG
);
44 s3c2412_sleep_enter();
46 pr_info("Failed to suspend the system\n");
47 return 1; /* Aborting suspend */
50 /* mapping of interrupts to parts of the wakeup mask */
51 static const struct samsung_wakeup_mask wake_irqs
[] = {
52 { .irq
= IRQ_RTC
, .bit
= S3C2412_PWRCFG_RTC_MASKIRQ
, },
55 static void s3c2412_pm_prepare(void)
57 samsung_sync_wakemask(S3C2412_PWRCFG
,
58 wake_irqs
, ARRAY_SIZE(wake_irqs
));
61 static int s3c2412_pm_add(struct device
*dev
, struct subsys_interface
*sif
)
63 pm_cpu_prep
= s3c2412_pm_prepare
;
64 pm_cpu_sleep
= s3c2412_cpu_suspend
;
69 static struct sleep_save s3c2412_sleep
[] = {
70 SAVE_ITEM(S3C2412_DSC0
),
71 SAVE_ITEM(S3C2412_DSC1
),
72 SAVE_ITEM(S3C2413_GPJDAT
),
73 SAVE_ITEM(S3C2413_GPJCON
),
74 SAVE_ITEM(S3C2413_GPJUP
),
76 /* save the PWRCFG to get back to original sleep method */
78 SAVE_ITEM(S3C2412_PWRCFG
),
80 /* save the sleep configuration anyway, just in case these
81 * get damaged during wakeup */
83 SAVE_ITEM(S3C2412_GPBSLPCON
),
84 SAVE_ITEM(S3C2412_GPCSLPCON
),
85 SAVE_ITEM(S3C2412_GPDSLPCON
),
86 SAVE_ITEM(S3C2412_GPFSLPCON
),
87 SAVE_ITEM(S3C2412_GPGSLPCON
),
88 SAVE_ITEM(S3C2412_GPHSLPCON
),
89 SAVE_ITEM(S3C2413_GPJSLPCON
),
92 static struct subsys_interface s3c2412_pm_interface
= {
94 .subsys
= &s3c2412_subsys
,
95 .add_dev
= s3c2412_pm_add
,
98 static __init
int s3c2412_pm_init(void)
100 return subsys_interface_register(&s3c2412_pm_interface
);
103 arch_initcall(s3c2412_pm_init
);
105 static int s3c2412_pm_suspend(void)
107 s3c_pm_do_save(s3c2412_sleep
, ARRAY_SIZE(s3c2412_sleep
));
111 static void s3c2412_pm_resume(void)
115 tmp
= __raw_readl(S3C2412_PWRCFG
);
116 tmp
&= ~S3C2412_PWRCFG_STANDBYWFI_MASK
;
117 tmp
|= S3C2412_PWRCFG_STANDBYWFI_IDLE
;
118 __raw_writel(tmp
, S3C2412_PWRCFG
);
120 s3c_pm_do_restore(s3c2412_sleep
, ARRAY_SIZE(s3c2412_sleep
));
123 struct syscore_ops s3c2412_pm_syscore_ops
= {
124 .suspend
= s3c2412_pm_suspend
,
125 .resume
= s3c2412_pm_resume
,