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/irqinit_64.c | |
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/irqinit_64.c')
-rw-r--r-- | arch/x86/kernel/irqinit_64.c | 82 |
1 files changed, 81 insertions, 1 deletions
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 | } |