X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fjazz%2Firq.c;h=eef05093deb41b174a8b3e10fda4bfc85cf50d02;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=e81e23429ae428964ee719237472196864cd387b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index e81e23429..eef05093d 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -15,15 +15,11 @@ #include #include -extern asmlinkage void jazz_handle_int(void); - -static spinlock_t r4030_lock = SPIN_LOCK_UNLOCKED; - -extern asmlinkage void sni_rm200_pci_handle_int(void); +static DEFINE_SPINLOCK(r4030_lock); static void enable_r4030_irq(unsigned int irq) { - unsigned int mask = 1 << (irq - JAZZ_IE_PARALLEL); + unsigned int mask = 1 << (irq - JAZZ_PARALLEL_IRQ); unsigned long flags; spin_lock_irqsave(&r4030_lock, flags); @@ -42,7 +38,7 @@ static unsigned int startup_r4030_irq(unsigned int irq) void disable_r4030_irq(unsigned int irq) { - unsigned int mask = ~(1 << (irq - JAZZ_IE_PARALLEL)); + unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ)); unsigned long flags; spin_lock_irqsave(&r4030_lock, flags); @@ -59,15 +55,14 @@ static void end_r4030_irq(unsigned int irq) enable_r4030_irq(irq); } -static struct hw_interrupt_type r4030_irq_type = { - "R4030", - startup_r4030_irq, - shutdown_r4030_irq, - enable_r4030_irq, - disable_r4030_irq, - mask_and_ack_r4030_irq, - end_r4030_irq, - NULL +static struct irq_chip r4030_irq_type = { + .typename = "R4030", + .startup = startup_r4030_irq, + .shutdown = shutdown_r4030_irq, + .enable = enable_r4030_irq, + .disable = disable_r4030_irq, + .ack = mask_and_ack_r4030_irq, + .end = end_r4030_irq, }; void __init init_r4030_ints(void) @@ -78,7 +73,7 @@ void __init init_r4030_ints(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &r4030_irq_type; + irq_desc[i].chip = &r4030_irq_type; } r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); @@ -91,13 +86,84 @@ void __init init_r4030_ints(void) * driver compatibility reasons interrupts 0 - 15 to be the i8259 * interrupts even if the hardware uses a different interrupt numbering. */ -void __init init_IRQ (void) +void __init arch_init_irq(void) { - set_except_vector(0, jazz_handle_int); - - init_generic_irq(); init_i8259_irqs(); /* Integrated i8259 */ init_r4030_ints(); change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); } + +static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask) +{ + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); + do_IRQ(irq, regs); + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); +} + +static void ll_local_dev(struct pt_regs *regs) +{ + switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { + case 0: + panic("Unimplemented loc_no_irq handler"); + break; + case 4: + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL); + break; + case 8: + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY); + break; + case 12: + panic("Unimplemented loc_sound handler"); + break; + case 16: + panic("Unimplemented loc_video handler"); + break; + case 20: + loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET); + break; + case 24: + loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI); + break; + case 28: + loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD); + break; + case 32: + loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE); + break; + case 36: + loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1); + break; + case 40: + loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2); + break; + } +} + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & IE_IRQ5) + write_c0_compare(0); + else if (pending & IE_IRQ4) { + r4030_read_reg32(JAZZ_TIMER_REGISTER); + do_IRQ(JAZZ_TIMER_IRQ, regs); + } else if (pending & IE_IRQ3) + panic("Unimplemented ISA NMI handler"); + else if (pending & IE_IRQ2) + do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs); + else if (pending & IE_IRQ1) { + ll_local_dev(regs); + } else if (unlikely(pending & IE_IRQ0)) + panic("Unimplemented local_dma handler"); + else if (pending & IE_SW1) { + clear_c0_cause(IE_SW1); + panic("Unimplemented sw1 handler"); + } else if (pending & IE_SW0) { + clear_c0_cause(IE_SW0); + panic("Unimplemented sw0 handler"); + } +}