aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-realview
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-05-17 13:58:34 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-05-17 13:58:34 -0400
commitbc28248ee25e5c239cbe6afca35a100b08401de5 (patch)
tree89fb6944170bc85b5c9261cd7c7dba6954994cc3 /arch/arm/mach-realview
parentee348d5a1d810bc9958cabb7c27302aab235d36e (diff)
[ARM] smp: move core localtimer support out of platform specific files
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-realview')
-rw-r--r--arch/arm/mach-realview/localtimer.c70
-rw-r--r--arch/arm/mach-realview/platsmp.c14
2 files changed, 21 insertions, 63 deletions
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index 1c01d13460f0..cd98e7acd94d 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -11,10 +11,8 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h> 14#include <linux/smp.h>
16#include <linux/jiffies.h> 15#include <linux/jiffies.h>
17#include <linux/percpu.h>
18#include <linux/clockchips.h> 16#include <linux/clockchips.h>
19#include <linux/irq.h> 17#include <linux/irq.h>
20#include <linux/io.h> 18#include <linux/io.h>
@@ -24,18 +22,6 @@
24#include <mach/hardware.h> 22#include <mach/hardware.h>
25#include <asm/irq.h> 23#include <asm/irq.h>
26 24
27static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
28
29/*
30 * Used on SMP for either the local timer or IPI_TIMER
31 */
32void local_timer_interrupt(void)
33{
34 struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
35
36 clk->event_handler(clk);
37}
38
39#ifdef CONFIG_LOCAL_TIMERS 25#ifdef CONFIG_LOCAL_TIMERS
40 26
41/* set up by the platform code */ 27/* set up by the platform code */
@@ -44,7 +30,7 @@ void __iomem *twd_base;
44static unsigned long mpcore_timer_rate; 30static unsigned long mpcore_timer_rate;
45 31
46static void local_timer_set_mode(enum clock_event_mode mode, 32static void local_timer_set_mode(enum clock_event_mode mode,
47 struct clock_event_device *clk) 33 struct clock_event_device *evt)
48{ 34{
49 unsigned long ctrl; 35 unsigned long ctrl;
50 36
@@ -140,32 +126,29 @@ static void __cpuinit twd_calibrate_rate(void)
140/* 126/*
141 * Setup the local clock events for a CPU. 127 * Setup the local clock events for a CPU.
142 */ 128 */
143void __cpuinit local_timer_setup(void) 129void __cpuinit local_timer_setup(struct clock_event_device *evt)
144{ 130{
145 unsigned int cpu = smp_processor_id();
146 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
147 unsigned long flags; 131 unsigned long flags;
148 132
149 twd_calibrate_rate(); 133 twd_calibrate_rate();
150 134
151 clk->name = "local_timer"; 135 evt->name = "local_timer";
152 clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 136 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
153 clk->rating = 350; 137 evt->rating = 350;
154 clk->set_mode = local_timer_set_mode; 138 evt->set_mode = local_timer_set_mode;
155 clk->set_next_event = local_timer_set_next_event; 139 evt->set_next_event = local_timer_set_next_event;
156 clk->irq = IRQ_LOCALTIMER; 140 evt->irq = IRQ_LOCALTIMER;
157 clk->cpumask = cpumask_of(cpu); 141 evt->shift = 20;
158 clk->shift = 20; 142 evt->mult = div_sc(mpcore_timer_rate, NSEC_PER_SEC, evt->shift);
159 clk->mult = div_sc(mpcore_timer_rate, NSEC_PER_SEC, clk->shift); 143 evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
160 clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); 144 evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
161 clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
162 145
163 /* Make sure our local interrupt controller has this enabled */ 146 /* Make sure our local interrupt controller has this enabled */
164 local_irq_save(flags); 147 local_irq_save(flags);
165 get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER); 148 get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER);
166 local_irq_restore(flags); 149 local_irq_restore(flags);
167 150
168 clockevents_register_device(clk); 151 clockevents_register_device(evt);
169} 152}
170 153
171/* 154/*
@@ -176,29 +159,4 @@ void __cpuexit local_timer_stop(void)
176 __raw_writel(0, twd_base + TWD_TIMER_CONTROL); 159 __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
177} 160}
178 161
179#else /* CONFIG_LOCAL_TIMERS */ 162#endif /* CONFIG_LOCAL_TIMERS */
180
181static void dummy_timer_set_mode(enum clock_event_mode mode,
182 struct clock_event_device *clk)
183{
184}
185
186void __cpuinit local_timer_setup(void)
187{
188 unsigned int cpu = smp_processor_id();
189 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
190
191 clk->name = "dummy_timer";
192 clk->features = CLOCK_EVT_FEAT_ONESHOT |
193 CLOCK_EVT_FEAT_PERIODIC |
194 CLOCK_EVT_FEAT_DUMMY;
195 clk->rating = 400;
196 clk->mult = 1;
197 clk->set_mode = dummy_timer_set_mode;
198 clk->broadcast = smp_timer_broadcast;
199 clk->cpumask = cpumask_of(cpu);
200
201 clockevents_register_device(clk);
202}
203
204#endif /* !CONFIG_LOCAL_TIMERS */
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 30a9c68591f6..b34d3a57ce93 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -19,6 +19,7 @@
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/localtimer.h>
22 23
23#include <mach/board-eb.h> 24#include <mach/board-eb.h>
24#include <mach/board-pb11mp.h> 25#include <mach/board-pb11mp.h>
@@ -217,13 +218,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
217 if (max_cpus > ncores) 218 if (max_cpus > ncores)
218 max_cpus = ncores; 219 max_cpus = ncores;
219 220
220#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
221 /*
222 * Enable the local timer or broadcast device for the boot CPU.
223 */
224 local_timer_setup();
225#endif
226
227 /* 221 /*
228 * Initialise the present map, which describes the set of CPUs 222 * Initialise the present map, which describes the set of CPUs
229 * actually populated at the present time. 223 * actually populated at the present time.
@@ -239,6 +233,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
239 * WFI 233 * WFI
240 */ 234 */
241 if (max_cpus > 1) { 235 if (max_cpus > 1) {
236 /*
237 * Enable the local timer or broadcast device for the
238 * boot CPU, but only if we have more than one CPU.
239 */
240 percpu_timer_setup();
241
242 scu_enable(); 242 scu_enable();
243 poke_milo(); 243 poke_milo();
244 } 244 }