Commit 1ffee2cd authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] generalise PIC locations, PIT and FPU IRQ

parent a1b123ad
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <io_ports.h>
/* /*
* This is the 'legacy' 8259A Programmable Interrupt Controller, * This is the 'legacy' 8259A Programmable Interrupt Controller,
* present in the majority of PC/AT boxes. * present in the majority of PC/AT boxes.
...@@ -93,9 +95,9 @@ void disable_8259A_irq(unsigned int irq) ...@@ -93,9 +95,9 @@ void disable_8259A_irq(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags); spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= mask; cached_irq_mask |= mask;
if (irq & 8) if (irq & 8)
outb(cached_A1,0xA1); outb(cached_slave_mask, PIC_SLAVE_IMR);
else else
outb(cached_21,0x21); outb(cached_master_mask, PIC_MASTER_IMR);
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
} }
...@@ -107,9 +109,9 @@ void enable_8259A_irq(unsigned int irq) ...@@ -107,9 +109,9 @@ void enable_8259A_irq(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags); spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask &= mask; cached_irq_mask &= mask;
if (irq & 8) if (irq & 8)
outb(cached_A1,0xA1); outb(cached_slave_mask, PIC_SLAVE_IMR);
else else
outb(cached_21,0x21); outb(cached_master_mask, PIC_MASTER_IMR);
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
} }
...@@ -121,9 +123,9 @@ int i8259A_irq_pending(unsigned int irq) ...@@ -121,9 +123,9 @@ int i8259A_irq_pending(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags); spin_lock_irqsave(&i8259A_lock, flags);
if (irq < 8) if (irq < 8)
ret = inb(0x20) & mask; ret = inb(PIC_MASTER_CMD) & mask;
else else
ret = inb(0xA0) & (mask >> 8); ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
return ret; return ret;
...@@ -149,14 +151,14 @@ static inline int i8259A_irq_real(unsigned int irq) ...@@ -149,14 +151,14 @@ static inline int i8259A_irq_real(unsigned int irq)
int irqmask = 1<<irq; int irqmask = 1<<irq;
if (irq < 8) { if (irq < 8) {
outb(0x0B,0x20); /* ISR register */ outb(0x0B,PIC_MASTER_CMD); /* ISR register */
value = inb(0x20) & irqmask; value = inb(PIC_MASTER_CMD) & irqmask;
outb(0x0A,0x20); /* back to the IRR register */ outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */
return value; return value;
} }
outb(0x0B,0xA0); /* ISR register */ outb(0x0B,PIC_SLAVE_CMD); /* ISR register */
value = inb(0xA0) & (irqmask >> 8); value = inb(PIC_SLAVE_CMD) & (irqmask >> 8);
outb(0x0A,0xA0); /* back to the IRR register */ outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */
return value; return value;
} }
...@@ -193,14 +195,14 @@ void mask_and_ack_8259A(unsigned int irq) ...@@ -193,14 +195,14 @@ void mask_and_ack_8259A(unsigned int irq)
handle_real_irq: handle_real_irq:
if (irq & 8) { if (irq & 8) {
inb(0xA1); /* DUMMY - (do we need this?) */ inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */
outb(cached_A1,0xA1); outb(cached_slave_mask, PIC_SLAVE_IMR);
outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */
outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */
} else { } else {
inb(0x21); /* DUMMY - (do we need this?) */ inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */
outb(cached_21,0x21); outb(cached_master_mask, PIC_MASTER_IMR);
outb(0x60+irq,0x20); /* 'Specific EOI' to master */ outb(0x60+irq,PIC_MASTER_CMD); /* 'Specific EOI to master */
} }
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
return; return;
...@@ -272,26 +274,24 @@ void init_8259A(int auto_eoi) ...@@ -272,26 +274,24 @@ void init_8259A(int auto_eoi)
spin_lock_irqsave(&i8259A_lock, flags); spin_lock_irqsave(&i8259A_lock, flags);
outb(0xff, 0x21); /* mask all of 8259A-1 */ outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
outb(0xff, 0xA1); /* mask all of 8259A-2 */ outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
/* /*
* outb_p - this has to work on a wide range of PC hardware. * outb_p - this has to work on a wide range of PC hardware.
*/ */
outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ outb_p(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
if (auto_eoi) if (auto_eoi) /* master does Auto EOI */
outb_p(0x03, 0x21); /* master does Auto EOI */ outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
else else /* master expects normal EOI */
outb_p(0x01, 0x21); /* master expects normal EOI */ outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ outb_p(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */
outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
is to be investigated) */
if (auto_eoi) if (auto_eoi)
/* /*
* in AEOI mode we just have to mask the interrupt * in AEOI mode we just have to mask the interrupt
...@@ -303,8 +303,8 @@ void init_8259A(int auto_eoi) ...@@ -303,8 +303,8 @@ void init_8259A(int auto_eoi)
udelay(100); /* wait for 8259A to initialize */ udelay(100); /* wait for 8259A to initialize */
outb(cached_21, 0x21); /* restore master IRQ mask */ outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
outb(cached_A1, 0xA1); /* restore slave IRQ mask */ outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
} }
...@@ -321,11 +321,17 @@ void init_8259A(int auto_eoi) ...@@ -321,11 +321,17 @@ void init_8259A(int auto_eoi)
* be shot. * be shot.
*/ */
/*
* =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13!
*/
static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
{ {
extern void math_error(void *); extern void math_error(void *);
#ifndef CONFIG_X86_PC9800
outb(0,0xF0); outb(0,0xF0);
if (ignore_irq13 || !boot_cpu_data.hard_math) #endif
if (ignore_fpu_irq || !boot_cpu_data.hard_math)
return; return;
math_error((void *)regs->eip); math_error((void *)regs->eip);
} }
...@@ -334,7 +340,7 @@ static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) ...@@ -334,7 +340,7 @@ static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
* New motherboards sometimes make IRQ 13 be a PCI interrupt, * New motherboards sometimes make IRQ 13 be a PCI interrupt,
* so allow interrupt sharing. * so allow interrupt sharing.
*/ */
static struct irqaction irq13 = { math_error_irq, 0, 0, "fpu", NULL, NULL }; static struct irqaction fpu_irq = { math_error_irq, 0, 0, "fpu", NULL, NULL };
void __init init_ISA_irqs (void) void __init init_ISA_irqs (void)
{ {
...@@ -366,11 +372,11 @@ void __init init_ISA_irqs (void) ...@@ -366,11 +372,11 @@ void __init init_ISA_irqs (void)
static void setup_timer(void) static void setup_timer(void)
{ {
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ outb_p(0x34,PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10); udelay(10);
outb_p(LATCH & 0xff , 0x40); /* LSB */ outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
udelay(10); udelay(10);
outb(LATCH >> 8 , 0x40); /* MSB */ outb(LATCH >> 8 , PIT_CH0); /* MSB */
} }
static int timer_resume(struct device *dev, u32 level) static int timer_resume(struct device *dev, u32 level)
...@@ -437,5 +443,5 @@ void __init init_IRQ(void) ...@@ -437,5 +443,5 @@ void __init init_IRQ(void)
* original braindamaged IBM FERR coupling. * original braindamaged IBM FERR coupling.
*/ */
if (boot_cpu_data.hard_math && !cpu_has_fpu) if (boot_cpu_data.hard_math && !cpu_has_fpu)
setup_irq(13, &irq13); setup_irq(FPU_IRQ, &fpu_irq);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment