aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/board-rx51.c38
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c298
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c126
-rw-r--r--arch/arm/mach-omap2/pm.h21
4 files changed, 190 insertions, 293 deletions
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 27f01f051dff..2da92a6ba40a 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -59,25 +59,24 @@ static struct platform_device leds_gpio = {
59}; 59};
60 60
61/* 61/*
62 * cpuidle C-states definition override from the default values. 62 * cpuidle C-states definition for rx51.
63 * The 'exit_latency' field is the sum of sleep and wake-up latencies. 63 *
64 */ 64 * The 'exit_latency' field is the sum of sleep
65static struct cpuidle_params rx51_cpuidle_params[] = { 65 * and wake-up latencies.
66 /* C1 */ 66
67 {110 + 162, 5 , 1}, 67 ---------------------------------------------
68 /* C2 */ 68 | state | exit_latency | target_residency |
69 {106 + 180, 309, 1}, 69 ---------------------------------------------
70 /* C3 */ 70 | C1 | 110 + 162 | 5 |
71 {107 + 410, 46057, 0}, 71 | C2 | 106 + 180 | 309 |
72 /* C4 */ 72 | C3 | 107 + 410 | 46057 |
73 {121 + 3374, 46057, 0}, 73 | C4 | 121 + 3374 | 46057 |
74 /* C5 */ 74 | C5 | 855 + 1146 | 46057 |
75 {855 + 1146, 46057, 1}, 75 | C6 | 7580 + 4134 | 484329 |
76 /* C6 */ 76 | C7 | 7505 + 15274 | 484329 |
77 {7580 + 4134, 484329, 0}, 77 ---------------------------------------------
78 /* C7 */ 78
79 {7505 + 15274, 484329, 1}, 79*/
80};
81 80
82extern void __init rx51_peripherals_init(void); 81extern void __init rx51_peripherals_init(void);
83 82
@@ -98,7 +97,6 @@ static void __init rx51_init(void)
98 struct omap_sdrc_params *sdrc_params; 97 struct omap_sdrc_params *sdrc_params;
99 98
100 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); 99 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
101 omap3_pm_init_cpuidle(rx51_cpuidle_params);
102 omap_serial_init(); 100 omap_serial_init();
103 101
104 sdrc_params = nokia_get_sdram_timings(); 102 sdrc_params = nokia_get_sdram_timings();
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 535866489ce3..207bc1c7759f 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -38,40 +38,44 @@
38 38
39#ifdef CONFIG_CPU_IDLE 39#ifdef CONFIG_CPU_IDLE
40 40
41/*
42 * The latencies/thresholds for various C states have
43 * to be configured from the respective board files.
44 * These are some default values (which might not provide
45 * the best power savings) used on boards which do not
46 * pass these details from the board file.
47 */
48static struct cpuidle_params cpuidle_params_table[] = {
49 /* C1 */
50 {2 + 2, 5, 1},
51 /* C2 */
52 {10 + 10, 30, 1},
53 /* C3 */
54 {50 + 50, 300, 1},
55 /* C4 */
56 {1500 + 1800, 4000, 1},
57 /* C5 */
58 {2500 + 7500, 12000, 1},
59 /* C6 */
60 {3000 + 8500, 15000, 1},
61 /* C7 */
62 {10000 + 30000, 300000, 1},
63};
64#define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
65
66/* Mach specific information to be recorded in the C-state driver_data */ 41/* Mach specific information to be recorded in the C-state driver_data */
67struct omap3_idle_statedata { 42struct omap3_idle_statedata {
68 u32 mpu_state; 43 u32 mpu_state;
69 u32 core_state; 44 u32 core_state;
70 u8 valid;
71}; 45};
72struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES];
73 46
74struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; 47static struct omap3_idle_statedata omap3_idle_data[] = {
48 {
49 .mpu_state = PWRDM_POWER_ON,
50 .core_state = PWRDM_POWER_ON,
51 },
52 {
53 .mpu_state = PWRDM_POWER_ON,
54 .core_state = PWRDM_POWER_ON,
55 },
56 {
57 .mpu_state = PWRDM_POWER_RET,
58 .core_state = PWRDM_POWER_ON,
59 },
60 {
61 .mpu_state = PWRDM_POWER_OFF,
62 .core_state = PWRDM_POWER_ON,
63 },
64 {
65 .mpu_state = PWRDM_POWER_RET,
66 .core_state = PWRDM_POWER_RET,
67 },
68 {
69 .mpu_state = PWRDM_POWER_OFF,
70 .core_state = PWRDM_POWER_RET,
71 },
72 {
73 .mpu_state = PWRDM_POWER_OFF,
74 .core_state = PWRDM_POWER_OFF,
75 },
76};
77
78static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
75 79
76static int _cpuidle_allow_idle(struct powerdomain *pwrdm, 80static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
77 struct clockdomain *clkdm) 81 struct clockdomain *clkdm)
@@ -91,8 +95,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
91 struct cpuidle_driver *drv, 95 struct cpuidle_driver *drv,
92 int index) 96 int index)
93{ 97{
94 struct omap3_idle_statedata *cx = 98 struct omap3_idle_statedata *cx = &omap3_idle_data[index];
95 cpuidle_get_statedata(&dev->states_usage[index]);
96 u32 mpu_state = cx->mpu_state, core_state = cx->core_state; 99 u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
97 100
98 local_fiq_disable(); 101 local_fiq_disable();
@@ -169,14 +172,12 @@ static inline int omap3_enter_idle(struct cpuidle_device *dev,
169 * if it satisfies the enable_off_mode condition. 172 * if it satisfies the enable_off_mode condition.
170 */ 173 */
171static int next_valid_state(struct cpuidle_device *dev, 174static int next_valid_state(struct cpuidle_device *dev,
172 struct cpuidle_driver *drv, 175 struct cpuidle_driver *drv, int index)
173 int index)
174{ 176{
175 struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; 177 struct omap3_idle_statedata *cx = &omap3_idle_data[index];
176 struct cpuidle_state *curr = &drv->states[index];
177 struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
178 u32 mpu_deepest_state = PWRDM_POWER_RET; 178 u32 mpu_deepest_state = PWRDM_POWER_RET;
179 u32 core_deepest_state = PWRDM_POWER_RET; 179 u32 core_deepest_state = PWRDM_POWER_RET;
180 int idx;
180 int next_index = -1; 181 int next_index = -1;
181 182
182 if (enable_off_mode) { 183 if (enable_off_mode) {
@@ -191,45 +192,29 @@ static int next_valid_state(struct cpuidle_device *dev,
191 } 192 }
192 193
193 /* Check if current state is valid */ 194 /* Check if current state is valid */
194 if ((cx->valid) && 195 if ((cx->mpu_state >= mpu_deepest_state) &&
195 (cx->mpu_state >= mpu_deepest_state) && 196 (cx->core_state >= core_deepest_state))
196 (cx->core_state >= core_deepest_state)) {
197 return index; 197 return index;
198 } else {
199 int idx = OMAP3_NUM_STATES - 1;
200
201 /* Reach the current state starting at highest C-state */
202 for (; idx >= 0; idx--) {
203 if (&drv->states[idx] == curr) {
204 next_index = idx;
205 break;
206 }
207 }
208
209 /* Should never hit this condition */
210 WARN_ON(next_index == -1);
211 198
212 /* 199 /*
213 * Drop to next valid state. 200 * Drop to next valid state.
214 * Start search from the next (lower) state. 201 * Start search from the next (lower) state.
215 */ 202 */
216 idx--; 203 for (idx = index - 1; idx >= 0; idx--) {
217 for (; idx >= 0; idx--) { 204 cx = &omap3_idle_data[idx];
218 cx = cpuidle_get_statedata(&dev->states_usage[idx]); 205 if ((cx->mpu_state >= mpu_deepest_state) &&
219 if ((cx->valid) && 206 (cx->core_state >= core_deepest_state)) {
220 (cx->mpu_state >= mpu_deepest_state) && 207 next_index = idx;
221 (cx->core_state >= core_deepest_state)) { 208 break;
222 next_index = idx;
223 break;
224 }
225 } 209 }
226 /*
227 * C1 is always valid.
228 * So, no need to check for 'next_index == -1' outside
229 * this loop.
230 */
231 } 210 }
232 211
212 /*
213 * C1 is always valid.
214 * So, no need to check for 'next_index == -1' outside
215 * this loop.
216 */
217
233 return next_index; 218 return next_index;
234} 219}
235 220
@@ -273,7 +258,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
273 * Prevent PER off if CORE is not in retention or off as this 258 * Prevent PER off if CORE is not in retention or off as this
274 * would disable PER wakeups completely. 259 * would disable PER wakeups completely.
275 */ 260 */
276 cx = cpuidle_get_statedata(&dev->states_usage[index]); 261 cx = &omap3_idle_data[index];
277 core_next_state = cx->core_state; 262 core_next_state = cx->core_state;
278 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); 263 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
279 if ((per_next_state == PWRDM_POWER_OFF) && 264 if ((per_next_state == PWRDM_POWER_OFF) &&
@@ -298,57 +283,71 @@ select_state:
298 283
299DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 284DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
300 285
301void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
302{
303 int i;
304
305 if (!cpuidle_board_params)
306 return;
307
308 for (i = 0; i < OMAP3_NUM_STATES; i++) {
309 cpuidle_params_table[i].valid = cpuidle_board_params[i].valid;
310 cpuidle_params_table[i].exit_latency =
311 cpuidle_board_params[i].exit_latency;
312 cpuidle_params_table[i].target_residency =
313 cpuidle_board_params[i].target_residency;
314 }
315 return;
316}
317
318struct cpuidle_driver omap3_idle_driver = { 286struct cpuidle_driver omap3_idle_driver = {
319 .name = "omap3_idle", 287 .name = "omap3_idle",
320 .owner = THIS_MODULE, 288 .owner = THIS_MODULE,
289 .states = {
290 {
291 .enter = omap3_enter_idle,
292 .exit_latency = 2 + 2,
293 .target_residency = 5,
294 .flags = CPUIDLE_FLAG_TIME_VALID,
295 .name = "C1",
296 .desc = "MPU ON + CORE ON",
297 },
298 {
299 .enter = omap3_enter_idle_bm,
300 .exit_latency = 10 + 10,
301 .target_residency = 30,
302 .flags = CPUIDLE_FLAG_TIME_VALID,
303 .name = "C2",
304 .desc = "MPU ON + CORE ON",
305 },
306 {
307 .enter = omap3_enter_idle_bm,
308 .exit_latency = 50 + 50,
309 .target_residency = 300,
310 .flags = CPUIDLE_FLAG_TIME_VALID,
311 .name = "C3",
312 .desc = "MPU RET + CORE ON",
313 },
314 {
315 .enter = omap3_enter_idle_bm,
316 .exit_latency = 1500 + 1800,
317 .target_residency = 4000,
318 .flags = CPUIDLE_FLAG_TIME_VALID,
319 .name = "C4",
320 .desc = "MPU OFF + CORE ON",
321 },
322 {
323 .enter = omap3_enter_idle_bm,
324 .exit_latency = 2500 + 7500,
325 .target_residency = 12000,
326 .flags = CPUIDLE_FLAG_TIME_VALID,
327 .name = "C5",
328 .desc = "MPU RET + CORE RET",
329 },
330 {
331 .enter = omap3_enter_idle_bm,
332 .exit_latency = 3000 + 8500,
333 .target_residency = 15000,
334 .flags = CPUIDLE_FLAG_TIME_VALID,
335 .name = "C6",
336 .desc = "MPU OFF + CORE RET",
337 },
338 {
339 .enter = omap3_enter_idle_bm,
340 .exit_latency = 10000 + 30000,
341 .target_residency = 30000,
342 .flags = CPUIDLE_FLAG_TIME_VALID,
343 .name = "C7",
344 .desc = "MPU OFF + CORE OFF",
345 },
346 },
347 .state_count = ARRAY_SIZE(omap3_idle_data),
348 .safe_state_index = 0,
321}; 349};
322 350
323/* Helper to fill the C-state common data*/
324static inline void _fill_cstate(struct cpuidle_driver *drv,
325 int idx, const char *descr)
326{
327 struct cpuidle_state *state = &drv->states[idx];
328
329 state->exit_latency = cpuidle_params_table[idx].exit_latency;
330 state->target_residency = cpuidle_params_table[idx].target_residency;
331 state->flags = CPUIDLE_FLAG_TIME_VALID;
332 state->enter = omap3_enter_idle_bm;
333 sprintf(state->name, "C%d", idx + 1);
334 strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
335
336}
337
338/* Helper to register the driver_data */
339static inline struct omap3_idle_statedata *_fill_cstate_usage(
340 struct cpuidle_device *dev,
341 int idx)
342{
343 struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
344 struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
345
346 cx->valid = cpuidle_params_table[idx].valid;
347 cpuidle_set_statedata(state_usage, cx);
348
349 return cx;
350}
351
352/** 351/**
353 * omap3_idle_init - Init routine for OMAP3 idle 352 * omap3_idle_init - Init routine for OMAP3 idle
354 * 353 *
@@ -358,77 +357,20 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
358int __init omap3_idle_init(void) 357int __init omap3_idle_init(void)
359{ 358{
360 struct cpuidle_device *dev; 359 struct cpuidle_device *dev;
361 struct cpuidle_driver *drv = &omap3_idle_driver;
362 struct omap3_idle_statedata *cx;
363 360
364 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 361 mpu_pd = pwrdm_lookup("mpu_pwrdm");
365 core_pd = pwrdm_lookup("core_pwrdm"); 362 core_pd = pwrdm_lookup("core_pwrdm");
366 per_pd = pwrdm_lookup("per_pwrdm"); 363 per_pd = pwrdm_lookup("per_pwrdm");
367 cam_pd = pwrdm_lookup("cam_pwrdm"); 364 cam_pd = pwrdm_lookup("cam_pwrdm");
368 365
366 if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
367 return -ENODEV;
369 368
370 drv->safe_state_index = -1;
371 dev = &per_cpu(omap3_idle_dev, smp_processor_id());
372
373 /* C1 . MPU WFI + Core active */
374 _fill_cstate(drv, 0, "MPU ON + CORE ON");
375 (&drv->states[0])->enter = omap3_enter_idle;
376 drv->safe_state_index = 0;
377 cx = _fill_cstate_usage(dev, 0);
378 cx->valid = 1; /* C1 is always valid */
379 cx->mpu_state = PWRDM_POWER_ON;
380 cx->core_state = PWRDM_POWER_ON;
381
382 /* C2 . MPU WFI + Core inactive */
383 _fill_cstate(drv, 1, "MPU ON + CORE ON");
384 cx = _fill_cstate_usage(dev, 1);
385 cx->mpu_state = PWRDM_POWER_ON;
386 cx->core_state = PWRDM_POWER_ON;
387
388 /* C3 . MPU CSWR + Core inactive */
389 _fill_cstate(drv, 2, "MPU RET + CORE ON");
390 cx = _fill_cstate_usage(dev, 2);
391 cx->mpu_state = PWRDM_POWER_RET;
392 cx->core_state = PWRDM_POWER_ON;
393
394 /* C4 . MPU OFF + Core inactive */
395 _fill_cstate(drv, 3, "MPU OFF + CORE ON");
396 cx = _fill_cstate_usage(dev, 3);
397 cx->mpu_state = PWRDM_POWER_OFF;
398 cx->core_state = PWRDM_POWER_ON;
399
400 /* C5 . MPU RET + Core RET */
401 _fill_cstate(drv, 4, "MPU RET + CORE RET");
402 cx = _fill_cstate_usage(dev, 4);
403 cx->mpu_state = PWRDM_POWER_RET;
404 cx->core_state = PWRDM_POWER_RET;
405
406 /* C6 . MPU OFF + Core RET */
407 _fill_cstate(drv, 5, "MPU OFF + CORE RET");
408 cx = _fill_cstate_usage(dev, 5);
409 cx->mpu_state = PWRDM_POWER_OFF;
410 cx->core_state = PWRDM_POWER_RET;
411
412 /* C7 . MPU OFF + Core OFF */
413 _fill_cstate(drv, 6, "MPU OFF + CORE OFF");
414 cx = _fill_cstate_usage(dev, 6);
415 /*
416 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
417 * enable OFF mode in a stable form for previous revisions.
418 * We disable C7 state as a result.
419 */
420 if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
421 cx->valid = 0;
422 pr_warn("%s: core off state C7 disabled due to i583\n",
423 __func__);
424 }
425 cx->mpu_state = PWRDM_POWER_OFF;
426 cx->core_state = PWRDM_POWER_OFF;
427
428 drv->state_count = OMAP3_NUM_STATES;
429 cpuidle_register_driver(&omap3_idle_driver); 369 cpuidle_register_driver(&omap3_idle_driver);
430 370
431 dev->state_count = OMAP3_NUM_STATES; 371 dev = &per_cpu(omap3_idle_dev, smp_processor_id());
372 dev->cpu = 0;
373
432 if (cpuidle_register_device(dev)) { 374 if (cpuidle_register_device(dev)) {
433 printk(KERN_ERR "%s: CPUidle register device failed\n", 375 printk(KERN_ERR "%s: CPUidle register device failed\n",
434 __func__); 376 __func__);
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index f386cbe9c889..be1617ca84bd 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -24,26 +24,31 @@
24 24
25#ifdef CONFIG_CPU_IDLE 25#ifdef CONFIG_CPU_IDLE
26 26
27/* Machine specific information to be recorded in the C-state driver_data */ 27/* Machine specific information */
28struct omap4_idle_statedata { 28struct omap4_idle_statedata {
29 u32 cpu_state; 29 u32 cpu_state;
30 u32 mpu_logic_state; 30 u32 mpu_logic_state;
31 u32 mpu_state; 31 u32 mpu_state;
32 u8 valid;
33}; 32};
34 33
35static struct cpuidle_params cpuidle_params_table[] = { 34static struct omap4_idle_statedata omap4_idle_data[] = {
36 /* C1 - CPU0 ON + CPU1 ON + MPU ON */ 35 {
37 {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, 36 .cpu_state = PWRDM_POWER_ON,
38 /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ 37 .mpu_state = PWRDM_POWER_ON,
39 {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, 38 .mpu_logic_state = PWRDM_POWER_RET,
40 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ 39 },
41 {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, 40 {
41 .cpu_state = PWRDM_POWER_OFF,
42 .mpu_state = PWRDM_POWER_RET,
43 .mpu_logic_state = PWRDM_POWER_RET,
44 },
45 {
46 .cpu_state = PWRDM_POWER_OFF,
47 .mpu_state = PWRDM_POWER_RET,
48 .mpu_logic_state = PWRDM_POWER_OFF,
49 },
42}; 50};
43 51
44#define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
45
46struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES];
47static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; 52static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd;
48 53
49/** 54/**
@@ -60,8 +65,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
60 struct cpuidle_driver *drv, 65 struct cpuidle_driver *drv,
61 int index) 66 int index)
62{ 67{
63 struct omap4_idle_statedata *cx = 68 struct omap4_idle_statedata *cx = &omap4_idle_data[index];
64 cpuidle_get_statedata(&dev->states_usage[index]);
65 u32 cpu1_state; 69 u32 cpu1_state;
66 int cpu_id = smp_processor_id(); 70 int cpu_id = smp_processor_id();
67 71
@@ -78,7 +82,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
78 cpu1_state = pwrdm_read_pwrst(cpu1_pd); 82 cpu1_state = pwrdm_read_pwrst(cpu1_pd);
79 if (cpu1_state != PWRDM_POWER_OFF) { 83 if (cpu1_state != PWRDM_POWER_OFF) {
80 index = drv->safe_state_index; 84 index = drv->safe_state_index;
81 cx = cpuidle_get_statedata(&dev->states_usage[index]); 85 cx = &omap4_idle_data[index];
82 } 86 }
83 87
84 if (index > 0) 88 if (index > 0)
@@ -133,36 +137,39 @@ struct cpuidle_driver omap4_idle_driver = {
133 .name = "omap4_idle", 137 .name = "omap4_idle",
134 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
135 .en_core_tk_irqen = 1, 139 .en_core_tk_irqen = 1,
140 .states = {
141 {
142 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
143 .exit_latency = 2 + 2,
144 .target_residency = 5,
145 .flags = CPUIDLE_FLAG_TIME_VALID,
146 .enter = omap4_enter_idle,
147 .name = "C1",
148 .desc = "MPUSS ON"
149 },
150 {
151 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
152 .exit_latency = 328 + 440,
153 .target_residency = 960,
154 .flags = CPUIDLE_FLAG_TIME_VALID,
155 .enter = omap4_enter_idle,
156 .name = "C2",
157 .desc = "MPUSS CSWR",
158 },
159 {
160 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
161 .exit_latency = 460 + 518,
162 .target_residency = 1100,
163 .flags = CPUIDLE_FLAG_TIME_VALID,
164 .enter = omap4_enter_idle,
165 .name = "C3",
166 .desc = "MPUSS OSWR",
167 },
168 },
169 .state_count = ARRAY_SIZE(omap4_idle_data),
170 .safe_state_index = 0,
136}; 171};
137 172
138static inline void _fill_cstate(struct cpuidle_driver *drv,
139 int idx, const char *descr)
140{
141 struct cpuidle_state *state = &drv->states[idx];
142
143 state->exit_latency = cpuidle_params_table[idx].exit_latency;
144 state->target_residency = cpuidle_params_table[idx].target_residency;
145 state->flags = CPUIDLE_FLAG_TIME_VALID;
146 state->enter = omap4_enter_idle;
147 sprintf(state->name, "C%d", idx + 1);
148 strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
149}
150
151static inline struct omap4_idle_statedata *_fill_cstate_usage(
152 struct cpuidle_device *dev,
153 int idx)
154{
155 struct omap4_idle_statedata *cx = &omap4_idle_data[idx];
156 struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
157
158 cx->valid = cpuidle_params_table[idx].valid;
159 cpuidle_set_statedata(state_usage, cx);
160
161 return cx;
162}
163
164
165
166/** 173/**
167 * omap4_idle_init - Init routine for OMAP4 idle 174 * omap4_idle_init - Init routine for OMAP4 idle
168 * 175 *
@@ -171,9 +178,7 @@ static inline struct omap4_idle_statedata *_fill_cstate_usage(
171 */ 178 */
172int __init omap4_idle_init(void) 179int __init omap4_idle_init(void)
173{ 180{
174 struct omap4_idle_statedata *cx;
175 struct cpuidle_device *dev; 181 struct cpuidle_device *dev;
176 struct cpuidle_driver *drv = &omap4_idle_driver;
177 unsigned int cpu_id = 0; 182 unsigned int cpu_id = 0;
178 183
179 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 184 mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -182,42 +187,15 @@ int __init omap4_idle_init(void)
182 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) 187 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd))
183 return -ENODEV; 188 return -ENODEV;
184 189
185
186 drv->safe_state_index = -1;
187 dev = &per_cpu(omap4_idle_dev, cpu_id); 190 dev = &per_cpu(omap4_idle_dev, cpu_id);
188 dev->cpu = cpu_id; 191 dev->cpu = cpu_id;
189 192
190 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
191 _fill_cstate(drv, 0, "MPUSS ON");
192 drv->safe_state_index = 0;
193 cx = _fill_cstate_usage(dev, 0);
194 cx->valid = 1; /* C1 is always valid */
195 cx->cpu_state = PWRDM_POWER_ON;
196 cx->mpu_state = PWRDM_POWER_ON;
197 cx->mpu_logic_state = PWRDM_POWER_RET;
198
199 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
200 _fill_cstate(drv, 1, "MPUSS CSWR");
201 cx = _fill_cstate_usage(dev, 1);
202 cx->cpu_state = PWRDM_POWER_OFF;
203 cx->mpu_state = PWRDM_POWER_RET;
204 cx->mpu_logic_state = PWRDM_POWER_RET;
205
206 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
207 _fill_cstate(drv, 2, "MPUSS OSWR");
208 cx = _fill_cstate_usage(dev, 2);
209 cx->cpu_state = PWRDM_POWER_OFF;
210 cx->mpu_state = PWRDM_POWER_RET;
211 cx->mpu_logic_state = PWRDM_POWER_OFF;
212
213 drv->state_count = OMAP4_NUM_STATES;
214 cpuidle_register_driver(&omap4_idle_driver); 193 cpuidle_register_driver(&omap4_idle_driver);
215 194
216 dev->state_count = OMAP4_NUM_STATES;
217 if (cpuidle_register_device(dev)) { 195 if (cpuidle_register_device(dev)) {
218 pr_err("%s: CPUidle register device failed\n", __func__); 196 pr_err("%s: CPUidle register device failed\n", __func__);
219 return -EIO; 197 return -EIO;
220 } 198 }
221 199
222 return 0; 200 return 0;
223} 201}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 36fa90b6ece8..78564895e914 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -38,27 +38,6 @@ static inline int omap4_opp_init(void)
38} 38}
39#endif 39#endif
40 40
41/*
42 * cpuidle mach specific parameters
43 *
44 * The board code can override the default C-states definition using
45 * omap3_pm_init_cpuidle
46 */
47struct cpuidle_params {
48 u32 exit_latency; /* exit_latency = sleep + wake-up latencies */
49 u32 target_residency;
50 u8 valid; /* validates the C-state */
51};
52
53#if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
54extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
55#else
56static
57inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
58{
59}
60#endif
61
62extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); 41extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
63extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); 42extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
64 43