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 4294dee171SRalf Baechle static struct irq_chip r4030_irq_type = { 43*70d21cdeSAtsushi Nemoto .name = "R4030", 441603b5acSAtsushi Nemoto .ack = disable_r4030_irq, 451603b5acSAtsushi Nemoto .mask = disable_r4030_irq, 461603b5acSAtsushi Nemoto .mask_ack = disable_r4030_irq, 471603b5acSAtsushi Nemoto .unmask = enable_r4030_irq, 481da177e4SLinus Torvalds }; 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds void __init init_r4030_ints(void) 511da177e4SLinus Torvalds { 521da177e4SLinus Torvalds int i; 531da177e4SLinus Torvalds 541603b5acSAtsushi Nemoto for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) 551417836eSAtsushi Nemoto set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); 581da177e4SLinus Torvalds r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ 591da177e4SLinus Torvalds r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */ 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds /* 631da177e4SLinus Torvalds * On systems with i8259-style interrupt controllers we assume for 641da177e4SLinus Torvalds * driver compatibility reasons interrupts 0 - 15 to be the i8259 651da177e4SLinus Torvalds * interrupts even if the hardware uses a different interrupt numbering. 661da177e4SLinus Torvalds */ 671da177e4SLinus Torvalds void __init arch_init_irq(void) 681da177e4SLinus Torvalds { 691da177e4SLinus Torvalds init_i8259_irqs(); /* Integrated i8259 */ 701da177e4SLinus Torvalds init_r4030_ints(); 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); 731da177e4SLinus Torvalds } 74e4ac58afSRalf Baechle 75937a8015SRalf Baechle static void loc_call(unsigned int irq, unsigned int mask) 76e4ac58afSRalf Baechle { 77e4ac58afSRalf Baechle r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 78e4ac58afSRalf Baechle r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); 79937a8015SRalf Baechle do_IRQ(irq); 80e4ac58afSRalf Baechle r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 81e4ac58afSRalf Baechle r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); 82e4ac58afSRalf Baechle } 83e4ac58afSRalf Baechle 84937a8015SRalf Baechle static void ll_local_dev(void) 85e4ac58afSRalf Baechle { 86e4ac58afSRalf Baechle switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { 87e4ac58afSRalf Baechle case 0: 88e4ac58afSRalf Baechle panic("Unimplemented loc_no_irq handler"); 89e4ac58afSRalf Baechle break; 90e4ac58afSRalf Baechle case 4: 91937a8015SRalf Baechle loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_PARALLEL); 92e4ac58afSRalf Baechle break; 93e4ac58afSRalf Baechle case 8: 94937a8015SRalf Baechle loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_FLOPPY); 95e4ac58afSRalf Baechle break; 96e4ac58afSRalf Baechle case 12: 97e4ac58afSRalf Baechle panic("Unimplemented loc_sound handler"); 98e4ac58afSRalf Baechle break; 99e4ac58afSRalf Baechle case 16: 100e4ac58afSRalf Baechle panic("Unimplemented loc_video handler"); 101e4ac58afSRalf Baechle break; 102e4ac58afSRalf Baechle case 20: 103937a8015SRalf Baechle loc_call(JAZZ_ETHERNET_IRQ, JAZZ_IE_ETHERNET); 104e4ac58afSRalf Baechle break; 105e4ac58afSRalf Baechle case 24: 106937a8015SRalf Baechle loc_call(JAZZ_SCSI_IRQ, JAZZ_IE_SCSI); 107e4ac58afSRalf Baechle break; 108e4ac58afSRalf Baechle case 28: 109937a8015SRalf Baechle loc_call(JAZZ_KEYBOARD_IRQ, JAZZ_IE_KEYBOARD); 110e4ac58afSRalf Baechle break; 111e4ac58afSRalf Baechle case 32: 112937a8015SRalf Baechle loc_call(JAZZ_MOUSE_IRQ, JAZZ_IE_MOUSE); 113e4ac58afSRalf Baechle break; 114e4ac58afSRalf Baechle case 36: 115937a8015SRalf Baechle loc_call(JAZZ_SERIAL1_IRQ, JAZZ_IE_SERIAL1); 116e4ac58afSRalf Baechle break; 117e4ac58afSRalf Baechle case 40: 118937a8015SRalf Baechle loc_call(JAZZ_SERIAL2_IRQ, JAZZ_IE_SERIAL2); 119e4ac58afSRalf Baechle break; 120e4ac58afSRalf Baechle } 121e4ac58afSRalf Baechle } 122e4ac58afSRalf Baechle 123937a8015SRalf Baechle asmlinkage void plat_irq_dispatch(void) 124e4ac58afSRalf Baechle { 125e4ac58afSRalf Baechle unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 126e4ac58afSRalf Baechle 127e4ac58afSRalf Baechle if (pending & IE_IRQ5) 128e4ac58afSRalf Baechle write_c0_compare(0); 129e4ac58afSRalf Baechle else if (pending & IE_IRQ4) { 130e4ac58afSRalf Baechle r4030_read_reg32(JAZZ_TIMER_REGISTER); 131937a8015SRalf Baechle do_IRQ(JAZZ_TIMER_IRQ); 132e4ac58afSRalf Baechle } else if (pending & IE_IRQ3) 133e4ac58afSRalf Baechle panic("Unimplemented ISA NMI handler"); 134e4ac58afSRalf Baechle else if (pending & IE_IRQ2) 135937a8015SRalf Baechle do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); 136e4ac58afSRalf Baechle else if (pending & IE_IRQ1) { 137937a8015SRalf Baechle ll_local_dev(); 138e4ac58afSRalf Baechle } else if (unlikely(pending & IE_IRQ0)) 139e4ac58afSRalf Baechle panic("Unimplemented local_dma handler"); 140e4ac58afSRalf Baechle else if (pending & IE_SW1) { 141e4ac58afSRalf Baechle clear_c0_cause(IE_SW1); 142e4ac58afSRalf Baechle panic("Unimplemented sw1 handler"); 143e4ac58afSRalf Baechle } else if (pending & IE_SW0) { 144e4ac58afSRalf Baechle clear_c0_cause(IE_SW0); 145e4ac58afSRalf Baechle panic("Unimplemented sw0 handler"); 146e4ac58afSRalf Baechle } 147e4ac58afSRalf Baechle } 148