Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) by Basler Vision Technologies AG |
| 3 | * Author: Thomas Koeller <thomas.koeller@baslereb.com> |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ |
| 19 | |
| 20 | #include <linux/errno.h> |
| 21 | #include <linux/init.h> |
| 22 | #include <linux/kernel_stat.h> |
| 23 | #include <linux/module.h> |
| 24 | #include <linux/signal.h> |
| 25 | #include <linux/sched.h> |
| 26 | #include <linux/types.h> |
| 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/ioport.h> |
| 29 | #include <linux/timex.h> |
| 30 | #include <linux/slab.h> |
| 31 | #include <linux/random.h> |
Jiri Slaby | 1977f03 | 2007-10-18 23:40:25 -0700 | [diff] [blame] | 32 | #include <linux/bitops.h> |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 33 | #include <asm/bootinfo.h> |
| 34 | #include <asm/io.h> |
| 35 | #include <asm/irq.h> |
| 36 | #include <asm/irq_cpu.h> |
| 37 | #include <asm/mipsregs.h> |
| 38 | #include <asm/system.h> |
| 39 | #include <asm/rm9k-ocd.h> |
| 40 | |
| 41 | #include <excite.h> |
| 42 | |
| 43 | extern asmlinkage void excite_handle_int(void); |
| 44 | |
| 45 | /* |
| 46 | * Initialize the interrupt handler |
| 47 | */ |
| 48 | void __init arch_init_irq(void) |
| 49 | { |
Atsushi Nemoto | 97dcb82 | 2007-01-08 02:14:29 +0900 | [diff] [blame] | 50 | mips_cpu_irq_init(); |
| 51 | rm7k_cpu_irq_init(); |
| 52 | rm9k_cpu_irq_init(); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 53 | |
| 54 | #ifdef CONFIG_KGDB |
| 55 | excite_kgdb_init(); |
| 56 | #endif |
| 57 | } |
| 58 | |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 59 | asmlinkage void plat_irq_dispatch(void) |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 60 | { |
| 61 | const u32 |
| 62 | interrupts = read_c0_cause() >> 8, |
| 63 | mask = ((read_c0_status() >> 8) & 0x000000ff) | |
| 64 | (read_c0_intcontrol() & 0x0000ff00), |
| 65 | pending = interrupts & mask; |
| 66 | u32 msgintflags, msgintmask, msgint; |
| 67 | |
| 68 | /* process timer interrupt */ |
| 69 | if (pending & (1 << TIMER_IRQ)) { |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 70 | do_IRQ(TIMER_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 71 | return; |
| 72 | } |
| 73 | |
| 74 | /* Process PCI interrupts */ |
| 75 | #if USB_IRQ < 10 |
| 76 | msgintflags = ocd_readl(INTP0Status0 + (USB_MSGINT / 0x20 * 0x10)); |
| 77 | msgintmask = ocd_readl(INTP0Mask0 + (USB_MSGINT / 0x20 * 0x10)); |
| 78 | msgint = msgintflags & msgintmask & (0x1 << (USB_MSGINT % 0x20)); |
| 79 | if ((pending & (1 << USB_IRQ)) && msgint) { |
| 80 | #else |
| 81 | if (pending & (1 << USB_IRQ)) { |
| 82 | #endif |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 83 | do_IRQ(USB_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 84 | return; |
| 85 | } |
| 86 | |
| 87 | /* Process TITAN interrupts */ |
| 88 | msgintflags = ocd_readl(INTP0Status0 + (TITAN_MSGINT / 0x20 * 0x10)); |
| 89 | msgintmask = ocd_readl(INTP0Mask0 + (TITAN_MSGINT / 0x20 * 0x10)); |
| 90 | msgint = msgintflags & msgintmask & (0x1 << (TITAN_MSGINT % 0x20)); |
| 91 | if ((pending & (1 << TITAN_IRQ)) && msgint) { |
| 92 | ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10)); |
| 93 | #if defined(CONFIG_KGDB) |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 94 | excite_kgdb_inthdl(); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 95 | #endif |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 96 | do_IRQ(TITAN_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 97 | return; |
| 98 | } |
| 99 | |
| 100 | /* Process FPGA line #0 interrupts */ |
| 101 | msgintflags = ocd_readl(INTP0Status0 + (FPGA0_MSGINT / 0x20 * 0x10)); |
| 102 | msgintmask = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10)); |
| 103 | msgint = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20)); |
| 104 | if ((pending & (1 << FPGA0_IRQ)) && msgint) { |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 105 | do_IRQ(FPGA0_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 106 | return; |
| 107 | } |
| 108 | |
| 109 | /* Process FPGA line #1 interrupts */ |
| 110 | msgintflags = ocd_readl(INTP0Status0 + (FPGA1_MSGINT / 0x20 * 0x10)); |
| 111 | msgintmask = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10)); |
| 112 | msgint = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20)); |
| 113 | if ((pending & (1 << FPGA1_IRQ)) && msgint) { |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 114 | do_IRQ(FPGA1_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 115 | return; |
| 116 | } |
| 117 | |
| 118 | /* Process PHY interrupts */ |
| 119 | msgintflags = ocd_readl(INTP0Status0 + (PHY_MSGINT / 0x20 * 0x10)); |
| 120 | msgintmask = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10)); |
| 121 | msgint = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20)); |
| 122 | if ((pending & (1 << PHY_IRQ)) && msgint) { |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 123 | do_IRQ(PHY_IRQ); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 124 | return; |
| 125 | } |
| 126 | |
| 127 | /* Process spurious interrupts */ |
Ralf Baechle | 937a801 | 2006-10-07 19:44:33 +0100 | [diff] [blame] | 128 | spurious_interrupt(); |
Ralf Baechle | 35189fa | 2006-06-18 16:39:46 +0100 | [diff] [blame] | 129 | } |