diff options
author | Dimitri Sivanich <sivanich@sgi.com> | 2009-03-04 13:56:05 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-04 14:25:37 -0500 |
commit | acaabe795a62bba089c185917af86b44654313dc (patch) | |
tree | bbdf5eb8a7eb2a1a8c40bfc332db6d328a64b043 /arch/x86/kernel | |
parent | f254f3909efaf59ca2d0f408de2d044dace60706 (diff) |
x86: UV, SGI RTC: add generic system vector
This patch allocates a system interrupt vector for various platform
specific uses.
Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: john stultz <johnstul@us.ibm.com>
LKML-Reference: <20090304185605.GA24419@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 2 | ||||
-rw-r--r-- | arch/x86/kernel/irq.c | 34 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_64.c | 3 |
4 files changed, 42 insertions, 0 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 83d1836b9467..7ba4621c0dfa 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -984,6 +984,8 @@ apicinterrupt UV_BAU_MESSAGE \ | |||
984 | #endif | 984 | #endif |
985 | apicinterrupt LOCAL_TIMER_VECTOR \ | 985 | apicinterrupt LOCAL_TIMER_VECTOR \ |
986 | apic_timer_interrupt smp_apic_timer_interrupt | 986 | apic_timer_interrupt smp_apic_timer_interrupt |
987 | apicinterrupt GENERIC_INTERRUPT_VECTOR \ | ||
988 | generic_interrupt smp_generic_interrupt | ||
987 | 989 | ||
988 | #ifdef CONFIG_SMP | 990 | #ifdef CONFIG_SMP |
989 | apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \ | 991 | apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \ |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index f13ca1650aaf..b864341dcc45 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -15,6 +15,9 @@ | |||
15 | 15 | ||
16 | atomic_t irq_err_count; | 16 | atomic_t irq_err_count; |
17 | 17 | ||
18 | /* Function pointer for generic interrupt vector handling */ | ||
19 | void (*generic_interrupt_extension)(void) = NULL; | ||
20 | |||
18 | /* | 21 | /* |
19 | * 'what should we do if we get a hw irq event on an illegal vector'. | 22 | * 'what should we do if we get a hw irq event on an illegal vector'. |
20 | * each architecture has to answer this themselves. | 23 | * each architecture has to answer this themselves. |
@@ -56,6 +59,12 @@ static int show_other_interrupts(struct seq_file *p) | |||
56 | seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); | 59 | seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); |
57 | seq_printf(p, " Local timer interrupts\n"); | 60 | seq_printf(p, " Local timer interrupts\n"); |
58 | #endif | 61 | #endif |
62 | if (generic_interrupt_extension) { | ||
63 | seq_printf(p, "PLT: "); | ||
64 | for_each_online_cpu(j) | ||
65 | seq_printf(p, "%10u ", irq_stats(j)->generic_irqs); | ||
66 | seq_printf(p, " Platform interrupts\n"); | ||
67 | } | ||
59 | #ifdef CONFIG_SMP | 68 | #ifdef CONFIG_SMP |
60 | seq_printf(p, "RES: "); | 69 | seq_printf(p, "RES: "); |
61 | for_each_online_cpu(j) | 70 | for_each_online_cpu(j) |
@@ -163,6 +172,8 @@ u64 arch_irq_stat_cpu(unsigned int cpu) | |||
163 | #ifdef CONFIG_X86_LOCAL_APIC | 172 | #ifdef CONFIG_X86_LOCAL_APIC |
164 | sum += irq_stats(cpu)->apic_timer_irqs; | 173 | sum += irq_stats(cpu)->apic_timer_irqs; |
165 | #endif | 174 | #endif |
175 | if (generic_interrupt_extension) | ||
176 | sum += irq_stats(cpu)->generic_irqs; | ||
166 | #ifdef CONFIG_SMP | 177 | #ifdef CONFIG_SMP |
167 | sum += irq_stats(cpu)->irq_resched_count; | 178 | sum += irq_stats(cpu)->irq_resched_count; |
168 | sum += irq_stats(cpu)->irq_call_count; | 179 | sum += irq_stats(cpu)->irq_call_count; |
@@ -226,4 +237,27 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs) | |||
226 | return 1; | 237 | return 1; |
227 | } | 238 | } |
228 | 239 | ||
240 | /* | ||
241 | * Handler for GENERIC_INTERRUPT_VECTOR. | ||
242 | */ | ||
243 | void smp_generic_interrupt(struct pt_regs *regs) | ||
244 | { | ||
245 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
246 | |||
247 | ack_APIC_irq(); | ||
248 | |||
249 | exit_idle(); | ||
250 | |||
251 | irq_enter(); | ||
252 | |||
253 | inc_irq_stat(generic_irqs); | ||
254 | |||
255 | if (generic_interrupt_extension) | ||
256 | generic_interrupt_extension(); | ||
257 | |||
258 | irq_exit(); | ||
259 | |||
260 | set_irq_regs(old_regs); | ||
261 | } | ||
262 | |||
229 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 263 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); |
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 50b8c3a3006c..bc1326105448 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
@@ -175,6 +175,9 @@ void __init native_init_IRQ(void) | |||
175 | /* self generated IPI for local APIC timer */ | 175 | /* self generated IPI for local APIC timer */ |
176 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); | 176 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); |
177 | 177 | ||
178 | /* generic IPI for platform specific use */ | ||
179 | alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt); | ||
180 | |||
178 | /* IPI vectors for APIC spurious and error interrupts */ | 181 | /* IPI vectors for APIC spurious and error interrupts */ |
179 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); | 182 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); |
180 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); | 183 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); |
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index da481a1e3f30..c7a49e0ffbfb 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c | |||
@@ -147,6 +147,9 @@ static void __init apic_intr_init(void) | |||
147 | /* self generated IPI for local APIC timer */ | 147 | /* self generated IPI for local APIC timer */ |
148 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); | 148 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); |
149 | 149 | ||
150 | /* generic IPI for platform specific use */ | ||
151 | alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt); | ||
152 | |||
150 | /* IPI vectors for APIC spurious and error interrupts */ | 153 | /* IPI vectors for APIC spurious and error interrupts */ |
151 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); | 154 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); |
152 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); | 155 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); |