aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pnx4008/pm.c
diff options
context:
space:
mode:
authorVitaly Wool <vwool@ru.mvista.com>2006-05-16 06:54:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-18 11:16:55 -0400
commit78818e477bf785391b02672d053fdbb2e111fb50 (patch)
treed1a43ddfb1b966fe981c10c874bae4faad070f29 /arch/arm/mach-pnx4008/pm.c
parenta5a503038e71a6b7d4bd9e596ac13087274e60c7 (diff)
[ARM] 3466/1: [2/3] Support for Philips PNX4008 platform: chip support
Patch from Vitaly Wool This patch adds basic chip support for PNX4008 ARM platform. It's basically the same as the previous one, but with the rmk's comments taken into account. Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> Signed-off-by: Dmitry Pervushin <dpervushin@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pnx4008/pm.c')
-rw-r--r--arch/arm/mach-pnx4008/pm.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
new file mode 100644
index 000000000000..3649cd3dfc9a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -0,0 +1,184 @@
1/*
2 * arch/arm/mach-pnx4008/pm.c
3 *
4 * Power Management driver for PNX4008
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/pm.h>
15#include <linux/rtc.h>
16#include <linux/sched.h>
17#include <linux/proc_fs.h>
18#include <linux/pm.h>
19#include <linux/delay.h>
20#include <linux/clk.h>
21
22#include <asm/io.h>
23#include <asm/mach-types.h>
24#include <asm/cacheflush.h>
25#include <asm/arch/pm.h>
26#include <asm/arch/clock.h>
27
28#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
29
30static void *saved_sram;
31
32static struct clk *pll4_clk;
33
34static inline void pnx4008_standby(void)
35{
36 void (*pnx4008_cpu_standby_ptr) (void);
37
38 local_irq_disable();
39 local_fiq_disable();
40
41 clk_disable(pll4_clk);
42
43 /*saving portion of SRAM to be used by suspend function. */
44 memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
45
46 /*make sure SRAM copy gets physically written into SDRAM.
47 SDRAM will be placed into self-refresh during power down */
48 flush_cache_all();
49
50 /*copy suspend function into SRAM */
51 memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
52
53 /*do suspend */
54 pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
55 pnx4008_cpu_standby_ptr();
56
57 /*restoring portion of SRAM that was used by suspend function */
58 memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
59
60 clk_enable(pll4_clk);
61
62 local_fiq_enable();
63 local_irq_enable();
64}
65
66static inline void pnx4008_suspend(void)
67{
68 void (*pnx4008_cpu_suspend_ptr) (void);
69
70 local_irq_disable();
71 local_fiq_disable();
72
73 clk_disable(pll4_clk);
74
75 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
76 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
77
78 /*saving portion of SRAM to be used by suspend function. */
79 memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
80
81 /*make sure SRAM copy gets physically written into SDRAM.
82 SDRAM will be placed into self-refresh during power down */
83 flush_cache_all();
84
85 /*copy suspend function into SRAM */
86 memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
87
88 /*do suspend */
89 pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
90 pnx4008_cpu_suspend_ptr();
91
92 /*restoring portion of SRAM that was used by suspend function */
93 memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
94
95 clk_enable(pll4_clk);
96
97 local_fiq_enable();
98 local_irq_enable();
99}
100
101static int pnx4008_pm_enter(suspend_state_t state)
102{
103 switch (state) {
104 case PM_SUSPEND_STANDBY:
105 pnx4008_standby();
106 break;
107 case PM_SUSPEND_MEM:
108 pnx4008_suspend();
109 break;
110 case PM_SUSPEND_DISK:
111 return -ENOTSUPP;
112 default:
113 return -EINVAL;
114 }
115 return 0;
116}
117
118/*
119 * Called after processes are frozen, but before we shut down devices.
120 */
121static int pnx4008_pm_prepare(suspend_state_t state)
122{
123 switch (state) {
124 case PM_SUSPEND_STANDBY:
125 case PM_SUSPEND_MEM:
126 break;
127
128 case PM_SUSPEND_DISK:
129 return -ENOTSUPP;
130 break;
131
132 default:
133 return -EINVAL;
134 break;
135 }
136 return 0;
137}
138
139/*
140 * Called after devices are re-setup, but before processes are thawed.
141 */
142static int pnx4008_pm_finish(suspend_state_t state)
143{
144 return 0;
145}
146
147/*
148 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
149 */
150static struct pm_ops pnx4008_pm_ops = {
151 .prepare = pnx4008_pm_prepare,
152 .enter = pnx4008_pm_enter,
153 .finish = pnx4008_pm_finish,
154};
155
156static int __init pnx4008_pm_init(void)
157{
158 u32 sram_size_to_allocate;
159
160 pll4_clk = clk_get(0, "ck_pll4");
161 if (IS_ERR(pll4_clk)) {
162 printk(KERN_ERR
163 "PM Suspend cannot acquire ARM(PLL4) clock control\n");
164 return PTR_ERR(pll4_clk);
165 }
166
167 if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
168 sram_size_to_allocate = pnx4008_cpu_standby_sz;
169 else
170 sram_size_to_allocate = pnx4008_cpu_suspend_sz;
171
172 saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
173 if (!saved_sram) {
174 printk(KERN_ERR
175 "PM Suspend: cannot allocate memory to save portion of SRAM\n");
176 clk_put(pll4_clk);
177 return -ENOMEM;
178 }
179
180 pm_set_ops(&pnx4008_pm_ops);
181 return 0;
182}
183
184late_initcall(pnx4008_pm_init);