X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fkernel%2Fi8259.c;h=5ecd34ab8c2bba9ae70d15ff9803ead2957c72d9;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=f5d084a990d3bb869bfd34b1d053eb8c2c47523b;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index f5d084a99..5ecd34ab8 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -12,21 +12,18 @@ #include #include #include +#include #include #include #include #include -#include #include -#include #include #include #include #include -#include - /* * Common place to define all x86 IRQ vectors * @@ -130,13 +127,13 @@ void (*interrupt[NR_IRQS])(void) = { * moves to arch independent land */ -spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(i8259A_lock); static void end_8259A_irq (unsigned int irq) { if (irq > 256) { char var; - printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, current->thread_info); + printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, task_thread_info(current)); BUG(); } @@ -148,7 +145,7 @@ static void end_8259A_irq (unsigned int irq) #define shutdown_8259A_irq disable_8259A_irq -void mask_and_ack_8259A(unsigned int); +static void mask_and_ack_8259A(unsigned int); static unsigned int startup_8259A_irq(unsigned int irq) { @@ -157,14 +154,13 @@ static unsigned int startup_8259A_irq(unsigned int irq) } static struct hw_interrupt_type i8259A_irq_type = { - "XT-PIC", - startup_8259A_irq, - shutdown_8259A_irq, - enable_8259A_irq, - disable_8259A_irq, - mask_and_ack_8259A, - end_8259A_irq, - NULL + .typename = "XT-PIC", + .startup = startup_8259A_irq, + .shutdown = shutdown_8259A_irq, + .enable = enable_8259A_irq, + .disable = disable_8259A_irq, + .ack = mask_and_ack_8259A, + .end = end_8259A_irq, }; /* @@ -272,7 +268,7 @@ static inline int i8259A_irq_real(unsigned int irq) * first, _then_ send the EOI, and the order of EOI * to the two 8259s is important! */ -void mask_and_ack_8259A(unsigned int irq) +static void mask_and_ack_8259A(unsigned int irq) { unsigned int irqmask = 1 << irq; unsigned long flags; @@ -409,16 +405,28 @@ static int i8259A_resume(struct sys_device *dev) return 0; } -static int i8259A_suspend(struct sys_device *dev, u32 state) +static int i8259A_suspend(struct sys_device *dev, pm_message_t state) { save_ELCR(irq_trigger); return 0; } +static int i8259A_shutdown(struct sys_device *dev) +{ + /* Put the i8259A into a quiescent state that + * the kernel initialization code can get it + * out of. + */ + outb(0xff, 0x21); /* mask all of 8259A-1 */ + outb(0xff, 0xA1); /* mask all of 8259A-1 */ + return 0; +} + static struct sysdev_class i8259_sysdev_class = { set_kset_name("i8259"), .suspend = i8259A_suspend, .resume = i8259A_resume, + .shutdown = i8259A_shutdown, }; static struct sys_device device_i8259A = { @@ -475,9 +483,19 @@ void spurious_interrupt(void); void error_interrupt(void); void reschedule_interrupt(void); void call_function_interrupt(void); -void invalidate_interrupt(void); - -static void setup_timer(void) +void invalidate_interrupt0(void); +void invalidate_interrupt1(void); +void invalidate_interrupt2(void); +void invalidate_interrupt3(void); +void invalidate_interrupt4(void); +void invalidate_interrupt5(void); +void invalidate_interrupt6(void); +void invalidate_interrupt7(void); +void thermal_interrupt(void); +void threshold_interrupt(void); +void i8254_timer_resume(void); + +static void setup_timer_hardware(void) { outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ udelay(10); @@ -488,12 +506,17 @@ static void setup_timer(void) static int timer_resume(struct sys_device *dev) { - setup_timer(); + setup_timer_hardware(); return 0; } +void i8254_timer_resume(void) +{ + setup_timer_hardware(); +} + static struct sysdev_class timer_sysclass = { - set_kset_name("timer"), + set_kset_name("timer_pit"), .resume = timer_resume, }; @@ -526,10 +549,9 @@ void __init init_IRQ(void) int vector = FIRST_EXTERNAL_VECTOR + i; if (i >= NR_IRQS) break; - if (vector != IA32_SYSCALL_VECTOR && vector != KDB_VECTOR) { + if (vector != IA32_SYSCALL_VECTOR) set_intr_gate(vector, interrupt[i]); } - } #ifdef CONFIG_SMP /* @@ -544,12 +566,21 @@ void __init init_IRQ(void) */ set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - /* IPI for invalidation */ - set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); + /* IPIs for invalidation */ + set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); + set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); /* IPI for generic function call */ set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); #endif + set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); + set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); #ifdef CONFIG_X86_LOCAL_APIC /* self generated IPI for local APIC timer */ @@ -564,7 +595,7 @@ void __init init_IRQ(void) * Set the clock to HZ Hz, we already have a valid * vector now: */ - setup_timer(); + setup_timer_hardware(); if (!acpi_ioapic) setup_irq(2, &irq2);