summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/timer.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-14 13:18:27 +0200
committerIngo Molnar <mingo@kernel.org>2012-04-14 13:19:04 +0200
commit6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch)
tree021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /arch/arm/mach-msm/timer.c
parent682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff)
parenta385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff)
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree), to prepare for tooling changes, and also to pick up v3.4 MM changes that the uprobes code needs to take care of. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/arm/mach-msm/timer.c')
-rw-r--r--arch/arm/mach-msm/timer.c91
1 files changed, 54 insertions, 37 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 11d0d8f2656..81280825493 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -24,6 +24,7 @@
#include <asm/mach/time.h>
#include <asm/hardware/gic.h>
#include <asm/localtimer.h>
+#include <asm/sched_clock.h>
#include <mach/msm_iomap.h>
#include <mach/cpu.h>
@@ -105,12 +106,12 @@ static union {
static void __iomem *source_base;
-static cycle_t msm_read_timer_count(struct clocksource *cs)
+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
{
return readl_relaxed(source_base + TIMER_COUNT_VAL);
}
-static cycle_t msm_read_timer_count_shift(struct clocksource *cs)
+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
{
/*
* Shift timer count down by a constant due to unreliable lower bits
@@ -127,6 +128,50 @@ 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 notrace u32 msm_sched_clock_read(void)
+{
+ return msm_clocksource.read(&msm_clocksource);
+}
+
static void __init msm_timer_init(void)
{
struct clock_event_device *ce = &msm_clockevent;
@@ -173,8 +218,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,
@@ -189,42 +238,10 @@ err:
res = clocksource_register_hz(cs, dgt_hz);
if (res)
pr_err("clocksource_register failed\n");
+ setup_sched_clock(msm_sched_clock_read,
+ cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz);
}
-#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
};