aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/common.h5
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c52
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c84
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c14
-rw-r--r--arch/arm/mach-omap2/pm.c9
5 files changed, 47 insertions, 117 deletions
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index d6ba13e1c540..14522d077c88 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -249,7 +249,6 @@ extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
249extern int omap4_finish_suspend(unsigned long cpu_state); 249extern int omap4_finish_suspend(unsigned long cpu_state);
250extern void omap4_cpu_resume(void); 250extern void omap4_cpu_resume(void);
251extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); 251extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
252extern u32 omap4_mpuss_read_prev_context_state(void);
253#else 252#else
254static inline int omap4_enter_lowpower(unsigned int cpu, 253static inline int omap4_enter_lowpower(unsigned int cpu,
255 unsigned int power_state) 254 unsigned int power_state)
@@ -277,10 +276,6 @@ static inline int omap4_finish_suspend(unsigned long cpu_state)
277static inline void omap4_cpu_resume(void) 276static inline void omap4_cpu_resume(void)
278{} 277{}
279 278
280static inline u32 omap4_mpuss_read_prev_context_state(void)
281{
282 return 0;
283}
284#endif 279#endif
285 280
286struct omap_sdrc_params; 281struct omap_sdrc_params;
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 80392fca86c6..cca045c95fbf 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -26,6 +26,7 @@
26#include <linux/cpuidle.h> 26#include <linux/cpuidle.h>
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/cpu_pm.h> 28#include <linux/cpu_pm.h>
29#include <asm/cpuidle.h>
29 30
30#include "powerdomain.h" 31#include "powerdomain.h"
31#include "clockdomain.h" 32#include "clockdomain.h"
@@ -99,11 +100,15 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
99 }, 100 },
100}; 101};
101 102
102/* Private functions */ 103/**
103 104 * omap3_enter_idle - Programs OMAP3 to enter the specified state
104static int __omap3_enter_idle(struct cpuidle_device *dev, 105 * @dev: cpuidle device
105 struct cpuidle_driver *drv, 106 * @drv: cpuidle driver
106 int index) 107 * @index: the index of state to be entered
108 */
109static int omap3_enter_idle(struct cpuidle_device *dev,
110 struct cpuidle_driver *drv,
111 int index)
107{ 112{
108 struct omap3_idle_statedata *cx = &omap3_idle_data[index]; 113 struct omap3_idle_statedata *cx = &omap3_idle_data[index];
109 114
@@ -149,22 +154,6 @@ return_sleep_time:
149} 154}
150 155
151/** 156/**
152 * omap3_enter_idle - Programs OMAP3 to enter the specified state
153 * @dev: cpuidle device
154 * @drv: cpuidle driver
155 * @index: the index of state to be entered
156 *
157 * Called from the CPUidle framework to program the device to the
158 * specified target state selected by the governor.
159 */
160static inline int omap3_enter_idle(struct cpuidle_device *dev,
161 struct cpuidle_driver *drv,
162 int index)
163{
164 return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle);
165}
166
167/**
168 * next_valid_state - Find next valid C-state 157 * next_valid_state - Find next valid C-state
169 * @dev: cpuidle device 158 * @dev: cpuidle device
170 * @drv: cpuidle driver 159 * @drv: cpuidle driver
@@ -271,11 +260,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
271 return ret; 260 return ret;
272} 261}
273 262
274static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
275
276static struct cpuidle_driver omap3_idle_driver = { 263static struct cpuidle_driver omap3_idle_driver = {
277 .name = "omap3_idle", 264 .name = "omap3_idle",
278 .owner = THIS_MODULE, 265 .owner = THIS_MODULE,
279 .states = { 266 .states = {
280 { 267 {
281 .enter = omap3_enter_idle_bm, 268 .enter = omap3_enter_idle_bm,
@@ -348,8 +335,6 @@ static struct cpuidle_driver omap3_idle_driver = {
348 */ 335 */
349int __init omap3_idle_init(void) 336int __init omap3_idle_init(void)
350{ 337{
351 struct cpuidle_device *dev;
352
353 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 338 mpu_pd = pwrdm_lookup("mpu_pwrdm");
354 core_pd = pwrdm_lookup("core_pwrdm"); 339 core_pd = pwrdm_lookup("core_pwrdm");
355 per_pd = pwrdm_lookup("per_pwrdm"); 340 per_pd = pwrdm_lookup("per_pwrdm");
@@ -358,16 +343,5 @@ int __init omap3_idle_init(void)
358 if (!mpu_pd || !core_pd || !per_pd || !cam_pd) 343 if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
359 return -ENODEV; 344 return -ENODEV;
360 345
361 cpuidle_register_driver(&omap3_idle_driver); 346 return cpuidle_register(&omap3_idle_driver, NULL);
362
363 dev = &per_cpu(omap3_idle_dev, smp_processor_id());
364 dev->cpu = 0;
365
366 if (cpuidle_register_device(dev)) {
367 printk(KERN_ERR "%s: CPUidle register device failed\n",
368 __func__);
369 return -EIO;
370 }
371
372 return 0;
373} 347}
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index d639aef0deda..5a286b56205e 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP4 CPU idle Routines 2 * OMAP4+ CPU idle Routines
3 * 3 *
4 * Copyright (C) 2011 Texas Instruments, Inc. 4 * Copyright (C) 2011-2013 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com> 5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * Rajendra Nayak <rnayak@ti.com> 6 * Rajendra Nayak <rnayak@ti.com>
7 * 7 *
@@ -14,8 +14,8 @@
14#include <linux/cpuidle.h> 14#include <linux/cpuidle.h>
15#include <linux/cpu_pm.h> 15#include <linux/cpu_pm.h>
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/clockchips.h>
18 17
18#include <asm/cpuidle.h>
19#include <asm/proc-fns.h> 19#include <asm/proc-fns.h>
20 20
21#include "common.h" 21#include "common.h"
@@ -24,13 +24,13 @@
24#include "clockdomain.h" 24#include "clockdomain.h"
25 25
26/* Machine specific information */ 26/* Machine specific information */
27struct omap4_idle_statedata { 27struct idle_statedata {
28 u32 cpu_state; 28 u32 cpu_state;
29 u32 mpu_logic_state; 29 u32 mpu_logic_state;
30 u32 mpu_state; 30 u32 mpu_state;
31}; 31};
32 32
33static struct omap4_idle_statedata omap4_idle_data[] = { 33static struct idle_statedata omap4_idle_data[] = {
34 { 34 {
35 .cpu_state = PWRDM_POWER_ON, 35 .cpu_state = PWRDM_POWER_ON,
36 .mpu_state = PWRDM_POWER_ON, 36 .mpu_state = PWRDM_POWER_ON,
@@ -53,11 +53,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
53 53
54static atomic_t abort_barrier; 54static atomic_t abort_barrier;
55static bool cpu_done[NR_CPUS]; 55static bool cpu_done[NR_CPUS];
56static struct idle_statedata *state_ptr = &omap4_idle_data[0];
56 57
57/* Private functions */ 58/* Private functions */
58 59
59/** 60/**
60 * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions 61 * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
61 * @dev: cpuidle device 62 * @dev: cpuidle device
62 * @drv: cpuidle driver 63 * @drv: cpuidle driver
63 * @index: the index of state to be entered 64 * @index: the index of state to be entered
@@ -66,7 +67,7 @@ static bool cpu_done[NR_CPUS];
66 * specified low power state selected by the governor. 67 * specified low power state selected by the governor.
67 * Returns the amount of time spent in the low power state. 68 * Returns the amount of time spent in the low power state.
68 */ 69 */
69static int omap4_enter_idle_simple(struct cpuidle_device *dev, 70static int omap_enter_idle_simple(struct cpuidle_device *dev,
70 struct cpuidle_driver *drv, 71 struct cpuidle_driver *drv,
71 int index) 72 int index)
72{ 73{
@@ -77,12 +78,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev,
77 return index; 78 return index;
78} 79}
79 80
80static int omap4_enter_idle_coupled(struct cpuidle_device *dev, 81static int omap_enter_idle_coupled(struct cpuidle_device *dev,
81 struct cpuidle_driver *drv, 82 struct cpuidle_driver *drv,
82 int index) 83 int index)
83{ 84{
84 struct omap4_idle_statedata *cx = &omap4_idle_data[index]; 85 struct idle_statedata *cx = state_ptr + index;
85 int cpu_id = smp_processor_id();
86 86
87 local_fiq_disable(); 87 local_fiq_disable();
88 88
@@ -109,8 +109,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
109 } 109 }
110 } 110 }
111 111
112 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
113
114 /* 112 /*
115 * Call idle CPU PM enter notifier chain so that 113 * Call idle CPU PM enter notifier chain so that
116 * VFP and per CPU interrupt context is saved. 114 * VFP and per CPU interrupt context is saved.
@@ -149,11 +147,10 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
149 * Call idle CPU cluster PM exit notifier chain 147 * Call idle CPU cluster PM exit notifier chain
150 * to restore GIC and wakeupgen context. 148 * to restore GIC and wakeupgen context.
151 */ 149 */
152 if (omap4_mpuss_read_prev_context_state()) 150 if ((cx->mpu_state == PWRDM_POWER_RET) &&
151 (cx->mpu_logic_state == PWRDM_POWER_OFF))
153 cpu_cluster_pm_exit(); 152 cpu_cluster_pm_exit();
154 153
155 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
156
157fail: 154fail:
158 cpuidle_coupled_parallel_barrier(dev, &abort_barrier); 155 cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
159 cpu_done[dev->cpu] = false; 156 cpu_done[dev->cpu] = false;
@@ -163,49 +160,38 @@ fail:
163 return index; 160 return index;
164} 161}
165 162
166/*
167 * For each cpu, setup the broadcast timer because local timers
168 * stops for the states above C1.
169 */
170static void omap_setup_broadcast_timer(void *arg)
171{
172 int cpu = smp_processor_id();
173 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
174}
175
176static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
177
178static struct cpuidle_driver omap4_idle_driver = { 163static struct cpuidle_driver omap4_idle_driver = {
179 .name = "omap4_idle", 164 .name = "omap4_idle",
180 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
181 .en_core_tk_irqen = 1,
182 .states = { 166 .states = {
183 { 167 {
184 /* C1 - CPU0 ON + CPU1 ON + MPU ON */ 168 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
185 .exit_latency = 2 + 2, 169 .exit_latency = 2 + 2,
186 .target_residency = 5, 170 .target_residency = 5,
187 .flags = CPUIDLE_FLAG_TIME_VALID, 171 .flags = CPUIDLE_FLAG_TIME_VALID,
188 .enter = omap4_enter_idle_simple, 172 .enter = omap_enter_idle_simple,
189 .name = "C1", 173 .name = "C1",
190 .desc = "MPUSS ON" 174 .desc = "CPUx ON, MPUSS ON"
191 }, 175 },
192 { 176 {
193 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ 177 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
194 .exit_latency = 328 + 440, 178 .exit_latency = 328 + 440,
195 .target_residency = 960, 179 .target_residency = 960,
196 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, 180 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
197 .enter = omap4_enter_idle_coupled, 181 CPUIDLE_FLAG_TIMER_STOP,
182 .enter = omap_enter_idle_coupled,
198 .name = "C2", 183 .name = "C2",
199 .desc = "MPUSS CSWR", 184 .desc = "CPUx OFF, MPUSS CSWR",
200 }, 185 },
201 { 186 {
202 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ 187 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
203 .exit_latency = 460 + 518, 188 .exit_latency = 460 + 518,
204 .target_residency = 1100, 189 .target_residency = 1100,
205 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, 190 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
206 .enter = omap4_enter_idle_coupled, 191 CPUIDLE_FLAG_TIMER_STOP,
192 .enter = omap_enter_idle_coupled,
207 .name = "C3", 193 .name = "C3",
208 .desc = "MPUSS OSWR", 194 .desc = "CPUx OFF, MPUSS OSWR",
209 }, 195 },
210 }, 196 },
211 .state_count = ARRAY_SIZE(omap4_idle_data), 197 .state_count = ARRAY_SIZE(omap4_idle_data),
@@ -215,16 +201,13 @@ static struct cpuidle_driver omap4_idle_driver = {
215/* Public functions */ 201/* Public functions */
216 202
217/** 203/**
218 * omap4_idle_init - Init routine for OMAP4 idle 204 * omap4_idle_init - Init routine for OMAP4+ idle
219 * 205 *
220 * Registers the OMAP4 specific cpuidle driver to the cpuidle 206 * Registers the OMAP4+ specific cpuidle driver to the cpuidle
221 * framework with the valid set of states. 207 * framework with the valid set of states.
222 */ 208 */
223int __init omap4_idle_init(void) 209int __init omap4_idle_init(void)
224{ 210{
225 struct cpuidle_device *dev;
226 unsigned int cpu_id = 0;
227
228 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 211 mpu_pd = pwrdm_lookup("mpu_pwrdm");
229 cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); 212 cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
230 cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); 213 cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -236,22 +219,5 @@ int __init omap4_idle_init(void)
236 if (!cpu_clkdm[0] || !cpu_clkdm[1]) 219 if (!cpu_clkdm[0] || !cpu_clkdm[1])
237 return -ENODEV; 220 return -ENODEV;
238 221
239 /* Configure the broadcast timer on each cpu */ 222 return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
240 on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
241
242 for_each_cpu(cpu_id, cpu_online_mask) {
243 dev = &per_cpu(omap4_idle_dev, cpu_id);
244 dev->cpu = cpu_id;
245#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
246 dev->coupled_cpus = *cpu_online_mask;
247#endif
248 cpuidle_register_driver(&omap4_idle_driver);
249
250 if (cpuidle_register_device(dev)) {
251 pr_err("%s: CPUidle register failed\n", __func__);
252 return -EIO;
253 }
254 }
255
256 return 0;
257} 223}
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 8bcb64bcdcdb..e80327b6c81f 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -139,20 +139,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
139 } 139 }
140} 140}
141 141
142/**
143 * omap4_mpuss_read_prev_context_state:
144 * Function returns the MPUSS previous context state
145 */
146u32 omap4_mpuss_read_prev_context_state(void)
147{
148 u32 reg;
149
150 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
151 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
152 reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
153 return reg;
154}
155
156/* 142/*
157 * Store the CPU cluster state for L2X0 low power operations. 143 * Store the CPU cluster state for L2X0 low power operations.
158 */ 144 */
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index dec553349ae2..e742118fcfd2 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -264,6 +264,12 @@ static void __init omap4_init_voltages(void)
264 omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); 264 omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
265} 265}
266 266
267static inline void omap_init_cpufreq(void)
268{
269 struct platform_device_info devinfo = { .name = "omap-cpufreq", };
270 platform_device_register_full(&devinfo);
271}
272
267static int __init omap2_common_pm_init(void) 273static int __init omap2_common_pm_init(void)
268{ 274{
269 if (!of_have_populated_dt()) 275 if (!of_have_populated_dt())
@@ -293,6 +299,9 @@ int __init omap2_common_pm_late_init(void)
293 299
294 /* Smartreflex device init */ 300 /* Smartreflex device init */
295 omap_devinit_smartreflex(); 301 omap_devinit_smartreflex();
302
303 /* cpufreq dummy device instantiation */
304 omap_init_cpufreq();
296 } 305 }
297 306
298#ifdef CONFIG_SUSPEND 307#ifdef CONFIG_SUSPEND