diff options
Diffstat (limited to 'arch')
-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 |