diff options
Diffstat (limited to 'arch/arm/mach-realview')
-rw-r--r-- | arch/arm/mach-realview/localtimer.c | 70 | ||||
-rw-r--r-- | arch/arm/mach-realview/platsmp.c | 14 |
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 | ||
27 | static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); | ||
28 | |||
29 | /* | ||
30 | * Used on SMP for either the local timer or IPI_TIMER | ||
31 | */ | ||
32 | void 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; | |||
44 | static unsigned long mpcore_timer_rate; | 30 | static unsigned long mpcore_timer_rate; |
45 | 31 | ||
46 | static void local_timer_set_mode(enum clock_event_mode mode, | 32 | static 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 | */ |
143 | void __cpuinit local_timer_setup(void) | 129 | void __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 | |||
181 | static void dummy_timer_set_mode(enum clock_event_mode mode, | ||
182 | struct clock_event_device *clk) | ||
183 | { | ||
184 | } | ||
185 | |||
186 | void __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 | } |