diff options
| -rw-r--r-- | arch/arm/common/gic.c | 75 | ||||
| -rw-r--r-- | arch/arm/include/asm/entry-macro-multi.S | 7 | ||||
| -rw-r--r-- | arch/arm/include/asm/hardirq.h | 3 | ||||
| -rw-r--r-- | arch/arm/include/asm/hardware/entry-macro-gic.S | 19 | ||||
| -rw-r--r-- | arch/arm/include/asm/localtimer.h | 11 | ||||
| -rw-r--r-- | arch/arm/include/asm/smp.h | 5 | ||||
| -rw-r--r-- | arch/arm/kernel/irq.c | 3 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 32 | ||||
| -rw-r--r-- | arch/arm/mach-exynos4/include/mach/entry-macro.S | 7 | ||||
| -rw-r--r-- | arch/arm/mach-msm/board-msm8x60.c | 11 | ||||
| -rw-r--r-- | arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 73 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/include/mach/entry-macro.S | 14 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/entry-intc.S | 3 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/include/mach/entry-macro.S | 3 |
14 files changed, 88 insertions, 178 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 666b278e56d7..bbea0168779b 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
| @@ -28,10 +28,14 @@ | |||
| 28 | #include <linux/smp.h> | 28 | #include <linux/smp.h> |
| 29 | #include <linux/cpumask.h> | 29 | #include <linux/cpumask.h> |
| 30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
| 31 | #include <linux/interrupt.h> | ||
| 32 | #include <linux/percpu.h> | ||
| 33 | #include <linux/slab.h> | ||
| 31 | 34 | ||
| 32 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
| 33 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
| 34 | #include <asm/hardware/gic.h> | 37 | #include <asm/hardware/gic.h> |
| 38 | #include <asm/localtimer.h> | ||
| 35 | 39 | ||
| 36 | static DEFINE_SPINLOCK(irq_controller_lock); | 40 | static DEFINE_SPINLOCK(irq_controller_lock); |
| 37 | 41 | ||
| @@ -255,6 +259,32 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | |||
| 255 | irq_set_chained_handler(irq, gic_handle_cascade_irq); | 259 | irq_set_chained_handler(irq, gic_handle_cascade_irq); |
| 256 | } | 260 | } |
| 257 | 261 | ||
| 262 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 263 | #define gic_ppi_handler percpu_timer_handler | ||
| 264 | #else | ||
| 265 | static 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 | |||
| 279 | static 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 | |||
| 286 | static struct irqaction *ppi_irqaction; | ||
| 287 | |||
| 258 | static void __init gic_dist_init(struct gic_chip_data *gic, | 288 | static void __init gic_dist_init(struct gic_chip_data *gic, |
| 259 | unsigned int irq_start) | 289 | unsigned int irq_start) |
| 260 | { | 290 | { |
| @@ -262,6 +292,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
| 262 | u32 cpumask; | 292 | u32 cpumask; |
| 263 | void __iomem *base = gic->dist_base; | 293 | void __iomem *base = gic->dist_base; |
| 264 | u32 cpu = 0; | 294 | u32 cpu = 0; |
| 295 | u32 nrppis = 0, ppi_base = 0; | ||
| 265 | 296 | ||
| 266 | #ifdef CONFIG_SMP | 297 | #ifdef CONFIG_SMP |
| 267 | cpu = cpu_logical_map(smp_processor_id()); | 298 | cpu = cpu_logical_map(smp_processor_id()); |
| @@ -283,6 +314,33 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
| 283 | gic_irqs = 1020; | 314 | gic_irqs = 1020; |
| 284 | 315 | ||
| 285 | /* | 316 | /* |
| 317 | * Nobody would be insane enough to use PPIs on a secondary | ||
| 318 | * GIC, right? | ||
| 319 | */ | ||
| 320 | if (gic == &gic_data[0]) { | ||
| 321 | nrppis = (32 - irq_start) & 31; | ||
| 322 | |||
| 323 | /* The GIC only supports up to 16 PPIs. */ | ||
| 324 | if (nrppis > 16) | ||
| 325 | BUG(); | ||
| 326 | |||
| 327 | 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 | } | ||
| 339 | |||
| 340 | pr_info("Configuring GIC with %d sources (%d PPIs)\n", | ||
| 341 | gic_irqs, (gic == &gic_data[0]) ? nrppis : 0); | ||
| 342 | |||
| 343 | /* | ||
| 286 | * Set all global interrupts to be level triggered, active low. | 344 | * Set all global interrupts to be level triggered, active low. |
| 287 | */ | 345 | */ |
| 288 | for (i = 32; i < gic_irqs; i += 16) | 346 | for (i = 32; i < gic_irqs; i += 16) |
| @@ -317,7 +375,22 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
| 317 | /* | 375 | /* |
| 318 | * Setup the Linux IRQ subsystem. | 376 | * Setup the Linux IRQ subsystem. |
| 319 | */ | 377 | */ |
| 320 | for (i = irq_start; i < irq_limit; i++) { | 378 | for (i = 0; i < nrppis; i++) { |
| 379 | int ppi = i + ppi_base; | ||
| 380 | int err; | ||
| 381 | |||
| 382 | irq_set_percpu_devid(ppi); | ||
| 383 | irq_set_chip_and_handler(ppi, &gic_chip, | ||
| 384 | handle_percpu_devid_irq); | ||
| 385 | irq_set_chip_data(ppi, gic); | ||
| 386 | 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 | } | ||
| 392 | |||
| 393 | for (i = irq_start + nrppis; i < irq_limit; i++) { | ||
| 321 | irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); | 394 | irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); |
| 322 | irq_set_chip_data(i, gic); | 395 | irq_set_chip_data(i, gic); |
| 323 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | 396 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S index 2f1e2098dfe7..88d61815f0c0 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S | |||
| @@ -25,13 +25,6 @@ | |||
| 25 | movne r1, sp | 25 | movne r1, sp |
| 26 | adrne lr, BSYM(1b) | 26 | adrne lr, BSYM(1b) |
| 27 | bne do_IPI | 27 | bne do_IPI |
| 28 | |||
| 29 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 30 | test_for_ltirq r0, r2, r6, lr | ||
| 31 | movne r0, sp | ||
| 32 | adrne lr, BSYM(1b) | ||
| 33 | bne do_local_timer | ||
| 34 | #endif | ||
| 35 | #endif | 28 | #endif |
| 36 | 9997: | 29 | 9997: |
| 37 | .endm | 30 | .endm |
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 89ad1805e579..ddf07a92a6c8 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h | |||
| @@ -9,9 +9,6 @@ | |||
| 9 | 9 | ||
| 10 | typedef struct { | 10 | typedef struct { |
| 11 | unsigned int __softirq_pending; | 11 | unsigned int __softirq_pending; |
| 12 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 13 | unsigned int local_timer_irqs; | ||
| 14 | #endif | ||
| 15 | #ifdef CONFIG_SMP | 12 | #ifdef CONFIG_SMP |
| 16 | unsigned int ipi_irqs[NR_IPI]; | 13 | unsigned int ipi_irqs[NR_IPI]; |
| 17 | #endif | 14 | #endif |
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S index c115b82fe80a..74ebc803904d 100644 --- a/arch/arm/include/asm/hardware/entry-macro-gic.S +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S | |||
| @@ -22,15 +22,11 @@ | |||
| 22 | * interrupt controller spec. To wit: | 22 | * interrupt controller spec. To wit: |
| 23 | * | 23 | * |
| 24 | * Interrupts 0-15 are IPI | 24 | * Interrupts 0-15 are IPI |
| 25 | * 16-28 are reserved | 25 | * 16-31 are local. We allow 30 to be used for the watchdog. |
| 26 | * 29-31 are local. We allow 30 to be used for the watchdog. | ||
| 27 | * 32-1020 are global | 26 | * 32-1020 are global |
| 28 | * 1021-1022 are reserved | 27 | * 1021-1022 are reserved |
| 29 | * 1023 is "spurious" (no interrupt) | 28 | * 1023 is "spurious" (no interrupt) |
| 30 | * | 29 | * |
| 31 | * For now, we ignore all local interrupts so only return an interrupt if it's | ||
| 32 | * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. | ||
| 33 | * | ||
| 34 | * A simple read from the controller will tell us the number of the highest | 30 | * A simple read from the controller will tell us the number of the highest |
| 35 | * priority enabled interrupt. We then just need to check whether it is in the | 31 | * priority enabled interrupt. We then just need to check whether it is in the |
| 36 | * valid range for an IRQ (30-1020 inclusive). | 32 | * valid range for an IRQ (30-1020 inclusive). |
| @@ -43,7 +39,7 @@ | |||
| 43 | 39 | ||
| 44 | ldr \tmp, =1021 | 40 | ldr \tmp, =1021 |
| 45 | bic \irqnr, \irqstat, #0x1c00 | 41 | bic \irqnr, \irqstat, #0x1c00 |
| 46 | cmp \irqnr, #29 | 42 | cmp \irqnr, #15 |
| 47 | cmpcc \irqnr, \irqnr | 43 | cmpcc \irqnr, \irqnr |
| 48 | cmpne \irqnr, \tmp | 44 | cmpne \irqnr, \tmp |
| 49 | cmpcs \irqnr, \irqnr | 45 | cmpcs \irqnr, \irqnr |
| @@ -62,14 +58,3 @@ | |||
| 62 | strcc \irqstat, [\base, #GIC_CPU_EOI] | 58 | strcc \irqstat, [\base, #GIC_CPU_EOI] |
| 63 | cmpcs \irqnr, \irqnr | 59 | cmpcs \irqnr, \irqnr |
| 64 | .endm | 60 | .endm |
| 65 | |||
| 66 | /* As above, this assumes that irqstat and base are preserved.. */ | ||
| 67 | |||
| 68 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 69 | bic \irqnr, \irqstat, #0x1c00 | ||
| 70 | mov \tmp, #0 | ||
| 71 | cmp \irqnr, #29 | ||
| 72 | moveq \tmp, #1 | ||
| 73 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
| 74 | cmp \tmp, #0 | ||
| 75 | .endm | ||
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 3306f281333c..5c8acb4c4040 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #ifndef __ASM_ARM_LOCALTIMER_H | 10 | #ifndef __ASM_ARM_LOCALTIMER_H |
| 11 | #define __ASM_ARM_LOCALTIMER_H | 11 | #define __ASM_ARM_LOCALTIMER_H |
| 12 | 12 | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | |||
| 13 | struct clock_event_device; | 15 | struct clock_event_device; |
| 14 | 16 | ||
| 15 | /* | 17 | /* |
| @@ -18,14 +20,9 @@ struct clock_event_device; | |||
| 18 | void percpu_timer_setup(void); | 20 | void percpu_timer_setup(void); |
| 19 | 21 | ||
| 20 | /* | 22 | /* |
| 21 | * Called from assembly, this is the local timer IRQ handler | 23 | * Per-cpu timer IRQ handler |
| 22 | */ | ||
| 23 | asmlinkage void do_local_timer(struct pt_regs *); | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Called from C code | ||
| 27 | */ | 24 | */ |
| 28 | void handle_local_timer(struct pt_regs *); | 25 | irqreturn_t percpu_timer_handler(int irq, void *dev_id); |
| 29 | 26 | ||
| 30 | #ifdef CONFIG_LOCAL_TIMERS | 27 | #ifdef CONFIG_LOCAL_TIMERS |
| 31 | 28 | ||
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 0a17b62538c2..1e5717afc4ac 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h | |||
| @@ -99,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu); | |||
| 99 | extern void arch_send_call_function_single_ipi(int cpu); | 99 | extern void arch_send_call_function_single_ipi(int cpu); |
| 100 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); | 100 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
| 101 | 101 | ||
| 102 | /* | ||
| 103 | * show local interrupt info | ||
| 104 | */ | ||
| 105 | extern void show_local_irqs(struct seq_file *, int); | ||
| 106 | |||
| 107 | #endif /* ifndef __ASM_ARM_SMP_H */ | 102 | #endif /* ifndef __ASM_ARM_SMP_H */ |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 53919b230e8b..7cb29261249a 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
| @@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
| 59 | #ifdef CONFIG_SMP | 59 | #ifdef CONFIG_SMP |
| 60 | show_ipi_list(p, prec); | 60 | show_ipi_list(p, prec); |
| 61 | #endif | 61 | #endif |
| 62 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 63 | show_local_irqs(p, prec); | ||
| 64 | #endif | ||
| 65 | seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); | 62 | seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); |
| 66 | return 0; | 63 | return 0; |
| 67 | } | 64 | } |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 35417d0fb8ab..917ed2fa4e4c 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -457,10 +457,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu) | |||
| 457 | for (i = 0; i < NR_IPI; i++) | 457 | for (i = 0; i < NR_IPI; i++) |
| 458 | sum += __get_irq_stat(cpu, ipi_irqs[i]); | 458 | sum += __get_irq_stat(cpu, ipi_irqs[i]); |
| 459 | 459 | ||
| 460 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 461 | sum += __get_irq_stat(cpu, local_timer_irqs); | ||
| 462 | #endif | ||
| 463 | |||
| 464 | return sum; | 460 | return sum; |
| 465 | } | 461 | } |
| 466 | 462 | ||
| @@ -478,34 +474,16 @@ static void ipi_timer(void) | |||
| 478 | } | 474 | } |
| 479 | 475 | ||
| 480 | #ifdef CONFIG_LOCAL_TIMERS | 476 | #ifdef CONFIG_LOCAL_TIMERS |
| 481 | asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) | 477 | irqreturn_t percpu_timer_handler(int irq, void *dev_id) |
| 482 | { | ||
| 483 | handle_local_timer(regs); | ||
| 484 | } | ||
| 485 | |||
| 486 | void handle_local_timer(struct pt_regs *regs) | ||
| 487 | { | 478 | { |
| 488 | struct pt_regs *old_regs = set_irq_regs(regs); | 479 | struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); |
| 489 | int cpu = smp_processor_id(); | ||
| 490 | 480 | ||
| 491 | if (local_timer_ack()) { | 481 | if (local_timer_ack()) { |
| 492 | __inc_irq_stat(cpu, local_timer_irqs); | 482 | evt->event_handler(evt); |
| 493 | ipi_timer(); | 483 | return IRQ_HANDLED; |
| 494 | } | 484 | } |
| 495 | 485 | ||
| 496 | set_irq_regs(old_regs); | 486 | return IRQ_NONE; |
| 497 | } | ||
| 498 | |||
| 499 | void show_local_irqs(struct seq_file *p, int prec) | ||
| 500 | { | ||
| 501 | unsigned int cpu; | ||
| 502 | |||
| 503 | seq_printf(p, "%*s: ", prec, "LOC"); | ||
| 504 | |||
| 505 | for_each_present_cpu(cpu) | ||
| 506 | seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs)); | ||
| 507 | |||
| 508 | seq_printf(p, " Local timer interrupts\n"); | ||
| 509 | } | 487 | } |
| 510 | #endif | 488 | #endif |
| 511 | 489 | ||
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index d7a1e281ce7a..006a4f4c65c6 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S | |||
| @@ -55,7 +55,7 @@ | |||
| 55 | 55 | ||
| 56 | bic \irqnr, \irqstat, #0x1c00 | 56 | bic \irqnr, \irqstat, #0x1c00 |
| 57 | 57 | ||
| 58 | cmp \irqnr, #29 | 58 | cmp \irqnr, #15 |
| 59 | cmpcc \irqnr, \irqnr | 59 | cmpcc \irqnr, \irqnr |
| 60 | cmpne \irqnr, \tmp | 60 | cmpne \irqnr, \tmp |
| 61 | cmpcs \irqnr, \irqnr | 61 | cmpcs \irqnr, \irqnr |
| @@ -76,8 +76,3 @@ | |||
| 76 | strcc \irqstat, [\base, #GIC_CPU_EOI] | 76 | strcc \irqstat, [\base, #GIC_CPU_EOI] |
| 77 | cmpcs \irqnr, \irqnr | 77 | cmpcs \irqnr, \irqnr |
| 78 | .endm | 78 | .endm |
| 79 | |||
| 80 | /* As above, this assumes that irqstat and base are preserved.. */ | ||
| 81 | |||
| 82 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 83 | .endm | ||
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 1163b6fd05d2..d70a2f643613 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c | |||
| @@ -36,8 +36,6 @@ static void __init msm8x60_map_io(void) | |||
| 36 | 36 | ||
| 37 | static void __init msm8x60_init_irq(void) | 37 | static void __init msm8x60_init_irq(void) |
| 38 | { | 38 | { |
| 39 | unsigned int i; | ||
| 40 | |||
| 41 | gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, | 39 | gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, |
| 42 | (void *)MSM_QGIC_CPU_BASE); | 40 | (void *)MSM_QGIC_CPU_BASE); |
| 43 | 41 | ||
| @@ -49,15 +47,6 @@ static void __init msm8x60_init_irq(void) | |||
| 49 | */ | 47 | */ |
| 50 | if (!machine_is_msm8x60_sim()) | 48 | if (!machine_is_msm8x60_sim()) |
| 51 | writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET); | 49 | writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET); |
| 52 | |||
| 53 | /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet | ||
| 54 | * as they are configured as level, which does not play nice with | ||
| 55 | * handle_percpu_irq. | ||
| 56 | */ | ||
| 57 | for (i = GIC_PPI_START; i < GIC_SPI_START; i++) { | ||
| 58 | if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE) | ||
| 59 | irq_set_handler(i, handle_percpu_irq); | ||
| 60 | } | ||
| 61 | } | 50 | } |
| 62 | 51 | ||
| 63 | static void __init msm8x60_init(void) | 52 | static void __init msm8x60_init(void) |
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S index 12467157afb9..717076f3ca73 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S | |||
| @@ -8,81 +8,10 @@ | |||
| 8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <mach/hardware.h> | 11 | #include <asm/hardware/entry-macro-gic.S> |
| 12 | #include <asm/hardware/gic.h> | ||
| 13 | 12 | ||
| 14 | .macro disable_fiq | 13 | .macro disable_fiq |
| 15 | .endm | 14 | .endm |
| 16 | 15 | ||
| 17 | .macro get_irqnr_preamble, base, tmp | ||
| 18 | ldr \base, =gic_cpu_base_addr | ||
| 19 | ldr \base, [\base] | ||
| 20 | .endm | ||
| 21 | |||
| 22 | .macro arch_ret_to_user, tmp1, tmp2 | 16 | .macro arch_ret_to_user, tmp1, tmp2 |
| 23 | .endm | 17 | .endm |
| 24 | |||
| 25 | /* | ||
| 26 | * The interrupt numbering scheme is defined in the | ||
| 27 | * interrupt controller spec. To wit: | ||
| 28 | * | ||
| 29 | * Migrated the code from ARM MP port to be more consistent | ||
| 30 | * with interrupt processing , the following still holds true | ||
| 31 | * however, all interrupts are treated the same regardless of | ||
| 32 | * if they are local IPI or PPI | ||
| 33 | * | ||
| 34 | * Interrupts 0-15 are IPI | ||
| 35 | * 16-31 are PPI | ||
| 36 | * (16-18 are the timers) | ||
| 37 | * 32-1020 are global | ||
| 38 | * 1021-1022 are reserved | ||
| 39 | * 1023 is "spurious" (no interrupt) | ||
| 40 | * | ||
| 41 | * A simple read from the controller will tell us the number of the | ||
| 42 | * highest priority enabled interrupt. We then just need to check | ||
| 43 | * whether it is in the valid range for an IRQ (0-1020 inclusive). | ||
| 44 | * | ||
| 45 | * Base ARM code assumes that the local (private) peripheral interrupts | ||
| 46 | * are not valid, we treat them differently, in that the privates are | ||
| 47 | * handled like normal shared interrupts with the exception that only | ||
| 48 | * one processor can register the interrupt and the handler must be | ||
| 49 | * the same for all processors. | ||
| 50 | */ | ||
| 51 | |||
| 52 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 53 | |||
| 54 | ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU, | ||
| 55 | 9-0 =int # */ | ||
| 56 | |||
| 57 | bic \irqnr, \irqstat, #0x1c00 @mask src | ||
| 58 | cmp \irqnr, #15 | ||
| 59 | ldr \tmp, =1021 | ||
| 60 | cmpcc \irqnr, \irqnr | ||
| 61 | cmpne \irqnr, \tmp | ||
| 62 | cmpcs \irqnr, \irqnr | ||
| 63 | |||
| 64 | .endm | ||
| 65 | |||
| 66 | /* We assume that irqstat (the raw value of the IRQ acknowledge | ||
| 67 | * register) is preserved from the macro above. | ||
| 68 | * If there is an IPI, we immediately signal end of interrupt on the | ||
| 69 | * controller, since this requires the original irqstat value which | ||
| 70 | * we won't easily be able to recreate later. | ||
| 71 | */ | ||
| 72 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
| 73 | bic \irqnr, \irqstat, #0x1c00 | ||
| 74 | cmp \irqnr, #16 | ||
| 75 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
| 76 | cmpcs \irqnr, \irqnr | ||
| 77 | .endm | ||
| 78 | |||
| 79 | /* As above, this assumes that irqstat and base are preserved.. */ | ||
| 80 | |||
| 81 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 82 | bic \irqnr, \irqstat, #0x1c00 | ||
| 83 | mov \tmp, #0 | ||
| 84 | cmp \irqnr, #16 | ||
| 85 | moveq \tmp, #1 | ||
| 86 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
| 87 | cmp \tmp, #0 | ||
| 88 | .endm | ||
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index ceb8b7e593d7..feb90a10945a 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S | |||
| @@ -78,7 +78,7 @@ | |||
| 78 | 4401: ldr \irqstat, [\base, #GIC_CPU_INTACK] | 78 | 4401: ldr \irqstat, [\base, #GIC_CPU_INTACK] |
| 79 | ldr \tmp, =1021 | 79 | ldr \tmp, =1021 |
| 80 | bic \irqnr, \irqstat, #0x1c00 | 80 | bic \irqnr, \irqstat, #0x1c00 |
| 81 | cmp \irqnr, #29 | 81 | cmp \irqnr, #15 |
| 82 | cmpcc \irqnr, \irqnr | 82 | cmpcc \irqnr, \irqnr |
| 83 | cmpne \irqnr, \tmp | 83 | cmpne \irqnr, \tmp |
| 84 | cmpcs \irqnr, \irqnr | 84 | cmpcs \irqnr, \irqnr |
| @@ -101,18 +101,6 @@ | |||
| 101 | it cs | 101 | it cs |
| 102 | cmpcs \irqnr, \irqnr | 102 | cmpcs \irqnr, \irqnr |
| 103 | .endm | 103 | .endm |
| 104 | |||
| 105 | /* As above, this assumes that irqstat and base are preserved */ | ||
| 106 | |||
| 107 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 108 | bic \irqnr, \irqstat, #0x1c00 | ||
| 109 | mov \tmp, #0 | ||
| 110 | cmp \irqnr, #29 | ||
| 111 | itt eq | ||
| 112 | moveq \tmp, #1 | ||
| 113 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
| 114 | cmp \tmp, #0 | ||
| 115 | .endm | ||
| 116 | #endif /* CONFIG_SMP */ | 104 | #endif /* CONFIG_SMP */ |
| 117 | 105 | ||
| 118 | #else /* MULTI_OMAP2 */ | 106 | #else /* MULTI_OMAP2 */ |
diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S index cac0a7ae2084..1a1c00ca39a2 100644 --- a/arch/arm/mach-shmobile/entry-intc.S +++ b/arch/arm/mach-shmobile/entry-intc.S | |||
| @@ -51,7 +51,4 @@ | |||
| 51 | .macro test_for_ipi, irqnr, irqstat, base, tmp | 51 | .macro test_for_ipi, irqnr, irqstat, base, tmp |
| 52 | .endm | 52 | .endm |
| 53 | 53 | ||
| 54 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 55 | .endm | ||
| 56 | |||
| 57 | arch_irq_handler shmobile_handle_irq_intc | 54 | arch_irq_handler shmobile_handle_irq_intc |
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S index d791f10eeac7..8d4a416d4285 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S | |||
| @@ -27,8 +27,5 @@ | |||
| 27 | .macro test_for_ipi, irqnr, irqstat, base, tmp | 27 | .macro test_for_ipi, irqnr, irqstat, base, tmp |
| 28 | .endm | 28 | .endm |
| 29 | 29 | ||
| 30 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
| 31 | .endm | ||
| 32 | |||
| 33 | .macro arch_ret_to_user, tmp1, tmp2 | 30 | .macro arch_ret_to_user, tmp1, tmp2 |
| 34 | .endm | 31 | .endm |
