Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-pnx4008/pm.c
10819 views
1
/*
2
* arch/arm/mach-pnx4008/pm.c
3
*
4
* Power Management driver for PNX4008
5
*
6
* Authors: Vitaly Wool, Dmitry Chigirev <[email protected]>
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/suspend.h>
19
#include <linux/delay.h>
20
#include <linux/clk.h>
21
#include <linux/io.h>
22
#include <linux/slab.h>
23
24
#include <asm/cacheflush.h>
25
26
#include <mach/hardware.h>
27
#include <mach/pm.h>
28
#include <mach/clock.h>
29
30
#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
31
32
static void *saved_sram;
33
34
static struct clk *pll4_clk;
35
36
static inline void pnx4008_standby(void)
37
{
38
void (*pnx4008_cpu_standby_ptr) (void);
39
40
local_irq_disable();
41
local_fiq_disable();
42
43
clk_disable(pll4_clk);
44
45
/*saving portion of SRAM to be used by suspend function. */
46
memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
47
48
/*make sure SRAM copy gets physically written into SDRAM.
49
SDRAM will be placed into self-refresh during power down */
50
flush_cache_all();
51
52
/*copy suspend function into SRAM */
53
memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
54
55
/*do suspend */
56
pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
57
pnx4008_cpu_standby_ptr();
58
59
/*restoring portion of SRAM that was used by suspend function */
60
memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
61
62
clk_enable(pll4_clk);
63
64
local_fiq_enable();
65
local_irq_enable();
66
}
67
68
static inline void pnx4008_suspend(void)
69
{
70
void (*pnx4008_cpu_suspend_ptr) (void);
71
72
local_irq_disable();
73
local_fiq_disable();
74
75
clk_disable(pll4_clk);
76
77
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
78
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
79
80
/*saving portion of SRAM to be used by suspend function. */
81
memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
82
83
/*make sure SRAM copy gets physically written into SDRAM.
84
SDRAM will be placed into self-refresh during power down */
85
flush_cache_all();
86
87
/*copy suspend function into SRAM */
88
memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
89
90
/*do suspend */
91
pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
92
pnx4008_cpu_suspend_ptr();
93
94
/*restoring portion of SRAM that was used by suspend function */
95
memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
96
97
clk_enable(pll4_clk);
98
99
local_fiq_enable();
100
local_irq_enable();
101
}
102
103
static int pnx4008_pm_enter(suspend_state_t state)
104
{
105
switch (state) {
106
case PM_SUSPEND_STANDBY:
107
pnx4008_standby();
108
break;
109
case PM_SUSPEND_MEM:
110
pnx4008_suspend();
111
break;
112
}
113
return 0;
114
}
115
116
static int pnx4008_pm_valid(suspend_state_t state)
117
{
118
return (state == PM_SUSPEND_STANDBY) ||
119
(state == PM_SUSPEND_MEM);
120
}
121
122
static const struct platform_suspend_ops pnx4008_pm_ops = {
123
.enter = pnx4008_pm_enter,
124
.valid = pnx4008_pm_valid,
125
};
126
127
static int __init pnx4008_pm_init(void)
128
{
129
u32 sram_size_to_allocate;
130
131
pll4_clk = clk_get(0, "ck_pll4");
132
if (IS_ERR(pll4_clk)) {
133
printk(KERN_ERR
134
"PM Suspend cannot acquire ARM(PLL4) clock control\n");
135
return PTR_ERR(pll4_clk);
136
}
137
138
if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
139
sram_size_to_allocate = pnx4008_cpu_standby_sz;
140
else
141
sram_size_to_allocate = pnx4008_cpu_suspend_sz;
142
143
saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
144
if (!saved_sram) {
145
printk(KERN_ERR
146
"PM Suspend: cannot allocate memory to save portion of SRAM\n");
147
clk_put(pll4_clk);
148
return -ENOMEM;
149
}
150
151
suspend_set_ops(&pnx4008_pm_ops);
152
return 0;
153
}
154
155
late_initcall(pnx4008_pm_init);
156
157