1/* 2 * arch/mips/vr4181/common/int_handler.S 3 * 4 * Adapted to the VR4181 and almost entirely rewritten: 5 * Copyright (C) 1999 Bradley D. LaRonde and Michael Klar 6 * 7 * Clean up to conform to the new IRQ 8 * Copyright (C) 2001 MontaVista Software Inc. 9 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 * 15 */ 16 17#include <asm/asm.h> 18#include <asm/regdef.h> 19#include <asm/mipsregs.h> 20#include <asm/stackframe.h> 21 22#include <asm/vr4181/vr4181.h> 23 24/* 25 * [jsun] 26 * See include/asm/vr4181/irq.h for IRQ assignment and strategy. 27 */ 28 29 .text 30 .set noreorder 31 32 .align 5 33 NESTED(vr4181_handle_irq, PT_SIZE, ra) 34 35 .set noat 36 SAVE_ALL 37 CLI 38 39 .set at 40 .set noreorder 41 42 mfc0 t0, CP0_CAUSE 43 mfc0 t2, CP0_STATUS 44 45 and t0, t2 46 47 /* we check IP3 first; it happens most frequently */ 48 andi t1, t0, STATUSF_IP3 49 bnez t1, ll_cpu_ip3 50 andi t1, t0, STATUSF_IP2 51 bnez t1, ll_cpu_ip2 52 andi t1, t0, STATUSF_IP7 /* cpu timer */ 53 bnez t1, ll_cputimer_irq 54 andi t1, t0, STATUSF_IP4 55 bnez t1, ll_cpu_ip4 56 andi t1, t0, STATUSF_IP5 57 bnez t1, ll_cpu_ip5 58 andi t1, t0, STATUSF_IP6 59 bnez t1, ll_cpu_ip6 60 andi t1, t0, STATUSF_IP0 /* software int 0 */ 61 bnez t1, ll_cpu_ip0 62 andi t1, t0, STATUSF_IP1 /* software int 1 */ 63 bnez t1, ll_cpu_ip1 64 nop 65 66 .set reorder 67do_spurious: 68 j spurious_interrupt 69 70/* 71 * regular CPU irqs 72 */ 73ll_cputimer_irq: 74 li a0, VR4181_IRQ_TIMER 75 move a1, sp 76 jal do_IRQ 77 j ret_from_irq 78 79 80ll_cpu_ip0: 81 li a0, VR4181_IRQ_SW1 82 move a1, sp 83 jal do_IRQ 84 j ret_from_irq 85 86ll_cpu_ip1: 87 li a0, VR4181_IRQ_SW2 88 move a1, sp 89 jal do_IRQ 90 j ret_from_irq 91 92ll_cpu_ip3: 93 li a0, VR4181_IRQ_INT1 94 move a1, sp 95 jal do_IRQ 96 j ret_from_irq 97 98ll_cpu_ip4: 99 li a0, VR4181_IRQ_INT2 100 move a1, sp 101 jal do_IRQ 102 j ret_from_irq 103 104ll_cpu_ip5: 105 li a0, VR4181_IRQ_INT3 106 move a1, sp 107 jal do_IRQ 108 j ret_from_irq 109 110ll_cpu_ip6: 111 li a0, VR4181_IRQ_INT4 112 move a1, sp 113 jal do_IRQ 114 j ret_from_irq 115 116/* 117 * One of the sys irq has happend. 118 * 119 * In the interest of speed, we first determine in the following order 120 * which 16-irq block have pending interrupts: 121 * sysint1 (16 sources, including cascading intrs from GPIO) 122 * sysint2 123 * gpio (16 intr sources) 124 * 125 * Then we do binary search to find the exact interrupt source. 126 */ 127ll_cpu_ip2: 128 129 lui t3,%hi(VR4181_SYSINT1REG) 130 lhu t0,%lo(VR4181_SYSINT1REG)(t3) 131 lhu t2,%lo(VR4181_MSYSINT1REG)(t3) 132 and t0, 0xfffb /* hack - remove RTC Long 1 intr */ 133 and t0, t2 134 beqz t0, check_sysint2 135 136 /* check for GPIO interrupts */ 137 andi t1, t0, 0x0100 138 bnez t1, check_gpio_int 139 140 /* so we have an interrupt in sysint1 which is not gpio int */ 141 li a0, VR4181_SYS_IRQ_BASE - 1 142 j check_16 143 144check_sysint2: 145 146 lhu t0,%lo(VR4181_SYSINT2REG)(t3) 147 lhu t2,%lo(VR4181_MSYSINT2REG)(t3) 148 and t0, 0xfffe /* hack - remove RTC Long 2 intr */ 149 and t0, t2 150 li a0, VR4181_SYS_IRQ_BASE + 16 - 1 151 j check_16 152 153check_gpio_int: 154 lui t3,%hi(VR4181_GPINTMSK) 155 lhu t0,%lo(VR4181_GPINTMSK)(t3) 156 lhu t2,%lo(VR4181_GPINTSTAT)(t3) 157 xori t0, 0xffff /* why? reverse logic? */ 158 and t0, t2 159 li a0, VR4181_GPIO_IRQ_BASE - 1 160 j check_16 161 162/* 163 * When we reach check_16, we have 16-bit status in t0 and base irq number 164 * in a0. 165 */ 166check_16: 167 andi t1, t0, 0xff 168 bnez t1, check_8 169 170 srl t0, 8 171 addi a0, 8 172 j check_8 173 174/* 175 * When we reach check_8, we have 8-bit status in t0 and base irq number 176 * in a0. 177 */ 178check_8: 179 andi t1, t0, 0xf 180 bnez t1, check_4 181 182 srl t0, 4 183 addi a0, 4 184 j check_4 185 186/* 187 * When we reach check_4, we have 4-bit status in t0 and base irq number 188 * in a0. 189 */ 190check_4: 191 andi t0, t0, 0xf 192 beqz t0, do_spurious 193 194loop: 195 andi t2, t0, 0x1 196 srl t0, 1 197 addi a0, 1 198 beqz t2, loop 199 200found_it: 201 move a1, sp 202 jal do_IRQ 203 204 j ret_from_irq 205 206 END(vr4181_handle_irq) 207