aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2012-01-10 19:44:19 +0000
committerMarc Zyngier <marc.zyngier@arm.com>2012-03-13 13:45:55 +0000
commit5ca709c16d0fb88b86db35e958b165b61cbc1962 (patch)
tree14d0494b698fbc10d7b220130fe12d43f0f631e1
parenta8cb6041d0ade808e0173f1e1ca1c92c67979806 (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>
-rw-r--r--arch/arm/mach-msm/timer.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 11d0d8f2656..75f4be40b3e 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -127,6 +127,45 @@ static struct clocksource msm_clocksource = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
+{
+ /* Use existing clock_event for cpu 0 */
+ if (!smp_processor_id())
+ return 0;
+
+ writel_relaxed(0, event_base + TIMER_ENABLE);
+ writel_relaxed(0, event_base + TIMER_CLEAR);
+ writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
+ evt->irq = msm_clockevent.irq;
+ evt->name = "local_timer";
+ evt->features = msm_clockevent.features;
+ evt->rating = msm_clockevent.rating;
+ evt->set_mode = msm_timer_set_mode;
+ evt->set_next_event = msm_timer_set_next_event;
+ evt->shift = msm_clockevent.shift;
+ evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
+ evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
+ evt->min_delta_ns = clockevent_delta2ns(4, evt);
+
+ *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
+ clockevents_register_device(evt);
+ enable_percpu_irq(evt->irq, 0);
+ return 0;
+}
+
+static void msm_local_timer_stop(struct clock_event_device *evt)
+{
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+ disable_percpu_irq(evt->irq);
+}
+
+static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
+ .setup = msm_local_timer_setup,
+ .stop = msm_local_timer_stop,
+};
+#endif /* CONFIG_LOCAL_TIMERS */
+
static void __init msm_timer_init(void)
{
struct clock_event_device *ce = &msm_clockevent;
@@ -173,8 +212,12 @@ static void __init msm_timer_init(void)
*__this_cpu_ptr(msm_evt.percpu_evt) = ce;
res = request_percpu_irq(ce->irq, msm_timer_interrupt,
ce->name, msm_evt.percpu_evt);
- if (!res)
+ if (!res) {
enable_percpu_irq(ce->irq, 0);
+#ifdef CONFIG_LOCAL_TIMERS
+ local_timer_register(&msm_local_timer_ops);
+#endif
+ }
} else {
msm_evt.evt = ce;
res = request_irq(ce->irq, msm_timer_interrupt,
@@ -191,40 +234,6 @@ err:
pr_err("clocksource_register failed\n");
}
-#ifdef CONFIG_LOCAL_TIMERS
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
- /* Use existing clock_event for cpu 0 */
- if (!smp_processor_id())
- return 0;
-
- writel_relaxed(0, event_base + TIMER_ENABLE);
- writel_relaxed(0, event_base + TIMER_CLEAR);
- writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
- evt->irq = msm_clockevent.irq;
- evt->name = "local_timer";
- evt->features = msm_clockevent.features;
- evt->rating = msm_clockevent.rating;
- evt->set_mode = msm_timer_set_mode;
- evt->set_next_event = msm_timer_set_next_event;
- evt->shift = msm_clockevent.shift;
- evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
- evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
- evt->min_delta_ns = clockevent_delta2ns(4, evt);
-
- *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
- clockevents_register_device(evt);
- enable_percpu_irq(evt->irq, 0);
- return 0;
-}
-
-void local_timer_stop(struct clock_event_device *evt)
-{
- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
- disable_percpu_irq(evt->irq);
-}
-#endif /* CONFIG_LOCAL_TIMERS */
-
struct sys_timer msm_timer = {
.init = msm_timer_init
};