1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/init.h>
26#include <linux/suspend.h>
27#include <linux/errno.h>
28#include <linux/time.h>
29
30#include <mach/hardware.h>
31#include <asm/memory.h>
32#include <asm/system.h>
33#include <asm/mach/time.h>
34
35extern void sa1100_cpu_suspend(long);
36
37#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
38#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
39
40
41
42
43
44
45enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
46 SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
47
48 SLEEP_SAVE_Ser1SDCR0,
49
50 SLEEP_SAVE_COUNT
51};
52
53
54static int sa11x0_pm_enter(suspend_state_t state)
55{
56 unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
57
58 gpio = GPLR;
59
60
61 SAVE(GPDR);
62 SAVE(GAFR);
63
64 SAVE(PPDR);
65 SAVE(PPSR);
66 SAVE(PPAR);
67 SAVE(PSDR);
68
69 SAVE(Ser1SDCR0);
70
71
72 RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
73
74
75 PSPR = virt_to_phys(cpu_resume);
76
77
78 sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
79
80 cpu_init();
81
82
83
84
85 PSPR = 0;
86
87
88
89
90
91 ICLR = 0;
92 ICCR = 1;
93 ICMR = 0;
94
95
96 RESTORE(GPDR);
97 RESTORE(GAFR);
98
99 RESTORE(PPDR);
100 RESTORE(PPSR);
101 RESTORE(PPAR);
102 RESTORE(PSDR);
103
104 RESTORE(Ser1SDCR0);
105
106 GPSR = gpio;
107 GPCR = ~gpio;
108
109
110
111
112 PSSR = PSSR_PH;
113
114 return 0;
115}
116
117static const struct platform_suspend_ops sa11x0_pm_ops = {
118 .enter = sa11x0_pm_enter,
119 .valid = suspend_valid_only_mem,
120};
121
122static int __init sa11x0_pm_init(void)
123{
124 suspend_set_ops(&sa11x0_pm_ops);
125 return 0;
126}
127
128late_initcall(sa11x0_pm_init);
129