0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/init.h>
0026 #include <linux/io.h>
0027 #include <linux/suspend.h>
0028 #include <linux/errno.h>
0029 #include <linux/time.h>
0030
0031 #include <mach/hardware.h>
0032 #include <asm/memory.h>
0033 #include <asm/suspend.h>
0034 #include <asm/mach/time.h>
0035
0036 extern int sa1100_finish_suspend(unsigned long);
0037
0038 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
0039 #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
0040
0041
0042
0043
0044
0045
0046 enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
0047 SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
0048
0049 SLEEP_SAVE_Ser1SDCR0,
0050
0051 SLEEP_SAVE_COUNT
0052 };
0053
0054
0055 static int sa11x0_pm_enter(suspend_state_t state)
0056 {
0057 unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
0058
0059 gpio = GPLR;
0060
0061
0062 SAVE(GPDR);
0063 SAVE(GAFR);
0064
0065 SAVE(PPDR);
0066 SAVE(PPSR);
0067 SAVE(PPAR);
0068 SAVE(PSDR);
0069
0070 SAVE(Ser1SDCR0);
0071
0072
0073 RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
0074
0075
0076 PSPR = __pa_symbol(cpu_resume);
0077
0078
0079 cpu_suspend(0, sa1100_finish_suspend);
0080
0081
0082
0083
0084 RCSR = RCSR_SMR;
0085 PSPR = 0;
0086
0087
0088
0089
0090
0091 ICLR = 0;
0092 ICCR = 1;
0093 ICMR = 0;
0094
0095
0096 RESTORE(GPDR);
0097 RESTORE(GAFR);
0098
0099 RESTORE(PPDR);
0100 RESTORE(PPSR);
0101 RESTORE(PPAR);
0102 RESTORE(PSDR);
0103
0104 RESTORE(Ser1SDCR0);
0105
0106 GPSR = gpio;
0107 GPCR = ~gpio;
0108
0109
0110
0111
0112 PSSR = PSSR_PH;
0113
0114 return 0;
0115 }
0116
0117 static const struct platform_suspend_ops sa11x0_pm_ops = {
0118 .enter = sa11x0_pm_enter,
0119 .valid = suspend_valid_only_mem,
0120 };
0121
0122 int __init sa11x0_pm_init(void)
0123 {
0124 suspend_set_ops(&sa11x0_pm_ops);
0125 return 0;
0126 }