11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4SLinus Torvalds * for more details. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) 1992 Linus Torvalds 71da177e4SLinus Torvalds * Copyright (C) 1994 - 2001, 2003 Ralf Baechle 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds #include <linux/init.h> 101da177e4SLinus Torvalds #include <linux/interrupt.h> 111da177e4SLinus Torvalds #include <linux/kernel.h> 121da177e4SLinus Torvalds #include <linux/spinlock.h> 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #include <asm/i8259.h> 151da177e4SLinus Torvalds #include <asm/io.h> 161da177e4SLinus Torvalds #include <asm/jazz.h> 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds static DEFINE_SPINLOCK(r4030_lock); 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds static void enable_r4030_irq(unsigned int irq) 211da177e4SLinus Torvalds { 221da177e4SLinus Torvalds unsigned int mask = 1 << (irq - JAZZ_PARALLEL_IRQ); 231da177e4SLinus Torvalds unsigned long flags; 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds spin_lock_irqsave(&r4030_lock, flags); 261da177e4SLinus Torvalds mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE); 271da177e4SLinus Torvalds r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask); 281da177e4SLinus Torvalds spin_unlock_irqrestore(&r4030_lock, flags); 291da177e4SLinus Torvalds } 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds void disable_r4030_irq(unsigned int irq) 321da177e4SLinus Torvalds { 331da177e4SLinus Torvalds unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ)); 341da177e4SLinus Torvalds unsigned long flags; 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds spin_lock_irqsave(&r4030_lock, flags); 371da177e4SLinus Torvalds mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE); 381da177e4SLinus Torvalds r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask); 391da177e4SLinus Torvalds spin_unlock_irqrestore(&r4030_lock, flags); 401da177e4SLinus Torvalds } 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds static void end_r4030_irq(unsigned int irq) 431da177e4SLinus Torvalds { 441da177e4SLinus Torvalds if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 451da177e4SLinus Torvalds enable_r4030_irq(irq); 461da177e4SLinus Torvalds } 471da177e4SLinus Torvalds 4894dee171SRalf Baechle static struct irq_chip r4030_irq_type = { 498ab00b9aSRalf Baechle .typename = "R4030", 501603b5acSAtsushi Nemoto .ack = disable_r4030_irq, 511603b5acSAtsushi Nemoto .mask = disable_r4030_irq, 521603b5acSAtsushi Nemoto .mask_ack = disable_r4030_irq, 531603b5acSAtsushi Nemoto .unmask = enable_r4030_irq, 548ab00b9aSRalf Baechle .end = end_r4030_irq, 551da177e4SLinus Torvalds }; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds void __init init_r4030_ints(void) 581da177e4SLinus Torvalds { 591da177e4SLinus Torvalds int i; 601da177e4SLinus Torvalds 611603b5acSAtsushi Nemoto for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) 621417836eSAtsushi Nemoto set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); 651da177e4SLinus Torvalds r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ 661da177e4SLinus Torvalds r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */ 671da177e4SLinus Torvalds } 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds /* 701da177e4SLinus Torvalds * On systems with i8259-style interrupt controllers we assume for 711da177e4SLinus Torvalds * driver compatibility reasons interrupts 0 - 15 to be the i8259 721da177e4SLinus Torvalds * interrupts even if the hardware uses a different interrupt numbering. 731da177e4SLinus Torvalds */ 741da177e4SLinus Torvalds void __init arch_init_irq(void) 751da177e4SLinus Torvalds { 761da177e4SLinus Torvalds init_i8259_irqs(); /* Integrated i8259 */ 771da177e4SLinus Torvalds init_r4030_ints(); 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); 801da177e4SLinus Torvalds } 81e4ac58afSRalf Baechle 82937a8015SRalf Baechle static void loc_call(unsigned int irq, unsigned int mask) 83e4ac58afSRalf Baechle { 84e4ac58afSRalf Baechle r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 85e4ac58afSRalf Baechle r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); 86937a8015SRalf Baechle do_IRQ(irq); 87e4ac58afSRalf Baechle r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 88e4ac58afSRalf Baechle r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); 89e4ac58afSRalf Baechle } 90e4ac58afSRalf Baechle 91937a8015SRalf Baechle static void ll_local_dev(void) 92e4ac58afSRalf Baechle { 93e4ac58afSRalf Baechle switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { 94e4ac58afSRalf Baechle case 0: 95e4ac58afSRalf Baechle panic("Unimplemented loc_no_irq handler"); 96e4ac58afSRalf Baechle break; 97e4ac58afSRalf Baechle case 4: 98937a8015SRalf Baechle loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_PARALLEL); 99e4ac58afSRalf Baechle break; 100e4ac58afSRalf Baechle case 8: 101937a8015SRalf Baechle loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_FLOPPY); 102e4ac58afSRalf Baechle break; 103e4ac58afSRalf Baechle case 12: 104e4ac58afSRalf Baechle panic("Unimplemented loc_sound handler"); 105e4ac58afSRalf Baechle break; 106e4ac58afSRalf Baechle case 16: 107e4ac58afSRalf Baechle panic("Unimplemented loc_video handler"); 108e4ac58afSRalf Baechle break; 109e4ac58afSRalf Baechle case 20: 110937a8015SRalf Baechle loc_call(JAZZ_ETHERNET_IRQ, JAZZ_IE_ETHERNET); 111e4ac58afSRalf Baechle break; 112e4ac58afSRalf Baechle case 24: 113937a8015SRalf Baechle loc_call(JAZZ_SCSI_IRQ, JAZZ_IE_SCSI); 114e4ac58afSRalf Baechle break; 115e4ac58afSRalf Baechle case 28: 116937a8015SRalf Baechle loc_call(JAZZ_KEYBOARD_IRQ, JAZZ_IE_KEYBOARD); 117e4ac58afSRalf Baechle break; 118e4ac58afSRalf Baechle case 32: 119937a8015SRalf Baechle loc_call(JAZZ_MOUSE_IRQ, JAZZ_IE_MOUSE); 120e4ac58afSRalf Baechle break; 121e4ac58afSRalf Baechle case 36: 122937a8015SRalf Baechle loc_call(JAZZ_SERIAL1_IRQ, JAZZ_IE_SERIAL1); 123e4ac58afSRalf Baechle break; 124e4ac58afSRalf Baechle case 40: 125937a8015SRalf Baechle loc_call(JAZZ_SERIAL2_IRQ, JAZZ_IE_SERIAL2); 126e4ac58afSRalf Baechle break; 127e4ac58afSRalf Baechle } 128e4ac58afSRalf Baechle } 129e4ac58afSRalf Baechle 130937a8015SRalf Baechle asmlinkage void plat_irq_dispatch(void) 131e4ac58afSRalf Baechle { 132e4ac58afSRalf Baechle unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 133e4ac58afSRalf Baechle 134e4ac58afSRalf Baechle if (pending & IE_IRQ5) 135e4ac58afSRalf Baechle write_c0_compare(0); 136e4ac58afSRalf Baechle else if (pending & IE_IRQ4) { 137e4ac58afSRalf Baechle r4030_read_reg32(JAZZ_TIMER_REGISTER); 138937a8015SRalf Baechle do_IRQ(JAZZ_TIMER_IRQ); 139e4ac58afSRalf Baechle } else if (pending & IE_IRQ3) 140e4ac58afSRalf Baechle panic("Unimplemented ISA NMI handler"); 141e4ac58afSRalf Baechle else if (pending & IE_IRQ2) 142937a8015SRalf Baechle do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); 143e4ac58afSRalf Baechle else if (pending & IE_IRQ1) { 144937a8015SRalf Baechle ll_local_dev(); 145e4ac58afSRalf Baechle } else if (unlikely(pending & IE_IRQ0)) 146e4ac58afSRalf Baechle panic("Unimplemented local_dma handler"); 147e4ac58afSRalf Baechle else if (pending & IE_SW1) { 148e4ac58afSRalf Baechle clear_c0_cause(IE_SW1); 149e4ac58afSRalf Baechle panic("Unimplemented sw1 handler"); 150e4ac58afSRalf Baechle } else if (pending & IE_SW0) { 151e4ac58afSRalf Baechle clear_c0_cause(IE_SW0); 152e4ac58afSRalf Baechle panic("Unimplemented sw0 handler"); 153e4ac58afSRalf Baechle } 154e4ac58afSRalf Baechle } 155