aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/common/gic.c52
-rw-r--r--arch/arm/include/asm/hardware/gic.h1
-rw-r--r--arch/arm/include/asm/localtimer.h16
-rw-r--r--arch/arm/include/asm/smp_twd.h2
-rw-r--r--arch/arm/kernel/smp.c16
-rw-r--r--arch/arm/kernel/smp_twd.c47
-rw-r--r--arch/arm/mach-exynos4/mct.c7
-rw-r--r--arch/arm/mach-msm/timer.c69
8 files changed, 99 insertions, 111 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index bbea0168779b..a2b320503931 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -35,7 +35,6 @@
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
37#include <asm/hardware/gic.h> 37#include <asm/hardware/gic.h>
38#include <asm/localtimer.h>
39 38
40static DEFINE_SPINLOCK(irq_controller_lock); 39static DEFINE_SPINLOCK(irq_controller_lock);
41 40
@@ -259,32 +258,6 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
259 irq_set_chained_handler(irq, gic_handle_cascade_irq); 258 irq_set_chained_handler(irq, gic_handle_cascade_irq);
260} 259}
261 260
262#ifdef CONFIG_LOCAL_TIMERS
263#define gic_ppi_handler percpu_timer_handler
264#else
265static irqreturn_t gic_ppi_handler(int irq, void *dev_id)
266{
267 return IRQ_NONE;
268}
269#endif
270
271#define PPI_IRQACT(nr) \
272 { \
273 .handler = gic_ppi_handler, \
274 .flags = IRQF_PERCPU | IRQF_TIMER, \
275 .irq = nr, \
276 .name = "PPI-" # nr, \
277 }
278
279static struct irqaction ppi_irqaction_template[16] __initdata = {
280 PPI_IRQACT(0), PPI_IRQACT(1), PPI_IRQACT(2), PPI_IRQACT(3),
281 PPI_IRQACT(4), PPI_IRQACT(5), PPI_IRQACT(6), PPI_IRQACT(7),
282 PPI_IRQACT(8), PPI_IRQACT(9), PPI_IRQACT(10), PPI_IRQACT(11),
283 PPI_IRQACT(12), PPI_IRQACT(13), PPI_IRQACT(14), PPI_IRQACT(15),
284};
285
286static struct irqaction *ppi_irqaction;
287
288static void __init gic_dist_init(struct gic_chip_data *gic, 261static void __init gic_dist_init(struct gic_chip_data *gic,
289 unsigned int irq_start) 262 unsigned int irq_start)
290{ 263{
@@ -325,16 +298,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
325 BUG(); 298 BUG();
326 299
327 ppi_base = gic->irq_offset + 32 - nrppis; 300 ppi_base = gic->irq_offset + 32 - nrppis;
328
329 ppi_irqaction = kmemdup(&ppi_irqaction_template[16 - nrppis],
330 sizeof(*ppi_irqaction) * nrppis,
331 GFP_KERNEL);
332
333 if (nrppis && !ppi_irqaction) {
334 pr_err("GIC: Can't allocate PPI memory");
335 nrppis = 0;
336 ppi_base = 0;
337 }
338 } 301 }
339 302
340 pr_info("Configuring GIC with %d sources (%d PPIs)\n", 303 pr_info("Configuring GIC with %d sources (%d PPIs)\n",
@@ -377,17 +340,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
377 */ 340 */
378 for (i = 0; i < nrppis; i++) { 341 for (i = 0; i < nrppis; i++) {
379 int ppi = i + ppi_base; 342 int ppi = i + ppi_base;
380 int err;
381 343
382 irq_set_percpu_devid(ppi); 344 irq_set_percpu_devid(ppi);
383 irq_set_chip_and_handler(ppi, &gic_chip, 345 irq_set_chip_and_handler(ppi, &gic_chip,
384 handle_percpu_devid_irq); 346 handle_percpu_devid_irq);
385 irq_set_chip_data(ppi, gic); 347 irq_set_chip_data(ppi, gic);
386 set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN); 348 set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
387
388 err = setup_percpu_irq(ppi, &ppi_irqaction[i]);
389 if (err)
390 pr_err("GIC: can't setup PPI%d (%d)\n", ppi, err);
391 } 349 }
392 350
393 for (i = irq_start + nrppis; i < irq_limit; i++) { 351 for (i = irq_start + nrppis; i < irq_limit; i++) {
@@ -448,16 +406,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)
448 gic_cpu_init(&gic_data[gic_nr]); 406 gic_cpu_init(&gic_data[gic_nr]);
449} 407}
450 408
451void __cpuinit gic_enable_ppi(unsigned int irq)
452{
453 unsigned long flags;
454
455 local_irq_save(flags);
456 irq_set_status_flags(irq, IRQ_NOPROBE);
457 gic_unmask_irq(irq_get_irq_data(irq));
458 local_irq_restore(flags);
459}
460
461#ifdef CONFIG_SMP 409#ifdef CONFIG_SMP
462void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 410void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
463{ 411{
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 435d3f86c708..2dadd50a77d2 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -40,7 +40,6 @@ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
40void gic_secondary_init(unsigned int); 40void gic_secondary_init(unsigned int);
41void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 41void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
42void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); 42void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
43void gic_enable_ppi(unsigned int);
44 43
45struct gic_chip_data { 44struct gic_chip_data {
46 unsigned int irq_offset; 45 unsigned int irq_offset;
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 5c8acb4c4040..f5e1cec7e35c 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -19,26 +19,20 @@ struct clock_event_device;
19 */ 19 */
20void percpu_timer_setup(void); 20void percpu_timer_setup(void);
21 21
22/*
23 * Per-cpu timer IRQ handler
24 */
25irqreturn_t percpu_timer_handler(int irq, void *dev_id);
26
27#ifdef CONFIG_LOCAL_TIMERS 22#ifdef CONFIG_LOCAL_TIMERS
28 23
29#ifdef CONFIG_HAVE_ARM_TWD 24#ifdef CONFIG_HAVE_ARM_TWD
30 25
31#include "smp_twd.h" 26#include "smp_twd.h"
32 27
33#define local_timer_ack() twd_timer_ack() 28#define local_timer_stop(c) twd_timer_stop((c))
34 29
35#else 30#else
36 31
37/* 32/*
38 * Platform provides this to acknowledge a local timer IRQ. 33 * Stop the local timer
39 * Returns true if the local timer IRQ is to be processed.
40 */ 34 */
41int local_timer_ack(void); 35void local_timer_stop(struct clock_event_device *);
42 36
43#endif 37#endif
44 38
@@ -53,6 +47,10 @@ static inline int local_timer_setup(struct clock_event_device *evt)
53{ 47{
54 return -ENXIO; 48 return -ENXIO;
55} 49}
50
51static inline void local_timer_stop(struct clock_event_device *evt)
52{
53}
56#endif 54#endif
57 55
58#endif 56#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index fed9981fba08..ef9ffba97ad8 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -22,7 +22,7 @@ struct clock_event_device;
22 22
23extern void __iomem *twd_base; 23extern void __iomem *twd_base;
24 24
25int twd_timer_ack(void);
26void twd_timer_setup(struct clock_event_device *); 25void twd_timer_setup(struct clock_event_device *);
26void twd_timer_stop(struct clock_event_device *);
27 27
28#endif 28#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 917ed2fa4e4c..a96c08cd6125 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -473,20 +473,6 @@ static void ipi_timer(void)
473 irq_exit(); 473 irq_exit();
474} 474}
475 475
476#ifdef CONFIG_LOCAL_TIMERS
477irqreturn_t percpu_timer_handler(int irq, void *dev_id)
478{
479 struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
480
481 if (local_timer_ack()) {
482 evt->event_handler(evt);
483 return IRQ_HANDLED;
484 }
485
486 return IRQ_NONE;
487}
488#endif
489
490#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 476#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
491static void smp_timer_broadcast(const struct cpumask *mask) 477static void smp_timer_broadcast(const struct cpumask *mask)
492{ 478{
@@ -537,7 +523,7 @@ static void percpu_timer_stop(void)
537 unsigned int cpu = smp_processor_id(); 523 unsigned int cpu = smp_processor_id();
538 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); 524 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
539 525
540 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 526 local_timer_stop(evt);
541} 527}
542#endif 528#endif
543 529
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 01c186222f3b..a8a6682d6b52 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -19,6 +19,7 @@
19#include <linux/io.h> 19#include <linux/io.h>
20 20
21#include <asm/smp_twd.h> 21#include <asm/smp_twd.h>
22#include <asm/localtimer.h>
22#include <asm/hardware/gic.h> 23#include <asm/hardware/gic.h>
23 24
24/* set up by the platform code */ 25/* set up by the platform code */
@@ -26,6 +27,8 @@ void __iomem *twd_base;
26 27
27static unsigned long twd_timer_rate; 28static unsigned long twd_timer_rate;
28 29
30static struct clock_event_device __percpu **twd_evt;
31
29static void twd_set_mode(enum clock_event_mode mode, 32static void twd_set_mode(enum clock_event_mode mode,
30 struct clock_event_device *clk) 33 struct clock_event_device *clk)
31{ 34{
@@ -80,6 +83,12 @@ int twd_timer_ack(void)
80 return 0; 83 return 0;
81} 84}
82 85
86void twd_timer_stop(struct clock_event_device *clk)
87{
88 twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
89 disable_percpu_irq(clk->irq);
90}
91
83static void __cpuinit twd_calibrate_rate(void) 92static void __cpuinit twd_calibrate_rate(void)
84{ 93{
85 unsigned long count; 94 unsigned long count;
@@ -119,11 +128,43 @@ static void __cpuinit twd_calibrate_rate(void)
119 } 128 }
120} 129}
121 130
131static irqreturn_t twd_handler(int irq, void *dev_id)
132{
133 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
134
135 if (twd_timer_ack()) {
136 evt->event_handler(evt);
137 return IRQ_HANDLED;
138 }
139
140 return IRQ_NONE;
141}
142
122/* 143/*
123 * Setup the local clock events for a CPU. 144 * Setup the local clock events for a CPU.
124 */ 145 */
125void __cpuinit twd_timer_setup(struct clock_event_device *clk) 146void __cpuinit twd_timer_setup(struct clock_event_device *clk)
126{ 147{
148 struct clock_event_device **this_cpu_clk;
149
150 if (!twd_evt) {
151 int err;
152
153 twd_evt = alloc_percpu(struct clock_event_device *);
154 if (!twd_evt) {
155 pr_err("twd: can't allocate memory\n");
156 return;
157 }
158
159 err = request_percpu_irq(clk->irq, twd_handler,
160 "twd", twd_evt);
161 if (err) {
162 pr_err("twd: can't register interrupt %d (%d)\n",
163 clk->irq, err);
164 return;
165 }
166 }
167
127 twd_calibrate_rate(); 168 twd_calibrate_rate();
128 169
129 clk->name = "local_timer"; 170 clk->name = "local_timer";
@@ -137,8 +178,10 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
137 clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); 178 clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
138 clk->min_delta_ns = clockevent_delta2ns(0xf, clk); 179 clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
139 180
181 this_cpu_clk = __this_cpu_ptr(twd_evt);
182 *this_cpu_clk = clk;
183
140 clockevents_register_device(clk); 184 clockevents_register_device(clk);
141 185
142 /* Make sure our local interrupt controller has this enabled */ 186 enable_percpu_irq(clk->irq, 0);
143 gic_enable_ppi(clk->irq);
144} 187}
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
index 1ae059b7ad7b..85a1bb79f11c 100644
--- a/arch/arm/mach-exynos4/mct.c
+++ b/arch/arm/mach-exynos4/mct.c
@@ -380,9 +380,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
380 380
381 if (cpu == 0) { 381 if (cpu == 0) {
382 mct_tick0_event_irq.dev_id = &mct_tick[cpu]; 382 mct_tick0_event_irq.dev_id = &mct_tick[cpu];
383 evt->irq = IRQ_MCT_L0;
383 setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); 384 setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
384 } else { 385 } else {
385 mct_tick1_event_irq.dev_id = &mct_tick[cpu]; 386 mct_tick1_event_irq.dev_id = &mct_tick[cpu];
387 evt->irq = IRQ_MCT_L1;
386 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); 388 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
387 irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); 389 irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
388 } 390 }
@@ -394,9 +396,10 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
394 exynos4_mct_tick_init(evt); 396 exynos4_mct_tick_init(evt);
395} 397}
396 398
397int local_timer_ack(void) 399void local_timer_stop(struct clock_event_device *evt)
398{ 400{
399 return 0; 401 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
402 disable_irq(evt->irq);
400} 403}
401 404
402#endif /* CONFIG_LOCAL_TIMERS */ 405#endif /* CONFIG_LOCAL_TIMERS */
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 63621f152c98..afeeca52fc66 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -71,12 +71,16 @@ enum timer_location {
71struct msm_clock { 71struct msm_clock {
72 struct clock_event_device clockevent; 72 struct clock_event_device clockevent;
73 struct clocksource clocksource; 73 struct clocksource clocksource;
74 struct irqaction irq; 74 unsigned int irq;
75 void __iomem *regbase; 75 void __iomem *regbase;
76 uint32_t freq; 76 uint32_t freq;
77 uint32_t shift; 77 uint32_t shift;
78 void __iomem *global_counter; 78 void __iomem *global_counter;
79 void __iomem *local_counter; 79 void __iomem *local_counter;
80 union {
81 struct clock_event_device *evt;
82 struct clock_event_device __percpu **percpu_evt;
83 };
80}; 84};
81 85
82enum { 86enum {
@@ -87,13 +91,10 @@ enum {
87 91
88 92
89static struct msm_clock msm_clocks[]; 93static struct msm_clock msm_clocks[];
90static struct clock_event_device *local_clock_event;
91 94
92static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) 95static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
93{ 96{
94 struct clock_event_device *evt = dev_id; 97 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
95 if (smp_processor_id() != 0)
96 evt = local_clock_event;
97 if (evt->event_handler == NULL) 98 if (evt->event_handler == NULL)
98 return IRQ_HANDLED; 99 return IRQ_HANDLED;
99 evt->event_handler(evt); 100 evt->event_handler(evt);
@@ -171,13 +172,7 @@ static struct msm_clock msm_clocks[] = {
171 .mask = CLOCKSOURCE_MASK(32), 172 .mask = CLOCKSOURCE_MASK(32),
172 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 173 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
173 }, 174 },
174 .irq = { 175 .irq = INT_GP_TIMER_EXP,
175 .name = "gp_timer",
176 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
177 .handler = msm_timer_interrupt,
178 .dev_id = &msm_clocks[0].clockevent,
179 .irq = INT_GP_TIMER_EXP
180 },
181 .freq = GPT_HZ, 176 .freq = GPT_HZ,
182 }, 177 },
183 [MSM_CLOCK_DGT] = { 178 [MSM_CLOCK_DGT] = {
@@ -196,13 +191,7 @@ static struct msm_clock msm_clocks[] = {
196 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), 191 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
197 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 192 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
198 }, 193 },
199 .irq = { 194 .irq = INT_DEBUG_TIMER_EXP,
200 .name = "dg_timer",
201 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
202 .handler = msm_timer_interrupt,
203 .dev_id = &msm_clocks[1].clockevent,
204 .irq = INT_DEBUG_TIMER_EXP
205 },
206 .freq = DGT_HZ >> MSM_DGT_SHIFT, 195 .freq = DGT_HZ >> MSM_DGT_SHIFT,
207 .shift = MSM_DGT_SHIFT, 196 .shift = MSM_DGT_SHIFT,
208 } 197 }
@@ -261,10 +250,30 @@ static void __init msm_timer_init(void)
261 printk(KERN_ERR "msm_timer_init: clocksource_register " 250 printk(KERN_ERR "msm_timer_init: clocksource_register "
262 "failed for %s\n", cs->name); 251 "failed for %s\n", cs->name);
263 252
264 res = setup_irq(clock->irq.irq, &clock->irq); 253 ce->irq = clock->irq;
254 if (cpu_is_msm8x60() || cpu_is_msm8960()) {
255 clock->percpu_evt = alloc_percpu(struct clock_event_device *);
256 if (!clock->percpu_evt) {
257 pr_err("msm_timer_init: memory allocation "
258 "failed for %s\n", ce->name);
259 continue;
260 }
261
262 *__this_cpu_ptr(clock->percpu_evt) = ce;
263 res = request_percpu_irq(ce->irq, msm_timer_interrupt,
264 ce->name, clock->percpu_evt);
265 if (!res)
266 enable_percpu_irq(ce->irq, 0);
267 } else {
268 clock->evt = ce;
269 res = request_irq(ce->irq, msm_timer_interrupt,
270 IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
271 ce->name, &clock->evt);
272 }
273
265 if (res) 274 if (res)
266 printk(KERN_ERR "msm_timer_init: setup_irq " 275 pr_err("msm_timer_init: request_irq failed for %s\n",
267 "failed for %s\n", cs->name); 276 ce->name);
268 277
269 clockevents_register_device(ce); 278 clockevents_register_device(ce);
270 } 279 }
@@ -273,6 +282,7 @@ static void __init msm_timer_init(void)
273#ifdef CONFIG_SMP 282#ifdef CONFIG_SMP
274int __cpuinit local_timer_setup(struct clock_event_device *evt) 283int __cpuinit local_timer_setup(struct clock_event_device *evt)
275{ 284{
285 static bool local_timer_inited;
276 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; 286 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
277 287
278 /* Use existing clock_event for cpu 0 */ 288 /* Use existing clock_event for cpu 0 */
@@ -281,12 +291,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
281 291
282 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); 292 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
283 293
284 if (!local_clock_event) { 294 if (!local_timer_inited) {
285 writel(0, clock->regbase + TIMER_ENABLE); 295 writel(0, clock->regbase + TIMER_ENABLE);
286 writel(0, clock->regbase + TIMER_CLEAR); 296 writel(0, clock->regbase + TIMER_CLEAR);
287 writel(~0, clock->regbase + TIMER_MATCH_VAL); 297 writel(~0, clock->regbase + TIMER_MATCH_VAL);
298 local_timer_inited = true;
288 } 299 }
289 evt->irq = clock->irq.irq; 300 evt->irq = clock->irq;
290 evt->name = "local_timer"; 301 evt->name = "local_timer";
291 evt->features = CLOCK_EVT_FEAT_ONESHOT; 302 evt->features = CLOCK_EVT_FEAT_ONESHOT;
292 evt->rating = clock->clockevent.rating; 303 evt->rating = clock->clockevent.rating;
@@ -298,17 +309,17 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
298 clockevent_delta2ns(0xf0000000 >> clock->shift, evt); 309 clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
299 evt->min_delta_ns = clockevent_delta2ns(4, evt); 310 evt->min_delta_ns = clockevent_delta2ns(4, evt);
300 311
301 local_clock_event = evt; 312 *__this_cpu_ptr(clock->percpu_evt) = evt;
302 313 enable_percpu_irq(evt->irq, 0);
303 gic_enable_ppi(clock->irq.irq);
304 314
305 clockevents_register_device(evt); 315 clockevents_register_device(evt);
306 return 0; 316 return 0;
307} 317}
308 318
309inline int local_timer_ack(void) 319void local_timer_stop(struct clock_event_device *evt)
310{ 320{
311 return 1; 321 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
322 disable_percpu_irq(evt->irq);
312} 323}
313 324
314#endif 325#endif