Commit | Line | Data |
---|---|---|
e50b6bef RK |
1 | /* |
2 | * arch/arm/mach-kirkwood/cpuidle.c | |
3 | * | |
4 | * CPU idle Marvell Kirkwood SoCs | |
5 | * | |
6 | * This file is licensed under the terms of the GNU General Public | |
7 | * License version 2. This program is licensed "as is" without any | |
8 | * warranty of any kind, whether express or implied. | |
9 | * | |
10 | * The cpu idle uses wait-for-interrupt and DDR self refresh in order | |
11 | * to implement two idle states - | |
12 | * #1 wait-for-interrupt | |
13 | * #2 wait-for-interrupt and DDR self refresh | |
14 | */ | |
15 | ||
16 | #include <linux/kernel.h> | |
17 | #include <linux/init.h> | |
18 | #include <linux/platform_device.h> | |
19 | #include <linux/cpuidle.h> | |
20 | #include <linux/io.h> | |
dc28094b | 21 | #include <linux/export.h> |
e50b6bef | 22 | #include <asm/proc-fns.h> |
b334648d | 23 | #include <asm/cpuidle.h> |
e50b6bef RK |
24 | #include <mach/kirkwood.h> |
25 | ||
26 | #define KIRKWOOD_MAX_STATES 2 | |
27 | ||
e50b6bef RK |
28 | /* Actual code that puts the SoC in different idle states */ |
29 | static int kirkwood_enter_idle(struct cpuidle_device *dev, | |
46bcfad7 | 30 | struct cpuidle_driver *drv, |
e978aa7d | 31 | int index) |
e50b6bef | 32 | { |
b334648d RL |
33 | writel(0x7, DDR_OPERATION_BASE); |
34 | cpu_do_idle(); | |
e978aa7d DD |
35 | |
36 | return index; | |
e50b6bef RK |
37 | } |
38 | ||
b334648d RL |
39 | static struct cpuidle_driver kirkwood_idle_driver = { |
40 | .name = "kirkwood_idle", | |
41 | .owner = THIS_MODULE, | |
42 | .en_core_tk_irqen = 1, | |
43 | .states[0] = ARM_CPUIDLE_WFI_STATE, | |
44 | .states[1] = { | |
45 | .enter = kirkwood_enter_idle, | |
46 | .exit_latency = 10, | |
47 | .target_residency = 100000, | |
48 | .flags = CPUIDLE_FLAG_TIME_VALID, | |
49 | .name = "DDR SR", | |
50 | .desc = "WFI and DDR Self Refresh", | |
51 | }, | |
52 | .state_count = KIRKWOOD_MAX_STATES, | |
53 | }; | |
54 | ||
55 | static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); | |
56 | ||
e50b6bef RK |
57 | /* Initialize CPU idle by registering the idle states */ |
58 | static int kirkwood_init_cpuidle(void) | |
59 | { | |
60 | struct cpuidle_device *device; | |
e50b6bef RK |
61 | |
62 | device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); | |
63 | device->state_count = KIRKWOOD_MAX_STATES; | |
e50b6bef | 64 | |
46bcfad7 | 65 | cpuidle_register_driver(&kirkwood_idle_driver); |
e50b6bef | 66 | if (cpuidle_register_device(device)) { |
98adf932 | 67 | pr_err("kirkwood_init_cpuidle: Failed registering\n"); |
e50b6bef RK |
68 | return -EIO; |
69 | } | |
70 | return 0; | |
71 | } | |
72 | ||
73 | device_initcall(kirkwood_init_cpuidle); |