|
From: Jun S. <ju...@us...> - 2001-09-27 23:59:17
|
Update of /cvsroot/linux-mips/linux/arch/mips/vr4181/common
In directory usw-pr-cvs1:/tmp/cvs-serv12527/arch/mips/vr4181/common
Modified Files:
Makefile irq.c
Added Files:
int_handler.S
Log Message:
Re-write low-level irq dispatching code for vr4181/osprey. Pave the way for
the complete IRQ re-write.
--- NEW FILE: int_handler.S ---
/*
* linux/arch/mips/vr4181/common/int_handler.S
*
* Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
*
* Written by Ralf Baechle and Andreas Busse, modified for DECStation
* support by Paul Antoine and Harald Koerfgen.
*
* completly rewritten:
* Copyright (C) 1998 Harald Koerfgen
*
* Adapted to the VR4181 and almost entirely rewritten:
* Copyright (C) 1999 Bradley D. LaRonde and Michael Klar
*
* Clean up to conform to the new IRQ
* Copyright (C) 2001 MontaVista Software Inc.
* Author: Jun Sun, js...@mv... or js...@ju...
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
#include <asm/vr4181/vr4181.h>
/*
* [jsun]
* See include/asm/vr4181/irq.h for IRQ assignment and strategy.
*/
.text
.set noreorder
.align 5
NESTED(vr4181_handle_irq, PT_SIZE, ra)
.set noat
SAVE_ALL
CLI
.set at
.set noreorder
mfc0 t0, CP0_CAUSE
mfc0 t2, CP0_STATUS
and t0, t2
/* we check IP2 first; it happens most frequently */
andi t1, t0, STATUSF_IP2
bnez t1, ll_cpu_ip2
andi t1, t0, STATUSF_IP7 /* cpu timer */
bnez t1, ll_cputimer_irq
andi t1, t0, STATUSF_IP3
bnez t1, ll_cpu_ip3
andi t1, t0, STATUSF_IP4
bnez t1, ll_cpu_ip4
andi t1, t0, STATUSF_IP5
bnez t1, ll_cpu_ip5
andi t1, t0, STATUSF_IP6
bnez t1, ll_cpu_ip6
andi t1, t0, STATUSF_IP0 /* software int 0 */
bnez t1, ll_cpu_ip0
andi t1, t0, STATUSF_IP1 /* software int 1 */
bnez t1, ll_cpu_ip1
nop
.set reorder
do_spurious:
j spurious_interrupt
/*
* regular CPU irqs
*/
ll_cputimer_irq:
li a0, VR4181_IRQ_TIMER
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip0:
li a0, VR4181_IRQ_SW1
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip1:
li a0, VR4181_IRQ_SW2
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip3:
li a0, VR4181_IRQ_INT1
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip4:
li a0, VR4181_IRQ_INT2
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip5:
li a0, VR4181_IRQ_INT3
move a1, sp
jal do_IRQ
j ret_from_irq
ll_cpu_ip6:
li a0, VR4181_IRQ_INT4
move a1, sp
jal do_IRQ
j ret_from_irq
/*
* One of the sys irq has happend.
*
* In the interest of speed, we first determine in the following order
* which 16-irq block have pending interrupts:
* sysint1 (16 sources, including cascading intrs from GPIO)
* sysint2
* gpio (16 intr sources)
*
* Then we do binary search to find the exact interrupt source.
*/
ll_cpu_ip2:
lui t3,%hi(VR4181_SYSINT1REG)
lhu t0,%lo(VR4181_SYSINT1REG)(t3)
lhu t2,%lo(VR4181_MSYSINT1REG)(t3)
and t0, 0xfffb /* hack - remove RTC Long 1 intr */
and t0, t2
beqz t0, check_sysint2
/* check for GPIO interrupts */
andi t1, t0, 0x0100
bnez t1, check_gpio_int
/* so we have an interrupt in sysint1 which is not gpio int */
li a0, VR4181_SYS_IRQ_BASE - 1
j check_16
check_sysint2:
lhu t0,%lo(VR4181_SYSINT2REG)(t3)
lhu t2,%lo(VR4181_MSYSINT2REG)(t3)
and t0, 0xfffe /* hack - remove RTC Long 2 intr */
and t0, t2
li a0, VR4181_SYS_IRQ_BASE + 16 - 1
j check_16
check_gpio_int:
lui t3,%hi(VR4181_GPINTMSK)
lhu t0,%lo(VR4181_GPINTMSK)(t3)
lhu t2,%lo(VR4181_GPINTSTAT)(t3)
xori t0, 0xffff /* why? reverse logic? */
and t0, t2
li a0, VR4181_GPIO_IRQ_BASE - 1
j check_16
/*
* When we reach check_16, we have 16-bit status in t0 and base irq number
* in a0.
*/
check_16:
andi t1, t0, 0xff
bnez t1, check_8
srl t0, 8
addi a0, 8
j check_8
/*
* When we reach check_8, we have 8-bit status in t0 and base irq number
* in a0.
*/
check_8:
andi t1, t0, 0xf
bnez t1, check_4
srl t0, 4
addi a0, 4
j check_4
/*
* When we reach check_4, we have 4-bit status in t0 and base irq number
* in a0.
*/
check_4:
andi t0, t0, 0xf
beqz t0, do_spurious
loop:
andi t2, t0, 0x1
srl t0, 1
addi a0, 1
beqz t2, loop
found_it:
move a1, sp
jal do_IRQ
j ret_from_irq
END(vr4181_handle_irq)
Index: Makefile
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/vr4181/common/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Makefile 2001/09/22 16:35:15 1.2
+++ Makefile 2001/09/27 23:59:15 1.3
@@ -13,6 +13,6 @@
O_TARGET:= vr4181.o
-obj-y := irq.o serial.o time.o
+obj-y := irq.o int_handler.o serial.o time.o
include $(TOPDIR)/Rules.make
Index: irq.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/vr4181/common/irq.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- irq.c 2001/09/27 00:03:04 1.3
+++ irq.c 2001/09/27 23:59:15 1.4
@@ -26,13 +26,14 @@
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/gdb-stub.h>
+
#include <asm/vr4181/vr4181.h>
/* [jsun] HACK */
#define CONFIG_CPU_VR4181 y
#define DEVICE_IRQ_MASKL 0xffff
-extern asmlinkage void vr41xx_handle_irq(void);
+extern asmlinkage void vr4181_handle_irq(void);
extern void breakpoint(void);
// This is used elsewhere
@@ -465,7 +466,7 @@
void __init init_IRQ(void)
{
- set_except_vector(0, vr41xx_handle_irq);
+ set_except_vector(0, vr4181_handle_irq);
// Default all ICU IRQs to off ...
*VR4181_MSYSINT1REG = 0;
|