diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2012-01-10 14:44:19 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2012-03-13 09:45:55 -0400 |
commit | 5ca709c16d0fb88b86db35e958b165b61cbc1962 (patch) | |
tree | 14d0494b698fbc10d7b220130fe12d43f0f631e1 /arch/arm/mach-msm/timer.c | |
parent | a8cb6041d0ade808e0173f1e1ca1c92c67979806 (diff) |
ARM: local timers: convert MSM to runtime registration interface
Convert the MSM timers to the runtime registration interface.
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: David Brown <davidb@codeaurora.org>
Acked-by: David Brown <davidb@codeaurora.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/mach-msm/timer.c')
-rw-r--r-- | arch/arm/mach-msm/timer.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 11d0d8f2656c..75f4be40b3e5 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c | |||
@@ -127,6 +127,45 @@ static struct clocksource msm_clocksource = { | |||
127 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 127 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | #ifdef CONFIG_LOCAL_TIMERS | ||
131 | static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt) | ||
132 | { | ||
133 | /* Use existing clock_event for cpu 0 */ | ||
134 | if (!smp_processor_id()) | ||
135 | return 0; | ||
136 | |||
137 | writel_relaxed(0, event_base + TIMER_ENABLE); | ||
138 | writel_relaxed(0, event_base + TIMER_CLEAR); | ||
139 | writel_relaxed(~0, event_base + TIMER_MATCH_VAL); | ||
140 | evt->irq = msm_clockevent.irq; | ||
141 | evt->name = "local_timer"; | ||
142 | evt->features = msm_clockevent.features; | ||
143 | evt->rating = msm_clockevent.rating; | ||
144 | evt->set_mode = msm_timer_set_mode; | ||
145 | evt->set_next_event = msm_timer_set_next_event; | ||
146 | evt->shift = msm_clockevent.shift; | ||
147 | evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift); | ||
148 | evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt); | ||
149 | evt->min_delta_ns = clockevent_delta2ns(4, evt); | ||
150 | |||
151 | *__this_cpu_ptr(msm_evt.percpu_evt) = evt; | ||
152 | clockevents_register_device(evt); | ||
153 | enable_percpu_irq(evt->irq, 0); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static void msm_local_timer_stop(struct clock_event_device *evt) | ||
158 | { | ||
159 | evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); | ||
160 | disable_percpu_irq(evt->irq); | ||
161 | } | ||
162 | |||
163 | static struct local_timer_ops msm_local_timer_ops __cpuinitdata = { | ||
164 | .setup = msm_local_timer_setup, | ||
165 | .stop = msm_local_timer_stop, | ||
166 | }; | ||
167 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
168 | |||
130 | static void __init msm_timer_init(void) | 169 | static void __init msm_timer_init(void) |
131 | { | 170 | { |
132 | struct clock_event_device *ce = &msm_clockevent; | 171 | struct clock_event_device *ce = &msm_clockevent; |
@@ -173,8 +212,12 @@ static void __init msm_timer_init(void) | |||
173 | *__this_cpu_ptr(msm_evt.percpu_evt) = ce; | 212 | *__this_cpu_ptr(msm_evt.percpu_evt) = ce; |
174 | res = request_percpu_irq(ce->irq, msm_timer_interrupt, | 213 | res = request_percpu_irq(ce->irq, msm_timer_interrupt, |
175 | ce->name, msm_evt.percpu_evt); | 214 | ce->name, msm_evt.percpu_evt); |
176 | if (!res) | 215 | if (!res) { |
177 | enable_percpu_irq(ce->irq, 0); | 216 | enable_percpu_irq(ce->irq, 0); |
217 | #ifdef CONFIG_LOCAL_TIMERS | ||
218 | local_timer_register(&msm_local_timer_ops); | ||
219 | #endif | ||
220 | } | ||
178 | } else { | 221 | } else { |
179 | msm_evt.evt = ce; | 222 | msm_evt.evt = ce; |
180 | res = request_irq(ce->irq, msm_timer_interrupt, | 223 | res = request_irq(ce->irq, msm_timer_interrupt, |
@@ -191,40 +234,6 @@ err: | |||
191 | pr_err("clocksource_register failed\n"); | 234 | pr_err("clocksource_register failed\n"); |
192 | } | 235 | } |
193 | 236 | ||
194 | #ifdef CONFIG_LOCAL_TIMERS | ||
195 | int __cpuinit local_timer_setup(struct clock_event_device *evt) | ||
196 | { | ||
197 | /* Use existing clock_event for cpu 0 */ | ||
198 | if (!smp_processor_id()) | ||
199 | return 0; | ||
200 | |||
201 | writel_relaxed(0, event_base + TIMER_ENABLE); | ||
202 | writel_relaxed(0, event_base + TIMER_CLEAR); | ||
203 | writel_relaxed(~0, event_base + TIMER_MATCH_VAL); | ||
204 | evt->irq = msm_clockevent.irq; | ||
205 | evt->name = "local_timer"; | ||
206 | evt->features = msm_clockevent.features; | ||
207 | evt->rating = msm_clockevent.rating; | ||
208 | evt->set_mode = msm_timer_set_mode; | ||
209 | evt->set_next_event = msm_timer_set_next_event; | ||
210 | evt->shift = msm_clockevent.shift; | ||
211 | evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift); | ||
212 | evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt); | ||
213 | evt->min_delta_ns = clockevent_delta2ns(4, evt); | ||
214 | |||
215 | *__this_cpu_ptr(msm_evt.percpu_evt) = evt; | ||
216 | clockevents_register_device(evt); | ||
217 | enable_percpu_irq(evt->irq, 0); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | void local_timer_stop(struct clock_event_device *evt) | ||
222 | { | ||
223 | evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); | ||
224 | disable_percpu_irq(evt->irq); | ||
225 | } | ||
226 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
227 | |||
228 | struct sys_timer msm_timer = { | 237 | struct sys_timer msm_timer = { |
229 | .init = msm_timer_init | 238 | .init = msm_timer_init |
230 | }; | 239 | }; |