diff options
Diffstat (limited to 'arch/ia64/kernel/irq_ia64.c')
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 1c5044a80958..bc47049f060f 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/machvec.h> | 38 | #include <asm/machvec.h> |
39 | #include <asm/pgtable.h> | 39 | #include <asm/pgtable.h> |
40 | #include <asm/system.h> | 40 | #include <asm/system.h> |
41 | #include <asm/tlbflush.h> | ||
41 | 42 | ||
42 | #ifdef CONFIG_PERFMON | 43 | #ifdef CONFIG_PERFMON |
43 | # include <asm/perfmon.h> | 44 | # include <asm/perfmon.h> |
@@ -126,8 +127,10 @@ void destroy_irq(unsigned int irq) | |||
126 | 127 | ||
127 | #ifdef CONFIG_SMP | 128 | #ifdef CONFIG_SMP |
128 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) | 129 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) |
130 | # define IS_LOCAL_TLB_FLUSH(vec) (vec == IA64_IPI_LOCAL_TLB_FLUSH) | ||
129 | #else | 131 | #else |
130 | # define IS_RESCHEDULE(vec) (0) | 132 | # define IS_RESCHEDULE(vec) (0) |
133 | # define IS_LOCAL_TLB_FLUSH(vec) (0) | ||
131 | #endif | 134 | #endif |
132 | /* | 135 | /* |
133 | * That's where the IVT branches when we get an external | 136 | * That's where the IVT branches when we get an external |
@@ -179,8 +182,11 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) | |||
179 | saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); | 182 | saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); |
180 | ia64_srlz_d(); | 183 | ia64_srlz_d(); |
181 | while (vector != IA64_SPURIOUS_INT_VECTOR) { | 184 | while (vector != IA64_SPURIOUS_INT_VECTOR) { |
182 | if (unlikely(IS_RESCHEDULE(vector))) | 185 | if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { |
183 | kstat_this_cpu.irqs[vector]++; | 186 | smp_local_flush_tlb(); |
187 | kstat_this_cpu.irqs[vector]++; | ||
188 | } else if (unlikely(IS_RESCHEDULE(vector))) | ||
189 | kstat_this_cpu.irqs[vector]++; | ||
184 | else { | 190 | else { |
185 | ia64_setreg(_IA64_REG_CR_TPR, vector); | 191 | ia64_setreg(_IA64_REG_CR_TPR, vector); |
186 | ia64_srlz_d(); | 192 | ia64_srlz_d(); |
@@ -226,8 +232,11 @@ void ia64_process_pending_intr(void) | |||
226 | * Perform normal interrupt style processing | 232 | * Perform normal interrupt style processing |
227 | */ | 233 | */ |
228 | while (vector != IA64_SPURIOUS_INT_VECTOR) { | 234 | while (vector != IA64_SPURIOUS_INT_VECTOR) { |
229 | if (unlikely(IS_RESCHEDULE(vector))) | 235 | if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { |
230 | kstat_this_cpu.irqs[vector]++; | 236 | smp_local_flush_tlb(); |
237 | kstat_this_cpu.irqs[vector]++; | ||
238 | } else if (unlikely(IS_RESCHEDULE(vector))) | ||
239 | kstat_this_cpu.irqs[vector]++; | ||
231 | else { | 240 | else { |
232 | struct pt_regs *old_regs = set_irq_regs(NULL); | 241 | struct pt_regs *old_regs = set_irq_regs(NULL); |
233 | 242 | ||
@@ -259,12 +268,12 @@ void ia64_process_pending_intr(void) | |||
259 | 268 | ||
260 | 269 | ||
261 | #ifdef CONFIG_SMP | 270 | #ifdef CONFIG_SMP |
262 | extern irqreturn_t handle_IPI (int irq, void *dev_id); | ||
263 | 271 | ||
264 | static irqreturn_t dummy_handler (int irq, void *dev_id) | 272 | static irqreturn_t dummy_handler (int irq, void *dev_id) |
265 | { | 273 | { |
266 | BUG(); | 274 | BUG(); |
267 | } | 275 | } |
276 | extern irqreturn_t handle_IPI (int irq, void *dev_id); | ||
268 | 277 | ||
269 | static struct irqaction ipi_irqaction = { | 278 | static struct irqaction ipi_irqaction = { |
270 | .handler = handle_IPI, | 279 | .handler = handle_IPI, |
@@ -277,6 +286,13 @@ static struct irqaction resched_irqaction = { | |||
277 | .flags = IRQF_DISABLED, | 286 | .flags = IRQF_DISABLED, |
278 | .name = "resched" | 287 | .name = "resched" |
279 | }; | 288 | }; |
289 | |||
290 | static struct irqaction tlb_irqaction = { | ||
291 | .handler = dummy_handler, | ||
292 | .flags = IRQF_DISABLED, | ||
293 | .name = "tlb_flush" | ||
294 | }; | ||
295 | |||
280 | #endif | 296 | #endif |
281 | 297 | ||
282 | void | 298 | void |
@@ -302,6 +318,7 @@ init_IRQ (void) | |||
302 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
303 | register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); | 319 | register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); |
304 | register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); | 320 | register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); |
321 | register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction); | ||
305 | #endif | 322 | #endif |
306 | #ifdef CONFIG_PERFMON | 323 | #ifdef CONFIG_PERFMON |
307 | pfm_init_percpu(); | 324 | pfm_init_percpu(); |