diff options
author | Pekka Enberg <penberg@cs.helsinki.fi> | 2009-04-09 04:52:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-10 08:35:56 -0400 |
commit | 320fd99672a44ece6d1cd0d838ba31c8ebbf5979 (patch) | |
tree | d85fecc5d3d648f4a259a7dcefd1c07b96053806 /arch/x86/kernel | |
parent | 598c73d250ffb112715aa48fb325d79e255be23b (diff) |
x86: unify native_init_IRQ() in irqinit_{32,64}.c
Impact: cleanup
Reviewed-by Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/irqinit_32.c | 53 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_64.c | 82 |
2 files changed, 115 insertions, 20 deletions
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 4488b713396e..a780de3ad5da 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/i8259.h> | 22 | #include <asm/i8259.h> |
23 | #include <asm/traps.h> | 23 | #include <asm/traps.h> |
24 | 24 | ||
25 | 25 | #ifdef CONFIG_X86_32 | |
26 | /* | 26 | /* |
27 | * Note that on a 486, we don't want to do a SIGFPE on an irq13 | 27 | * Note that on a 486, we don't want to do a SIGFPE on an irq13 |
28 | * as the irq is unreliable, and exception 16 works correctly | 28 | * as the irq is unreliable, and exception 16 works correctly |
@@ -52,6 +52,7 @@ static struct irqaction fpu_irq = { | |||
52 | .handler = math_error_irq, | 52 | .handler = math_error_irq, |
53 | .name = "fpu", | 53 | .name = "fpu", |
54 | }; | 54 | }; |
55 | #endif | ||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * IRQ2 is cascade interrupt to second interrupt controller | 58 | * IRQ2 is cascade interrupt to second interrupt controller |
@@ -155,24 +156,6 @@ static void __init smp_intr_init(void) | |||
155 | #endif /* CONFIG_SMP */ | 156 | #endif /* CONFIG_SMP */ |
156 | } | 157 | } |
157 | 158 | ||
158 | /** | ||
159 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors | ||
160 | * | ||
161 | * Description: | ||
162 | * Perform any necessary interrupt initialisation prior to setting up | ||
163 | * the "ordinary" interrupt call gates. For legacy reasons, the ISA | ||
164 | * interrupts should be initialised here if the machine emulates a PC | ||
165 | * in any way. | ||
166 | **/ | ||
167 | static void __init x86_quirk_pre_intr_init(void) | ||
168 | { | ||
169 | if (x86_quirks->arch_pre_intr_init) { | ||
170 | if (x86_quirks->arch_pre_intr_init()) | ||
171 | return; | ||
172 | } | ||
173 | init_ISA_irqs(); | ||
174 | } | ||
175 | |||
176 | static void __init apic_intr_init(void) | 159 | static void __init apic_intr_init(void) |
177 | { | 160 | { |
178 | smp_intr_init(); | 161 | smp_intr_init(); |
@@ -195,12 +178,36 @@ static void __init apic_intr_init(void) | |||
195 | #endif | 178 | #endif |
196 | } | 179 | } |
197 | 180 | ||
181 | #ifdef CONFIG_X86_32 | ||
182 | /** | ||
183 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors | ||
184 | * | ||
185 | * Description: | ||
186 | * Perform any necessary interrupt initialisation prior to setting up | ||
187 | * the "ordinary" interrupt call gates. For legacy reasons, the ISA | ||
188 | * interrupts should be initialised here if the machine emulates a PC | ||
189 | * in any way. | ||
190 | **/ | ||
191 | static void __init x86_quirk_pre_intr_init(void) | ||
192 | { | ||
193 | if (x86_quirks->arch_pre_intr_init) { | ||
194 | if (x86_quirks->arch_pre_intr_init()) | ||
195 | return; | ||
196 | } | ||
197 | init_ISA_irqs(); | ||
198 | } | ||
199 | #endif | ||
200 | |||
198 | void __init native_init_IRQ(void) | 201 | void __init native_init_IRQ(void) |
199 | { | 202 | { |
200 | int i; | 203 | int i; |
201 | 204 | ||
205 | #ifdef CONFIG_X86_32 | ||
202 | /* Execute any quirks before the call gates are initialised: */ | 206 | /* Execute any quirks before the call gates are initialised: */ |
203 | x86_quirk_pre_intr_init(); | 207 | x86_quirk_pre_intr_init(); |
208 | #else | ||
209 | init_ISA_irqs(); | ||
210 | #endif | ||
204 | 211 | ||
205 | /* | 212 | /* |
206 | * Cover the whole vector space, no vector can escape | 213 | * Cover the whole vector space, no vector can escape |
@@ -208,9 +215,15 @@ void __init native_init_IRQ(void) | |||
208 | * 'special' SMP interrupts) | 215 | * 'special' SMP interrupts) |
209 | */ | 216 | */ |
210 | for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { | 217 | for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { |
218 | #ifdef CONFIG_X86_32 | ||
211 | /* SYSCALL_VECTOR was reserved in trap_init. */ | 219 | /* SYSCALL_VECTOR was reserved in trap_init. */ |
212 | if (i != SYSCALL_VECTOR) | 220 | if (i != SYSCALL_VECTOR) |
213 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); | 221 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); |
222 | #else | ||
223 | /* IA32_SYSCALL_VECTOR was reserved in trap_init. */ | ||
224 | if (i != IA32_SYSCALL_VECTOR) | ||
225 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); | ||
226 | #endif | ||
214 | } | 227 | } |
215 | 228 | ||
216 | apic_intr_init(); | 229 | apic_intr_init(); |
@@ -218,6 +231,7 @@ void __init native_init_IRQ(void) | |||
218 | if (!acpi_ioapic) | 231 | if (!acpi_ioapic) |
219 | setup_irq(2, &irq2); | 232 | setup_irq(2, &irq2); |
220 | 233 | ||
234 | #ifdef CONFIG_X86_32 | ||
221 | /* | 235 | /* |
222 | * Call quirks after call gates are initialised (usually add in | 236 | * Call quirks after call gates are initialised (usually add in |
223 | * the architecture specific gates): | 237 | * the architecture specific gates): |
@@ -232,4 +246,5 @@ void __init native_init_IRQ(void) | |||
232 | setup_irq(FPU_IRQ, &fpu_irq); | 246 | setup_irq(FPU_IRQ, &fpu_irq); |
233 | 247 | ||
234 | irq_ctx_init(smp_processor_id()); | 248 | irq_ctx_init(smp_processor_id()); |
249 | #endif | ||
235 | } | 250 | } |
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index 61c9a922e80c..ed50e35ce97e 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c | |||
@@ -39,14 +39,46 @@ | |||
39 | * (these are usually mapped into the 0x30-0xff vector range) | 39 | * (these are usually mapped into the 0x30-0xff vector range) |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #ifdef CONFIG_X86_32 | ||
42 | /* | 43 | /* |
43 | * IRQ2 is cascade interrupt to second interrupt controller | 44 | * Note that on a 486, we don't want to do a SIGFPE on an irq13 |
45 | * as the irq is unreliable, and exception 16 works correctly | ||
46 | * (ie as explained in the intel literature). On a 386, you | ||
47 | * can't use exception 16 due to bad IBM design, so we have to | ||
48 | * rely on the less exact irq13. | ||
49 | * | ||
50 | * Careful.. Not only is IRQ13 unreliable, but it is also | ||
51 | * leads to races. IBM designers who came up with it should | ||
52 | * be shot. | ||
53 | */ | ||
54 | |||
55 | static irqreturn_t math_error_irq(int cpl, void *dev_id) | ||
56 | { | ||
57 | outb(0, 0xF0); | ||
58 | if (ignore_fpu_irq || !boot_cpu_data.hard_math) | ||
59 | return IRQ_NONE; | ||
60 | math_error((void __user *)get_irq_regs()->ip); | ||
61 | return IRQ_HANDLED; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * New motherboards sometimes make IRQ 13 be a PCI interrupt, | ||
66 | * so allow interrupt sharing. | ||
44 | */ | 67 | */ |
68 | static struct irqaction fpu_irq = { | ||
69 | .handler = math_error_irq, | ||
70 | .name = "fpu", | ||
71 | }; | ||
72 | #endif | ||
45 | 73 | ||
74 | /* | ||
75 | * IRQ2 is cascade interrupt to second interrupt controller | ||
76 | */ | ||
46 | static struct irqaction irq2 = { | 77 | static struct irqaction irq2 = { |
47 | .handler = no_action, | 78 | .handler = no_action, |
48 | .name = "cascade", | 79 | .name = "cascade", |
49 | }; | 80 | }; |
81 | |||
50 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 82 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
51 | [0 ... IRQ0_VECTOR - 1] = -1, | 83 | [0 ... IRQ0_VECTOR - 1] = -1, |
52 | [IRQ0_VECTOR] = 0, | 84 | [IRQ0_VECTOR] = 0, |
@@ -158,11 +190,36 @@ static void __init apic_intr_init(void) | |||
158 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); | 190 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); |
159 | } | 191 | } |
160 | 192 | ||
193 | #ifdef CONFIG_X86_32 | ||
194 | /** | ||
195 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors | ||
196 | * | ||
197 | * Description: | ||
198 | * Perform any necessary interrupt initialisation prior to setting up | ||
199 | * the "ordinary" interrupt call gates. For legacy reasons, the ISA | ||
200 | * interrupts should be initialised here if the machine emulates a PC | ||
201 | * in any way. | ||
202 | **/ | ||
203 | static void __init x86_quirk_pre_intr_init(void) | ||
204 | { | ||
205 | if (x86_quirks->arch_pre_intr_init) { | ||
206 | if (x86_quirks->arch_pre_intr_init()) | ||
207 | return; | ||
208 | } | ||
209 | init_ISA_irqs(); | ||
210 | } | ||
211 | #endif | ||
212 | |||
161 | void __init native_init_IRQ(void) | 213 | void __init native_init_IRQ(void) |
162 | { | 214 | { |
163 | int i; | 215 | int i; |
164 | 216 | ||
217 | #ifdef CONFIG_X86_32 | ||
218 | /* Execute any quirks before the call gates are initialised: */ | ||
219 | x86_quirk_pre_intr_init(); | ||
220 | #else | ||
165 | init_ISA_irqs(); | 221 | init_ISA_irqs(); |
222 | #endif | ||
166 | 223 | ||
167 | /* | 224 | /* |
168 | * Cover the whole vector space, no vector can escape | 225 | * Cover the whole vector space, no vector can escape |
@@ -170,13 +227,36 @@ void __init native_init_IRQ(void) | |||
170 | * 'special' SMP interrupts) | 227 | * 'special' SMP interrupts) |
171 | */ | 228 | */ |
172 | for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { | 229 | for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { |
230 | #ifdef CONFIG_X86_32 | ||
231 | /* SYSCALL_VECTOR was reserved in trap_init. */ | ||
232 | if (i != SYSCALL_VECTOR) | ||
233 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); | ||
234 | #else | ||
173 | /* IA32_SYSCALL_VECTOR was reserved in trap_init. */ | 235 | /* IA32_SYSCALL_VECTOR was reserved in trap_init. */ |
174 | if (i != IA32_SYSCALL_VECTOR) | 236 | if (i != IA32_SYSCALL_VECTOR) |
175 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); | 237 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); |
238 | #endif | ||
176 | } | 239 | } |
177 | 240 | ||
178 | apic_intr_init(); | 241 | apic_intr_init(); |
179 | 242 | ||
180 | if (!acpi_ioapic) | 243 | if (!acpi_ioapic) |
181 | setup_irq(2, &irq2); | 244 | setup_irq(2, &irq2); |
245 | |||
246 | #ifdef CONFIG_X86_32 | ||
247 | /* | ||
248 | * Call quirks after call gates are initialised (usually add in | ||
249 | * the architecture specific gates): | ||
250 | */ | ||
251 | x86_quirk_intr_init(); | ||
252 | |||
253 | /* | ||
254 | * External FPU? Set up irq13 if so, for | ||
255 | * original braindamaged IBM FERR coupling. | ||
256 | */ | ||
257 | if (boot_cpu_data.hard_math && !cpu_has_fpu) | ||
258 | setup_irq(FPU_IRQ, &fpu_irq); | ||
259 | |||
260 | irq_ctx_init(smp_processor_id()); | ||
261 | #endif | ||
182 | } | 262 | } |