diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2013-07-10 10:02:04 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2013-07-27 01:56:39 -0400 |
commit | d3f2950f2adeea3da0317e952914b59adaa4cdb3 (patch) | |
tree | be257db12595162a5cb27d510d67096486c690cf /arch/arm | |
parent | 8457246b106cc4e53f2534309dbe35a973c7d046 (diff) |
ARM: ux500: cpuidle: Move ux500 cpuidle driver to drivers/cpuidle
There is no more dependency with arch/arm headers, so we can safely move the
driver to the drivers/cpuidle directory.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-ux500/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpuidle.c | 131 |
2 files changed, 0 insertions, 132 deletions
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index bf9b6be5b180..fe1f3e26b88b 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | obj-y := cpu.o devices.o devices-common.o \ | 5 | obj-y := cpu.o devices.o devices-common.o \ |
6 | id.o usb.o timer.o pm.o | 6 | id.o usb.o timer.o pm.o |
7 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
8 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o | 7 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o |
9 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o |
10 | obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ |
diff --git a/arch/arm/mach-ux500/cpuidle.c b/arch/arm/mach-ux500/cpuidle.c deleted file mode 100644 index e0564652af35..000000000000 --- a/arch/arm/mach-ux500/cpuidle.c +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Linaro : Daniel Lezcano <daniel.lezcano@linaro.org> (IBM) | ||
3 | * | ||
4 | * Based on the work of Rickard Andersson <rickard.andersson@stericsson.com> | ||
5 | * and Jonas Aaberg <jonas.aberg@stericsson.com>. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/cpuidle.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/atomic.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/mfd/dbx500-prcmu.h> | ||
18 | #include <linux/platform_data/arm-ux500-pm.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include <asm/cpuidle.h> | ||
22 | #include <asm/proc-fns.h> | ||
23 | |||
24 | static atomic_t master = ATOMIC_INIT(0); | ||
25 | static DEFINE_SPINLOCK(master_lock); | ||
26 | |||
27 | static inline int ux500_enter_idle(struct cpuidle_device *dev, | ||
28 | struct cpuidle_driver *drv, int index) | ||
29 | { | ||
30 | int this_cpu = smp_processor_id(); | ||
31 | bool recouple = false; | ||
32 | |||
33 | if (atomic_inc_return(&master) == num_online_cpus()) { | ||
34 | |||
35 | /* With this lock, we prevent the other cpu to exit and enter | ||
36 | * this function again and become the master */ | ||
37 | if (!spin_trylock(&master_lock)) | ||
38 | goto wfi; | ||
39 | |||
40 | /* decouple the gic from the A9 cores */ | ||
41 | if (prcmu_gic_decouple()) { | ||
42 | spin_unlock(&master_lock); | ||
43 | goto out; | ||
44 | } | ||
45 | |||
46 | /* If an error occur, we will have to recouple the gic | ||
47 | * manually */ | ||
48 | recouple = true; | ||
49 | |||
50 | /* At this state, as the gic is decoupled, if the other | ||
51 | * cpu is in WFI, we have the guarantee it won't be wake | ||
52 | * up, so we can safely go to retention */ | ||
53 | if (!prcmu_is_cpu_in_wfi(this_cpu ? 0 : 1)) | ||
54 | goto out; | ||
55 | |||
56 | /* The prcmu will be in charge of watching the interrupts | ||
57 | * and wake up the cpus */ | ||
58 | if (prcmu_copy_gic_settings()) | ||
59 | goto out; | ||
60 | |||
61 | /* Check in the meantime an interrupt did | ||
62 | * not occur on the gic ... */ | ||
63 | if (prcmu_gic_pending_irq()) | ||
64 | goto out; | ||
65 | |||
66 | /* ... and the prcmu */ | ||
67 | if (prcmu_pending_irq()) | ||
68 | goto out; | ||
69 | |||
70 | /* Go to the retention state, the prcmu will wait for the | ||
71 | * cpu to go WFI and this is what happens after exiting this | ||
72 | * 'master' critical section */ | ||
73 | if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true)) | ||
74 | goto out; | ||
75 | |||
76 | /* When we switch to retention, the prcmu is in charge | ||
77 | * of recoupling the gic automatically */ | ||
78 | recouple = false; | ||
79 | |||
80 | spin_unlock(&master_lock); | ||
81 | } | ||
82 | wfi: | ||
83 | cpu_do_idle(); | ||
84 | out: | ||
85 | atomic_dec(&master); | ||
86 | |||
87 | if (recouple) { | ||
88 | prcmu_gic_recouple(); | ||
89 | spin_unlock(&master_lock); | ||
90 | } | ||
91 | |||
92 | return index; | ||
93 | } | ||
94 | |||
95 | static struct cpuidle_driver ux500_idle_driver = { | ||
96 | .name = "ux500_idle", | ||
97 | .owner = THIS_MODULE, | ||
98 | .states = { | ||
99 | ARM_CPUIDLE_WFI_STATE, | ||
100 | { | ||
101 | .enter = ux500_enter_idle, | ||
102 | .exit_latency = 70, | ||
103 | .target_residency = 260, | ||
104 | .flags = CPUIDLE_FLAG_TIME_VALID | | ||
105 | CPUIDLE_FLAG_TIMER_STOP, | ||
106 | .name = "ApIdle", | ||
107 | .desc = "ARM Retention", | ||
108 | }, | ||
109 | }, | ||
110 | .safe_state_index = 0, | ||
111 | .state_count = 2, | ||
112 | }; | ||
113 | |||
114 | static int __init dbx500_cpuidle_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | /* Configure wake up reasons */ | ||
117 | prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | | ||
118 | PRCMU_WAKEUP(ABB)); | ||
119 | |||
120 | return cpuidle_register(&ux500_idle_driver, NULL); | ||
121 | } | ||
122 | |||
123 | static struct platform_driver dbx500_cpuidle_plat_driver = { | ||
124 | .driver = { | ||
125 | .name = "cpuidle-dbx500", | ||
126 | .owner = THIS_MODULE, | ||
127 | }, | ||
128 | .probe = dbx500_cpuidle_probe, | ||
129 | }; | ||
130 | |||
131 | module_platform_driver(dbx500_cpuidle_plat_driver); | ||