aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-realview/localtimer.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2008-02-04 17:30:57 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-02-04 17:52:19 +0000
commita8655e83fc44ec2b92cbea9f3ff3cc0da05a991c (patch)
tree56bdc711208aca8b514e7366b56c66b9c05ac1be /arch/arm/mach-realview/localtimer.c
parent3e459990961db7f3f2dcf21e2b38a7216dfd10dd (diff)
[ARM] 4814/1: RealView: Add broadcasting clockevents support for ARM11MPCore
This patch adds dummy local timers for each CPU so that the board clock device is used to broadcast events to the other CPUs. The patch also adds the declaration for the dummy_timer_setup function (the equivalent of local_timer_setup when CONFIG_LOCAL_TIMERS is not set). Due to the way clockevents work, the dummy timer on the first CPU has to be registered before the board timer. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-realview/localtimer.c')
-rw-r--r--arch/arm/mach-realview/localtimer.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index c7bdf04ab09..529eb6979e6 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -14,6 +14,8 @@
#include <linux/device.h>
#include <linux/smp.h>
#include <linux/jiffies.h>
+#include <linux/percpu.h>
+#include <linux/clockchips.h>
#include <asm/mach/time.h>
#include <asm/hardware/arm_twd.h>
@@ -25,6 +27,20 @@
#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \
((cpu) * REALVIEW_TWD_SIZE))
+static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
+
+/*
+ * Used on SMP for either the local timer or IPI_TIMER
+ */
+void local_timer_interrupt(void)
+{
+ struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
+
+ clk->event_handler(clk);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+
static unsigned long mpcore_timer_rate;
/*
@@ -127,3 +143,26 @@ void __cpuexit local_timer_stop(unsigned int cpu)
{
__raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL);
}
+
+#else /* CONFIG_LOCAL_TIMERS */
+
+static void dummy_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+}
+
+void __cpuinit local_timer_setup(unsigned int cpu)
+{
+ struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
+
+ clk->name = "dummy_timer";
+ clk->features = CLOCK_EVT_FEAT_DUMMY;
+ clk->rating = 200;
+ clk->set_mode = dummy_timer_set_mode;
+ clk->broadcast = smp_timer_broadcast;
+ clk->cpumask = cpumask_of_cpu(cpu);
+
+ clockevents_register_device(clk);
+}
+
+#endif /* !CONFIG_LOCAL_TIMERS */