diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2008-02-04 17:30:57 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-02-04 17:52:19 +0000 |
commit | a8655e83fc44ec2b92cbea9f3ff3cc0da05a991c (patch) | |
tree | 56bdc711208aca8b514e7366b56c66b9c05ac1be /arch/arm/mach-realview/localtimer.c | |
parent | 3e459990961db7f3f2dcf21e2b38a7216dfd10dd (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.c | 39 |
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 */ |