forked from Minki/linux
[MIPS] Rewrite all the assembler interrupt handlers to C.
Saves like 1,600 lines of code, is way easier to debug, compilers frequently do a better job than the cut and paste type of handlers many boards had. And finally having all the stuff done in a single place also means alot of bug potencial for the MT ASE is gone. The only surviving handler in assembler is the DECstation one; I hope Maciej will rewrite it. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
d35d473c25
commit
e4ac58afdf
@ -6,7 +6,7 @@
|
||||
# Makefile for the Alchemy Au1000 CPU, generic files.
|
||||
#
|
||||
|
||||
obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
|
||||
obj-y += prom.o irq.o puts.o time.o reset.o \
|
||||
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
|
||||
sleeper.o cputable.o dma.o dbdma.o gpio.o
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: ppopov@mvista.com
|
||||
*
|
||||
* Interrupt dispatcher for Au1000 boards.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.set macro
|
||||
.set noat
|
||||
.align 5
|
||||
|
||||
NESTED(au1000_IRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI # Important: mark KERNEL mode !
|
||||
|
||||
mfc0 t0,CP0_CAUSE # get pending interrupts
|
||||
mfc0 t1,CP0_STATUS # get enabled interrupts
|
||||
and t0,t1 # isolate allowed ones
|
||||
|
||||
andi t0,0xff00 # isolate pending bits
|
||||
beqz t0, 3f # spurious interrupt
|
||||
|
||||
andi a0, t0, CAUSEF_IP7
|
||||
beq a0, zero, 1f
|
||||
move a0, sp
|
||||
jal mips_timer_interrupt
|
||||
j ret_from_irq
|
||||
|
||||
1:
|
||||
andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0
|
||||
beq a0, zero, 2f
|
||||
move a0,sp
|
||||
jal intc0_req0_irqdispatch
|
||||
j ret_from_irq
|
||||
2:
|
||||
andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1
|
||||
beq a0, zero, 3f
|
||||
move a0,sp
|
||||
jal intc0_req1_irqdispatch
|
||||
j ret_from_irq
|
||||
3:
|
||||
andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0
|
||||
beq a0, zero, 4f
|
||||
move a0,sp
|
||||
jal intc1_req0_irqdispatch
|
||||
j ret_from_irq
|
||||
4:
|
||||
andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1
|
||||
beq a0, zero, 5f
|
||||
move a0, sp
|
||||
jal intc1_req1_irqdispatch
|
||||
j ret_from_irq
|
||||
|
||||
5:
|
||||
move a0, sp
|
||||
jal spurious_interrupt
|
||||
j ret_from_irq
|
||||
END(au1000_IRQ)
|
@ -66,7 +66,6 @@
|
||||
#define EXT_INTC1_REQ1 5 /* IP 5 */
|
||||
#define MIPS_TIMER_IP 7 /* IP 7 */
|
||||
|
||||
extern asmlinkage void au1000_IRQ(void);
|
||||
extern void set_debug_traps(void);
|
||||
extern irq_cpustat_t irq_stat [NR_CPUS];
|
||||
|
||||
@ -446,7 +445,6 @@ void __init arch_init_irq(void)
|
||||
extern int au1xxx_ic0_nr_irqs;
|
||||
|
||||
cp0_status = read_c0_status();
|
||||
set_except_vector(0, au1000_IRQ);
|
||||
|
||||
/* Initialize interrupt controllers to a safe state.
|
||||
*/
|
||||
@ -661,3 +659,21 @@ restore_au1xxx_intctl(void)
|
||||
au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
|
||||
if (pending & CAUSEF_IP7)
|
||||
mips_timer_interrupt(regs);
|
||||
else if (pending & CAUSEF_IP2)
|
||||
intc0_req0_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP3)
|
||||
intc0_req1_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP4)
|
||||
intc1_req0_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP5)
|
||||
intc1_req1_irqdispatch(regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for the Cobalt micro systems family specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := irq.o int-handler.o reset.o setup.o
|
||||
obj-y := irq.o reset.o setup.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += console.o
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
|
||||
* Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/mach-cobalt/cobalt.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.align 5
|
||||
NESTED(cobalt_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
|
||||
PTR_LA ra, ret_from_irq
|
||||
move a0, sp
|
||||
j cobalt_irq
|
||||
|
||||
END(cobalt_handle_int)
|
@ -20,8 +20,6 @@
|
||||
|
||||
#include <asm/mach-cobalt/cobalt.h>
|
||||
|
||||
extern void cobalt_handle_int(void);
|
||||
|
||||
/*
|
||||
* We have two types of interrupts that we handle, ones that come in through
|
||||
* the CPU interrupt lines, and ones that come in on the via chip. The CPU
|
||||
@ -79,7 +77,7 @@ static inline void via_pic_irq(struct pt_regs *regs)
|
||||
do_IRQ(irq, regs);
|
||||
}
|
||||
|
||||
asmlinkage void cobalt_irq(struct pt_regs *regs)
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned pending;
|
||||
|
||||
@ -122,8 +120,6 @@ void __init arch_init_irq(void)
|
||||
*/
|
||||
GALILEO_OUTL(0, GT_INTRMASK_OFS);
|
||||
|
||||
set_except_vector(0, cobalt_handle_int);
|
||||
|
||||
init_i8259_irqs(); /* 0 ... 15 */
|
||||
mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y += setup.o irq.o int-handler.o nile4_pic.o
|
||||
obj-y += setup.o irq.o nile4_pic.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
|
||||
*
|
||||
* Based on arch/mips/sgi/kernel/indyIRQ.S
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
|
||||
*
|
||||
* Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
|
||||
* Sony Software Development Center Europe (SDCE), Brussels
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/* A lot of complication here is taken away because:
|
||||
*
|
||||
* 1) We handle one interrupt and return, sitting in a loop and moving across
|
||||
* all the pending IRQ bits in the cause register is _NOT_ the answer, the
|
||||
* common case is one pending IRQ so optimize in that direction.
|
||||
*
|
||||
* 2) We need not check against bits in the status register IRQ mask, that
|
||||
* would make this routine slow as hell.
|
||||
*
|
||||
* 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
|
||||
* between like BSD spl() brain-damage.
|
||||
*
|
||||
* Furthermore, the IRQs on the INDY look basically (barring software IRQs
|
||||
* which we don't use at all) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Local IRQ level zero
|
||||
* 3 Local IRQ level one
|
||||
* 4 8254 Timer zero
|
||||
* 5 8254 Timer one
|
||||
* 6 Bus Error
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Local IRQ zero
|
||||
* Local IRQ one
|
||||
* Bus Error
|
||||
* 8254 Timer zero
|
||||
* Lowest ---- 8254 Timer one
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(ddbIRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 s0, CP0_CAUSE # get irq mask
|
||||
|
||||
#if 1
|
||||
mfc0 t2,CP0_STATUS # get enabled interrupts
|
||||
and s0,t2 # isolate allowed ones
|
||||
#endif
|
||||
/* First we check for r4k counter/timer IRQ. */
|
||||
andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
|
||||
|
||||
/* Wheee, local level zero interrupt. */
|
||||
jal ddb_local0_irqdispatch
|
||||
move a0, sp # delay slot
|
||||
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
|
||||
|
||||
/* Wheee, local level one interrupt. */
|
||||
move a0, sp
|
||||
jal ddb_local1_irqdispatch
|
||||
nop
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
1:
|
||||
beq a0, zero, 1f
|
||||
nop
|
||||
|
||||
/* Wheee, an asynchronous bus error... */
|
||||
move a0, sp
|
||||
jal ddb_buserror_irq
|
||||
nop
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
1:
|
||||
/* Here by mistake? This is possible, what can happen
|
||||
* is that by the time we take the exception the IRQ
|
||||
* pin goes low, so just leave if this is the case.
|
||||
*/
|
||||
andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
|
||||
beq a0, zero, 1f
|
||||
|
||||
/* Must be one of the 8254 timers... */
|
||||
move a0, sp
|
||||
jal ddb_8254timer_irq
|
||||
nop
|
||||
1:
|
||||
j ret_from_irq
|
||||
nop
|
||||
END(ddbIRQ)
|
@ -21,8 +21,6 @@
|
||||
#include <asm/ddb5xxx/ddb5074.h>
|
||||
|
||||
|
||||
extern asmlinkage void ddbIRQ(void);
|
||||
|
||||
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
||||
|
||||
#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
|
||||
@ -90,7 +88,7 @@ static void m1543_irq_setup(void)
|
||||
|
||||
}
|
||||
|
||||
void ddb_local0_irqdispatch(struct pt_regs *regs)
|
||||
static void ddb_local0_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
u32 mask;
|
||||
int nile4_irq;
|
||||
@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
void ddb_local1_irqdispatch(void)
|
||||
static void ddb_local1_irqdispatch(void)
|
||||
{
|
||||
printk("ddb_local1_irqdispatch called\n");
|
||||
}
|
||||
|
||||
void ddb_buserror_irq(void)
|
||||
static void ddb_buserror_irq(void)
|
||||
{
|
||||
printk("ddb_buserror_irq called\n");
|
||||
}
|
||||
|
||||
void ddb_8254timer_irq(void)
|
||||
static void ddb_8254timer_irq(void)
|
||||
{
|
||||
printk("ddb_8254timer_irq called\n");
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & CAUSEF_IP2)
|
||||
ddb_local0_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP3)
|
||||
ddb_local1_irqdispatch();
|
||||
else if (pending & CAUSEF_IP6)
|
||||
ddb_buserror_irq();
|
||||
else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
|
||||
ddb_8254timer_irq();
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/* setup cascade interrupts */
|
||||
setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade);
|
||||
setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
|
||||
|
||||
set_except_vector(0, ddbIRQ);
|
||||
|
||||
nile4_irq_setup(NILE4_IRQ_BASE);
|
||||
m1543_irq_setup();
|
||||
init_i8259_irqs();
|
||||
|
@ -3,7 +3,7 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o
|
||||
obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o
|
||||
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for ddb5476
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
#include <asm/ddb5xxx/ddb5476.h>
|
||||
|
||||
/*
|
||||
* first level interrupt dispatcher for ocelot board -
|
||||
* We check for the timer first, then check PCI ints A and D.
|
||||
* Then check for serial IRQ and fall through.
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ddb5476_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
.set noreorder
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cpu_ip7
|
||||
andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */
|
||||
bnez t1, ll_cpu_ip2
|
||||
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
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
// jal spurious_interrupt
|
||||
// j ret_from_irq
|
||||
move a0, sp
|
||||
jal vrc5476_irq_dispatch
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
|
||||
ll_cpu_ip0:
|
||||
li a0, CPU_IRQ_BASE + 0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip1:
|
||||
li a0, CPU_IRQ_BASE + 1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip2: /* jump to second-level dispatching */
|
||||
move a0, sp
|
||||
jal vrc5476_irq_dispatch
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip3:
|
||||
li a0, CPU_IRQ_BASE + 3
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip4:
|
||||
li a0, CPU_IRQ_BASE + 4
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip5:
|
||||
li a0, CPU_IRQ_BASE + 5
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip6:
|
||||
li a0, CPU_IRQ_BASE + 6
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip7:
|
||||
li a0, CPU_IRQ_BASE + 7
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
END(ddb5476_handle_int)
|
@ -110,11 +110,36 @@ static void nile4_irq_setup(void)
|
||||
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
||||
static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
|
||||
|
||||
extern asmlinkage void ddb5476_handle_int(void);
|
||||
extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
|
||||
extern void mips_cpu_irq_init(u32 irq_base);
|
||||
extern void vrc5476_irq_init(u32 irq_base);
|
||||
|
||||
extern void vrc5476_irq_dispatch(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP7)
|
||||
do_IRQ(CPU_IRQ_BASE + 7, regs);
|
||||
else if (pending & STATUSF_IP2)
|
||||
vrc5476_irq_dispatch(regs);
|
||||
else if (pending & STATUSF_IP3)
|
||||
do_IRQ(CPU_IRQ_BASE + 3, regs);
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(CPU_IRQ_BASE + 4, regs);
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(CPU_IRQ_BASE + 5, regs);
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(CPU_IRQ_BASE + 6, regs);
|
||||
else if (pending & STATUSF_IP0)
|
||||
do_IRQ(CPU_IRQ_BASE, regs);
|
||||
else if (pending & STATUSF_IP1)
|
||||
do_IRQ(CPU_IRQ_BASE + 1, regs);
|
||||
|
||||
vrc5476_irq_dispatch(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/* hardware initialization */
|
||||
@ -137,7 +162,4 @@ void __init arch_init_irq(void)
|
||||
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
|
||||
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
|
||||
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
|
||||
|
||||
/* setup the grandpa intr vector */
|
||||
set_except_vector(0, ddb5476_handle_int);
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ vrc5476_irq_init(u32 base)
|
||||
}
|
||||
|
||||
|
||||
asmlinkage void
|
||||
void
|
||||
vrc5476_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
u32 mask;
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for NEC DDB-Vrc5477 board
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o
|
||||
obj-y += irq.o irq_5477.o setup.o lcd44780.o
|
||||
|
||||
obj-$(CONFIG_RUNTIME_DEBUG) += debug.o
|
||||
obj-$(CONFIG_KGDB) += kgdb_io.o
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for ddb5477
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/ddb5xxx/ddb5477.h>
|
||||
|
||||
/*
|
||||
* first level interrupt dispatcher for ocelot board -
|
||||
* We check for the timer first, then check PCI ints A and D.
|
||||
* Then check for serial IRQ and fall through.
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ddb5477_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
.set noreorder
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cputimer_irq
|
||||
andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
|
||||
bnez t1, ll_vrc5477_irq
|
||||
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
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
jal spurious_interrupt
|
||||
j ret_from_irq
|
||||
END(ddb5477_handle_int)
|
||||
|
||||
.align 5
|
||||
|
||||
ll_vrc5477_irq:
|
||||
move a0, sp
|
||||
jal vrc5477_irq_dispatch
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, CPU_IRQ_BASE + 7
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
|
||||
ll_cpu_ip0:
|
||||
li a0, CPU_IRQ_BASE + 0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpu_ip1:
|
||||
li a0, CPU_IRQ_BASE + 1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
|
||||
|
||||
extern void vrc5477_irq_init(u32 base);
|
||||
extern void mips_cpu_irq_init(u32 base);
|
||||
extern asmlinkage void ddb5477_handle_int(void);
|
||||
extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
|
||||
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
||||
|
||||
@ -135,9 +134,6 @@ void __init arch_init_irq(void)
|
||||
/* setup cascade interrupts */
|
||||
setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
|
||||
setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
|
||||
|
||||
/* hook up the first-level interrupt handler */
|
||||
set_except_vector(0, ddb5477_handle_int);
|
||||
}
|
||||
|
||||
u8 i8259_interrupt_ack(void)
|
||||
@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void)
|
||||
* the first level int-handler will jump here if it is a vrc5477 irq
|
||||
*/
|
||||
#define NUM_5477_IRQS 32
|
||||
asmlinkage void
|
||||
static void
|
||||
vrc5477_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
u32 intStatus;
|
||||
@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6)
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP7)
|
||||
do_IRQ(CPU_IRQ_BASE + 7, regs);
|
||||
else if (pending & VR5477INTS)
|
||||
vrc5477_irq_dispatch(regs);
|
||||
else if (pending & STATUSF_IP0)
|
||||
do_IRQ(CPU_IRQ_BASE, regs);
|
||||
else if (pending & STATUSF_IP1)
|
||||
do_IRQ(CPU_IRQ_BASE + 1, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
.text
|
||||
.set noreorder
|
||||
/*
|
||||
* decstation_handle_int: Interrupt handler for DECstations
|
||||
* plat_irq_dispatch: Interrupt handler for DECstations
|
||||
*
|
||||
* We follow the model in the Indy interrupt code by David Miller, where he
|
||||
* says: a lot of complication here is taken away because:
|
||||
@ -125,11 +125,7 @@
|
||||
* just take another exception, big deal.
|
||||
*/
|
||||
.align 5
|
||||
NESTED(decstation_handle_int, PT_SIZE, ra)
|
||||
.set noat
|
||||
SAVE_ALL
|
||||
CLI # TEST: interrupts should be off
|
||||
.set at
|
||||
NESTED(plat_irq_dispatch, PT_SIZE, ra)
|
||||
.set noreorder
|
||||
|
||||
/*
|
||||
@ -286,7 +282,7 @@ spurious:
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
END(decstation_handle_int)
|
||||
END(plat_irq_dispatch)
|
||||
|
||||
/*
|
||||
* Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
|
||||
|
@ -48,8 +48,6 @@ extern void dec_machine_halt(void);
|
||||
extern void dec_machine_power_off(void);
|
||||
extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
|
||||
|
||||
extern asmlinkage void decstation_handle_int(void);
|
||||
|
||||
unsigned long dec_kn_slot_base, dec_kn_slot_size;
|
||||
|
||||
EXPORT_SYMBOL(dec_kn_slot_base);
|
||||
@ -744,7 +742,6 @@ void __init arch_init_irq(void)
|
||||
panic("Don't know how to set this up!");
|
||||
break;
|
||||
}
|
||||
set_except_vector(0, decstation_handle_int);
|
||||
|
||||
/* Free the FPU interrupt if the exception is present. */
|
||||
if (!cpu_has_nofpuex) {
|
||||
|
@ -6,4 +6,4 @@
|
||||
# Makefile for the Galileo EV96100 board.
|
||||
#
|
||||
|
||||
obj-y += init.o irq.o puts.o reset.o time.o int-handler.o setup.o
|
||||
obj-y += init.o irq.o puts.o reset.o time.o setup.o
|
||||
|
@ -1,34 +0,0 @@
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.set noat
|
||||
.align 5
|
||||
|
||||
NESTED(ev96100IRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI # Important: mark KERNEL mode !
|
||||
|
||||
mfc0 t0, CP0_CAUSE # get pending interrupts
|
||||
mfc0 t1, CP0_STATUS # get enabled interrupts
|
||||
and t0, t1 # isolate allowed ones
|
||||
|
||||
# FIX ME add R7000 extensions
|
||||
andi t0,0xff00 # isolate pending bits
|
||||
andi a0, t0, CAUSEF_IP7
|
||||
beq a0, zero, 1f
|
||||
move a0, sp
|
||||
jal mips_timer_interrupt
|
||||
j ret_from_irq
|
||||
|
||||
1: beqz t0, 3f # spurious interrupt
|
||||
|
||||
move a0, t0
|
||||
move a1, sp
|
||||
jal ev96100_cpu_irq
|
||||
j ret_from_irq
|
||||
|
||||
3: jal spurious_interrupt
|
||||
j ret_from_irq
|
||||
END(ev96100IRQ)
|
@ -40,8 +40,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
extern asmlinkage void ev96100IRQ(void);
|
||||
|
||||
static inline unsigned int ffz8(unsigned int word)
|
||||
{
|
||||
unsigned long k;
|
||||
@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word)
|
||||
return k;
|
||||
}
|
||||
|
||||
extern void mips_timer_interrupt(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
|
||||
{
|
||||
do_IRQ(ffz8(pending >> 8), regs);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
|
||||
if (pending & CAUSEF_IP7)
|
||||
mips_timer_interrupt(regs);
|
||||
else if (pending)
|
||||
ev96100_cpu_irq(pending, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
set_except_vector(0, ev96100IRQ);
|
||||
mips_cpu_irq_init(0);
|
||||
}
|
||||
|
@ -6,6 +6,6 @@
|
||||
# Makefile for the Galileo EV64120 board.
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o
|
||||
obj-y += irq.o promcon.o reset.o serialGT.o setup.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* int-handler.S
|
||||
*
|
||||
* Based on the cobalt handler.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* galileo_handle_int -
|
||||
* We check for the timer first, then check PCI ints A and D.
|
||||
* Then check for serial IRQ and fall through.
|
||||
*/
|
||||
.align 5
|
||||
.set reorder
|
||||
.set noat
|
||||
NESTED(galileo_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0,CP0_CAUSE
|
||||
mfc0 t2,CP0_STATUS
|
||||
|
||||
and t0,t2
|
||||
|
||||
andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
|
||||
bnez t1,ll_gt64120_irq
|
||||
andi t1,t0,STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1,ll_pci_intA
|
||||
andi t1,t0,STATUSF_IP5 /* int3 hardware line */
|
||||
bnez t1,ll_pci_intD
|
||||
andi t1,t0,STATUSF_IP6 /* int4 hardware line */
|
||||
bnez t1,ll_serial_irq
|
||||
andi t1,t0,STATUSF_IP7 /* compare int */
|
||||
bnez t1,ll_compare_irq
|
||||
nop
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
END(galileo_handle_int)
|
||||
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_gt64120_irq:
|
||||
li a0,4
|
||||
move a1,sp
|
||||
jal do_IRQ
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_compare_irq:
|
||||
li a0,7
|
||||
move a1,sp
|
||||
jal do_IRQ
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_pci_intA:
|
||||
move a0,sp
|
||||
jal pci_intA
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
#if 0
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_pci_intB:
|
||||
move a0,sp
|
||||
jal pci_intB
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_pci_intC:
|
||||
move a0,sp
|
||||
jal pci_intC
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
#endif
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_pci_intD:
|
||||
move a0,sp
|
||||
jal pci_intD
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_serial_irq:
|
||||
li a0,6
|
||||
move a1,sp
|
||||
jal do_IRQ
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
@ -46,14 +46,22 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/gt64120.h>
|
||||
|
||||
asmlinkage inline void pci_intA(struct pt_regs *regs)
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
do_IRQ(GT_INTA, regs);
|
||||
}
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
asmlinkage inline void pci_intD(struct pt_regs *regs)
|
||||
{
|
||||
do_IRQ(GT_INTD, regs);
|
||||
if (pending & STATUSF_IP4) /* int2 hardware line (timer) */
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP2) /* int0 hardware line */
|
||||
do_IRQ(GT_INTA, regs);
|
||||
else if (pending & STATUSF_IP5) /* int3 hardware line */
|
||||
do_IRQ(GT_INTD, regs);
|
||||
else if (pending & STATUSF_IP6) /* int4 hardware line */
|
||||
do_IRQ(6, regs);
|
||||
else if (pending & STATUSF_IP7) /* compare int */
|
||||
do_IRQ(7, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
static void disable_ev64120_irq(unsigned int irq_nr)
|
||||
@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = {
|
||||
|
||||
void gt64120_irq_setup(void)
|
||||
{
|
||||
extern asmlinkage void galileo_handle_int(void);
|
||||
|
||||
/*
|
||||
* Clear all of the interrupts while we change the able around a bit.
|
||||
*/
|
||||
clear_c0_status(ST0_IM);
|
||||
|
||||
/* Sets the exception_handler array. */
|
||||
set_except_vector(0, galileo_handle_int);
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
/*
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for Momentum's Ocelot board.
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o prom.o reset.o setup.o
|
||||
obj-y += irq.o prom.o reset.o setup.o
|
||||
|
||||
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for ocelot board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* first level interrupt dispatcher for ocelot board -
|
||||
* We check for the timer first, then check PCI ints A and D.
|
||||
* Then check for serial IRQ and fall through.
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ocelot_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1, ll_pri_enet_irq
|
||||
andi t1, t0, STATUSF_IP3 /* int1 hardware line */
|
||||
bnez t1, ll_sec_enet_irq
|
||||
andi t1, t0, STATUSF_IP4 /* int2 hardware line */
|
||||
bnez t1, ll_uart1_irq
|
||||
andi t1, t0, STATUSF_IP5 /* int3 hardware line */
|
||||
bnez t1, ll_cpci_irq
|
||||
andi t1, t0, STATUSF_IP6 /* int4 hardware line */
|
||||
bnez t1, ll_galileo_irq
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cputimer_irq
|
||||
|
||||
/* now look at the extended interrupts */
|
||||
mfc0 t0, CP0_CAUSE
|
||||
cfc0 t1, CP0_S1_INTCONTROL
|
||||
|
||||
/* shift the mask 8 bits left to line up the bits */
|
||||
sll t2, t1, 8
|
||||
|
||||
and t0, t2
|
||||
srl t0, t0, 16
|
||||
|
||||
andi t1, t0, STATUSF_IP8 /* int6 hardware line */
|
||||
bnez t1, ll_pmc1_irq
|
||||
andi t1, t0, STATUSF_IP9 /* int7 hardware line */
|
||||
bnez t1, ll_pmc2_irq
|
||||
andi t1, t0, STATUSF_IP10 /* int8 hardware line */
|
||||
bnez t1, ll_cpci_abcd_irq
|
||||
andi t1, t0, STATUSF_IP11 /* int9 hardware line */
|
||||
bnez t1, ll_uart2_irq
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(ocelot_handle_int)
|
||||
|
||||
.align 5
|
||||
ll_pri_enet_irq:
|
||||
li a0, 2
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_sec_enet_irq:
|
||||
li a0, 3
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart1_irq:
|
||||
li a0, 4
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpci_irq:
|
||||
li a0, 5
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_galileo_irq:
|
||||
li a0, 6
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, 7
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pmc1_irq:
|
||||
li a0, 8
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pmc2_irq:
|
||||
li a0, 9
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpci_abcd_irq:
|
||||
li a0, 10
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart2_irq:
|
||||
li a0, 11
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
@ -48,7 +48,38 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
extern asmlinkage void ocelot_handle_int(void);
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
if (pending & STATUSF_IP2) /* int0 hardware line */
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP3) /* int1 hardware line */
|
||||
do_IRQ(3, regs);
|
||||
else if (pending & STATUSF_IP4) /* int2 hardware line */
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP5) /* int3 hardware line */
|
||||
do_IRQ(5, regs);
|
||||
else if (pending & STATUSF_IP6) /* int4 hardware line */
|
||||
do_IRQ(6, regs);
|
||||
else if (pending & STATUSF_IP7) /* cpu timer */
|
||||
do_IRQ(7, regs);
|
||||
else {
|
||||
/*
|
||||
* Now look at the extended interrupts
|
||||
*/
|
||||
pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
|
||||
|
||||
if (pending & STATUSF_IP8) /* int6 hardware line */
|
||||
do_IRQ(8, regs);
|
||||
else if (pending & STATUSF_IP9) /* int7 hardware line */
|
||||
do_IRQ(9, regs);
|
||||
else if (pending & STATUSF_IP10) /* int8 hardware line */
|
||||
do_IRQ(10, regs);
|
||||
else if (pending & STATUSF_IP11) /* int9 hardware line */
|
||||
do_IRQ(11, regs);
|
||||
}
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
@ -59,9 +90,6 @@ void __init arch_init_irq(void)
|
||||
clear_c0_status(ST0_IM);
|
||||
local_irq_disable();
|
||||
|
||||
/* Sets the first-level interrupt dispatcher. */
|
||||
set_except_vector(0, ocelot_handle_int);
|
||||
|
||||
mips_cpu_irq_init(0);
|
||||
rm7k_cpu_irq_init(8);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
|
||||
#
|
||||
|
||||
obj-y += it8172_setup.o irq.o int-handler.o pmon_prom.o \
|
||||
obj-y += it8172_setup.o irq.o pmon_prom.o \
|
||||
time.o lpc.o puts.o reset.o
|
||||
|
||||
obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
|
||||
|
@ -1,63 +0,0 @@
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.set macro
|
||||
.set noat
|
||||
.align 5
|
||||
|
||||
NESTED(it8172_IRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI # Important: mark KERNEL mode !
|
||||
|
||||
/* We're working with 'reorder' set at this point. */
|
||||
/*
|
||||
* Get pending interrupts
|
||||
*/
|
||||
|
||||
mfc0 t0,CP0_CAUSE # get pending interrupts
|
||||
mfc0 t1,CP0_STATUS # get enabled interrupts
|
||||
and t0,t1 # isolate allowed ones
|
||||
|
||||
andi t0,0xff00 # isolate pending bits
|
||||
beqz t0, 3f # spurious interrupt
|
||||
|
||||
andi a0, t0, CAUSEF_IP7
|
||||
beq a0, zero, 1f
|
||||
|
||||
li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1)
|
||||
move a1, sp
|
||||
jal ll_timer_interrupt
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
1:
|
||||
andi a0, t0, CAUSEF_IP2 # the only int we expect at this time
|
||||
beq a0, zero, 3f
|
||||
move a0,sp
|
||||
jal it8172_hw0_irqdispatch
|
||||
|
||||
mfc0 t0,CP0_STATUS # disable interrupts
|
||||
ori t0,1
|
||||
xori t0,1
|
||||
mtc0 t0,CP0_STATUS
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
la a1, ret_from_irq
|
||||
jr a1
|
||||
nop
|
||||
|
||||
3:
|
||||
move a0, sp
|
||||
jal mips_spurious_interrupt
|
||||
nop
|
||||
la a1, ret_from_irq
|
||||
jr a1
|
||||
nop
|
||||
|
||||
END(it8172_IRQ)
|
||||
|
@ -64,7 +64,6 @@
|
||||
|
||||
extern void set_debug_traps(void);
|
||||
extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
|
||||
extern asmlinkage void it8172_IRQ(void);
|
||||
|
||||
struct it8172_intc_regs volatile *it8172_hw0_icregs =
|
||||
(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
|
||||
@ -178,8 +177,6 @@ void __init arch_init_irq(void)
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
set_except_vector(0, it8172_IRQ);
|
||||
|
||||
/* mask all interrupts */
|
||||
it8172_hw0_icregs->lb_mask = 0xffff;
|
||||
it8172_hw0_icregs->lpc_mask = 0xffff;
|
||||
@ -279,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs)
|
||||
do_IRQ(irq, regs);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
|
||||
if (!pending)
|
||||
mips_spurious_interrupt(regs);
|
||||
else if (pending & CAUSEF_IP7)
|
||||
ll_timer_interrupt(127, regs);
|
||||
else if (pending & CAUSEF_IP2)
|
||||
it8172_hw0_irqdispatch(regs);
|
||||
}
|
||||
|
||||
void show_pending_irqs(void)
|
||||
{
|
||||
fputs("intstatus: ");
|
||||
|
@ -2,6 +2,6 @@
|
||||
# Makefile for the Jazz family specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := int-handler.o irq.o jazzdma.o reset.o setup.o
|
||||
obj-y := irq.o jazzdma.o reset.o setup.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,283 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
|
||||
*
|
||||
* Jazz family specific interrupt stuff
|
||||
*
|
||||
* To do: On Jazz machines we remap some non-ISA interrupts to ISA
|
||||
* interrupts. These interrupts should use their own vectors.
|
||||
* Squeeze the last cycles out of the handlers. Only a dead
|
||||
* cycle is a good cycle.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/jazz.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
|
||||
*/
|
||||
.set noreorder
|
||||
|
||||
NESTED(jazz_handle_int, PT_SIZE, ra)
|
||||
.set noat
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
/*
|
||||
* Get pending interrupts
|
||||
*/
|
||||
mfc0 t0,CP0_CAUSE # get pending interrupts
|
||||
mfc0 t1,CP0_STATUS # get enabled interrupts
|
||||
and t0,t1 # isolate allowed ones
|
||||
andi t0,0xff00 # isolate pending bits
|
||||
beqz t0,3f
|
||||
sll t0,16 # delay slot
|
||||
|
||||
/*
|
||||
* Find irq with highest priority
|
||||
* FIXME: This is slow - use binary search
|
||||
*/
|
||||
la t1,ll_vectors
|
||||
1: bltz t0,2f # found pending irq
|
||||
sll t0,1
|
||||
b 1b
|
||||
subu t1,PTRSIZE # delay slot
|
||||
|
||||
/*
|
||||
* Do the low-level stuff
|
||||
*/
|
||||
2: lw t0,(t1)
|
||||
jr t0
|
||||
nop # delay slot
|
||||
END(jazz_handle_int)
|
||||
|
||||
ll_sw0: li s1,~IE_SW0
|
||||
mfc0 t0,CP0_CAUSE
|
||||
and t0,s1
|
||||
mtc0 t0,CP0_CAUSE
|
||||
PANIC("Unimplemented sw0 handler")
|
||||
|
||||
ll_sw1: li s1,~IE_SW1
|
||||
mfc0 t0,CP0_CAUSE
|
||||
and t0,s1
|
||||
mtc0 t0,CP0_CAUSE
|
||||
PANIC("Unimplemented sw1 handler")
|
||||
|
||||
ll_local_dma: li s1,~IE_IRQ0
|
||||
PANIC("Unimplemented local_dma handler")
|
||||
|
||||
ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
|
||||
#if PTRSIZE == 8 /* True 64 bit kernel */
|
||||
dsll t0,1
|
||||
#endif
|
||||
.set reorder
|
||||
LONG_L t0,local_vector(t0)
|
||||
jr t0
|
||||
.set noreorder
|
||||
|
||||
/*
|
||||
* The braindead PICA hardware gives us no way to distinguish if we really
|
||||
* received interrupt 7 from the (E)ISA bus or if we just received an
|
||||
* interrupt with no findable cause. This sometimes happens with braindead
|
||||
* cards. Oh well - for all the Jazz boxes slots are more or less just
|
||||
* whistles and bells and we're aware of the problem.
|
||||
*/
|
||||
ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK
|
||||
|
||||
jal do_IRQ
|
||||
move a1,sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/*
|
||||
* Hmm... This is not just a plain PC clone so the question is
|
||||
* which devices on Jazz machines can generate an (E)ISA NMI?
|
||||
* (Writing to nonexistent memory?)
|
||||
*/
|
||||
ll_isa_nmi: li s1,~IE_IRQ3
|
||||
PANIC("Unimplemented isa_nmi handler")
|
||||
|
||||
/*
|
||||
* Timer IRQ - remapped to be more similar to an IBM compatible.
|
||||
*
|
||||
* The timer interrupt is handled specially to ensure that the jiffies
|
||||
* variable is updated at all times. Specifically, the timer interrupt is
|
||||
* just like the complete handlers except that it is invoked with interrupts
|
||||
* disabled and should never re-enable them. If other interrupts were
|
||||
* allowed to be processed while the timer interrupt is active, then the
|
||||
* other interrupts would have to avoid using the jiffies variable for delay
|
||||
* and interval timing operations to avoid hanging the system.
|
||||
*/
|
||||
ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
|
||||
li s1,~IE_IRQ4
|
||||
|
||||
li a0, JAZZ_TIMER_IRQ
|
||||
jal do_IRQ
|
||||
move a1,sp
|
||||
|
||||
mfc0 t0,CP0_STATUS # disable interrupts again
|
||||
ori t0,1
|
||||
xori t0,1
|
||||
mtc0 t0,CP0_STATUS
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/*
|
||||
* CPU count/compare IRQ (unused)
|
||||
*/
|
||||
ll_count: j ret_from_irq
|
||||
mtc0 zero,CP0_COMPARE
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Call the handler for the interrupt
|
||||
* (Currently unused)
|
||||
*/
|
||||
call_real: /*
|
||||
* temporarily disable interrupt
|
||||
*/
|
||||
mfc0 t2,CP0_STATUS
|
||||
and t2,s1
|
||||
mtc0 t2,CP0_STATUS
|
||||
nor s1,zero,s1
|
||||
jal do_IRQ
|
||||
|
||||
/*
|
||||
* reenable interrupt
|
||||
*/
|
||||
mfc0 t2,CP0_STATUS
|
||||
or t2,s1
|
||||
mtc0 t2,CP0_STATUS
|
||||
j ret_from_irq
|
||||
#endif
|
||||
|
||||
.data
|
||||
PTR ll_sw0 # SW0
|
||||
PTR ll_sw1 # SW1
|
||||
PTR ll_local_dma # Local DMA
|
||||
PTR ll_local_dev # Local devices
|
||||
PTR ll_isa_irq # ISA IRQ
|
||||
PTR ll_isa_nmi # ISA NMI
|
||||
PTR ll_timer # Timer
|
||||
ll_vectors: PTR ll_count # Count/Compare IRQ
|
||||
|
||||
/*
|
||||
* Interrupt handlers for local devices.
|
||||
*/
|
||||
.text
|
||||
.set reorder
|
||||
loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
|
||||
/*
|
||||
* Parallel port IRQ
|
||||
*/
|
||||
loc_parallel: li s1,~JAZZ_IE_PARALLEL
|
||||
li a0,JAZZ_PARALLEL_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Floppy IRQ
|
||||
*/
|
||||
loc_floppy: li s1,~JAZZ_IE_FLOPPY
|
||||
li a0,JAZZ_FLOPPY_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Sound IRQ
|
||||
*/
|
||||
loc_sound: PANIC("Unimplemented loc_sound handler")
|
||||
loc_video: PANIC("Unimplemented loc_video handler")
|
||||
|
||||
/*
|
||||
* Ethernet interrupt handler
|
||||
*/
|
||||
loc_ethernet: li s1,~JAZZ_IE_ETHERNET
|
||||
li a0,JAZZ_ETHERNET_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* SCSI interrupt handler
|
||||
*/
|
||||
loc_scsi: li s1,~JAZZ_IE_SCSI
|
||||
li a0,JAZZ_SCSI_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Keyboard interrupt handler
|
||||
*/
|
||||
loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
|
||||
li a0,JAZZ_KEYBOARD_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Mouse interrupt handler
|
||||
*/
|
||||
loc_mouse: li s1,~JAZZ_IE_MOUSE
|
||||
li a0,JAZZ_MOUSE_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Serial port 1 IRQ
|
||||
*/
|
||||
loc_serial1: li s1,~JAZZ_IE_SERIAL1
|
||||
li a0,JAZZ_SERIAL1_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Serial port 2 IRQ
|
||||
*/
|
||||
loc_serial2: li s1,~JAZZ_IE_SERIAL2
|
||||
li a0,JAZZ_SERIAL2_IRQ
|
||||
b loc_call
|
||||
|
||||
/*
|
||||
* Call the interrupt handler for an interrupt generated by a
|
||||
* local device.
|
||||
*/
|
||||
loc_call: /*
|
||||
* Temporarily disable interrupt source
|
||||
*/
|
||||
lhu t2,JAZZ_IO_IRQ_ENABLE
|
||||
and t2,s1
|
||||
sh t2,JAZZ_IO_IRQ_ENABLE
|
||||
|
||||
nor s1,zero,s1
|
||||
jal do_IRQ
|
||||
|
||||
/*
|
||||
* Reenable interrupt
|
||||
*/
|
||||
lhu t2,JAZZ_IO_IRQ_ENABLE
|
||||
or t2,s1
|
||||
sh t2,JAZZ_IO_IRQ_ENABLE
|
||||
|
||||
j ret_from_irq
|
||||
|
||||
/*
|
||||
* "Jump extender" to reach spurious_interrupt
|
||||
*/
|
||||
3: jal spurious_interrupt
|
||||
j ret_from_irq
|
||||
|
||||
/*
|
||||
* Vectors for interrupts generated by local devices
|
||||
*/
|
||||
.data
|
||||
local_vector: PTR loc_no_irq
|
||||
PTR loc_parallel
|
||||
PTR loc_floppy
|
||||
PTR loc_sound
|
||||
PTR loc_video
|
||||
PTR loc_ethernet
|
||||
PTR loc_scsi
|
||||
PTR loc_keyboard
|
||||
PTR loc_mouse
|
||||
PTR loc_serial1
|
||||
PTR loc_serial2
|
@ -15,8 +15,6 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/jazz.h>
|
||||
|
||||
extern asmlinkage void jazz_handle_int(void);
|
||||
|
||||
static DEFINE_SPINLOCK(r4030_lock);
|
||||
|
||||
static void enable_r4030_irq(unsigned int irq)
|
||||
@ -90,10 +88,82 @@ void __init init_r4030_ints(void)
|
||||
*/
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
set_except_vector(0, jazz_handle_int);
|
||||
|
||||
init_i8259_irqs(); /* Integrated i8259 */
|
||||
init_r4030_ints();
|
||||
|
||||
change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
|
||||
}
|
||||
|
||||
static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask)
|
||||
{
|
||||
r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
|
||||
r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask);
|
||||
do_IRQ(irq, regs);
|
||||
r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
|
||||
r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask);
|
||||
}
|
||||
|
||||
static void ll_local_dev(struct pt_regs *regs)
|
||||
{
|
||||
switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) {
|
||||
case 0:
|
||||
panic("Unimplemented loc_no_irq handler");
|
||||
break;
|
||||
case 4:
|
||||
loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL);
|
||||
break;
|
||||
case 8:
|
||||
loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY);
|
||||
break;
|
||||
case 12:
|
||||
panic("Unimplemented loc_sound handler");
|
||||
break;
|
||||
case 16:
|
||||
panic("Unimplemented loc_video handler");
|
||||
break;
|
||||
case 20:
|
||||
loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET);
|
||||
break;
|
||||
case 24:
|
||||
loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI);
|
||||
break;
|
||||
case 28:
|
||||
loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD);
|
||||
break;
|
||||
case 32:
|
||||
loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE);
|
||||
break;
|
||||
case 36:
|
||||
loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1);
|
||||
break;
|
||||
case 40:
|
||||
loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
|
||||
if (pending & IE_IRQ5)
|
||||
write_c0_compare(0);
|
||||
else if (pending & IE_IRQ4) {
|
||||
r4030_read_reg32(JAZZ_TIMER_REGISTER);
|
||||
do_IRQ(JAZZ_TIMER_IRQ, regs);
|
||||
} else if (pending & IE_IRQ3)
|
||||
panic("Unimplemented ISA NMI handler");
|
||||
else if (pending & IE_IRQ2)
|
||||
do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs);
|
||||
else if (pending & IE_IRQ1) {
|
||||
ll_local_dev(regs);
|
||||
} else if (unlikely(pending & IE_IRQ0))
|
||||
panic("Unimplemented local_dma handler");
|
||||
else if (pending & IE_SW1) {
|
||||
clear_c0_cause(IE_SW1);
|
||||
panic("Unimplemented sw1 handler");
|
||||
} else if (pending & IE_SW0) {
|
||||
clear_c0_cause(IE_SW0);
|
||||
panic("Unimplemented sw0 handler");
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for TOSHIBA JMR-TX3927 board
|
||||
#
|
||||
|
||||
obj-y += init.o int-handler.o irq.o setup.o
|
||||
obj-y += init.o irq.o setup.o
|
||||
obj-$(CONFIG_RUNTIME_DEBUG) += debug.o
|
||||
obj-$(CONFIG_KGDB) += kgdb_io.o
|
||||
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ahennessy@mvista.com
|
||||
*
|
||||
* Based on arch/mips/tsdb/kernel/int-handler.S
|
||||
*
|
||||
* Copyright (C) 2000-2001 Toshiba Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/jmr3927/jmr3927.h>
|
||||
|
||||
/* A lot of complication here is taken away because:
|
||||
*
|
||||
* 1) We handle one interrupt and return, sitting in a loop
|
||||
* and moving across all the pending IRQ bits in the cause
|
||||
* register is _NOT_ the answer, the common case is one
|
||||
* pending IRQ so optimize in that direction.
|
||||
*
|
||||
* 2) We need not check against bits in the status register
|
||||
* IRQ mask, that would make this routine slow as hell.
|
||||
*
|
||||
* 3) Linux only thinks in terms of all IRQs on or all IRQs
|
||||
* off, nothing in between like BSD spl() brain-damage.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Flush write buffer (needed?)
|
||||
* NOTE: TX39xx performs "non-blocking load", so explicitly use the target
|
||||
* register of LBU to flush immediately.
|
||||
*/
|
||||
#define FLUSH_WB(tmp) \
|
||||
la tmp, JMR3927_IOC_REV_ADDR; \
|
||||
lbu tmp, (tmp); \
|
||||
move tmp, zero;
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(jmr3927_IRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
jal jmr3927_irc_irqdispatch
|
||||
move a0, sp
|
||||
FLUSH_WB(t0)
|
||||
j ret_from_irq
|
||||
nop
|
||||
END(jmr3927_IRQ)
|
@ -77,8 +77,6 @@ static int jmr3927_gen_iack(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern asmlinkage void jmr3927_IRQ(void);
|
||||
|
||||
#define irc_dlevel 0
|
||||
#define irc_elevel 1
|
||||
|
||||
@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs)
|
||||
regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
|
||||
}
|
||||
|
||||
void jmr3927_irc_irqdispatch(struct pt_regs *regs)
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
int irq;
|
||||
|
||||
@ -398,8 +396,6 @@ void __init arch_init_irq(void)
|
||||
|
||||
jmr3927_irq_init(NR_ISA_IRQS);
|
||||
|
||||
set_except_vector(0, jmr3927_IRQ);
|
||||
|
||||
/* setup irq space */
|
||||
add_tb_irq_space(&jmr3927_isac_irqspace);
|
||||
add_tb_irq_space(&jmr3927_ioc_irqspace);
|
||||
|
@ -122,6 +122,20 @@ handle_vcei:
|
||||
.set pop
|
||||
END(except_vec3_r4000)
|
||||
|
||||
__FINIT
|
||||
|
||||
.align 5
|
||||
NESTED(handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
|
||||
PTR_LA ra, ret_from_irq
|
||||
move a0, sp
|
||||
j plat_irq_dispatch
|
||||
END(handle_int)
|
||||
|
||||
__INIT
|
||||
|
||||
/*
|
||||
* Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
|
||||
* This is a dedicated interrupt exception vector which reduces the
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <asm/watch.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
extern asmlinkage void handle_int(void);
|
||||
extern asmlinkage void handle_tlbm(void);
|
||||
extern asmlinkage void handle_tlbl(void);
|
||||
extern asmlinkage void handle_tlbs(void);
|
||||
@ -1296,6 +1297,7 @@ void __init trap_init(void)
|
||||
if (board_be_init)
|
||||
board_be_init();
|
||||
|
||||
set_except_vector(0, handle_int);
|
||||
set_except_vector(1, handle_tlbm);
|
||||
set_except_vector(2, handle_tlbl);
|
||||
set_except_vector(3, handle_tlbs);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
obj-y += reset.o setup.o prom.o lasat_board.o \
|
||||
at93c.o interrupt.o lasatIRQ.o
|
||||
at93c.o interrupt.o
|
||||
|
||||
obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o
|
||||
obj-$(CONFIG_DS1603) += ds1603.o
|
||||
|
@ -27,14 +27,13 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/lasat/lasatint.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/gdb-stub.h>
|
||||
|
||||
static volatile int *lasat_int_status = NULL;
|
||||
static volatile int *lasat_int_mask = NULL;
|
||||
static volatile int lasat_int_mask_shift;
|
||||
|
||||
extern asmlinkage void lasatIRQ(void);
|
||||
|
||||
void disable_lasat_irq(unsigned int irq_nr)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void)
|
||||
return int_status;
|
||||
}
|
||||
|
||||
void lasat_hw0_irqdispatch(struct pt_regs *regs)
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long int_status;
|
||||
unsigned int cause = read_c0_cause();
|
||||
int irq;
|
||||
|
||||
if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
|
||||
ll_timer_interrupt(7, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
int_status = get_int_status();
|
||||
|
||||
/* if int_status == 0, then the interrupt has already been cleared */
|
||||
@ -147,9 +152,6 @@ void __init arch_init_irq(void)
|
||||
panic("arch_init_irq: mips_machtype incorrect");
|
||||
}
|
||||
|
||||
/* Now safe to set the exception vector. */
|
||||
set_except_vector(0, lasatIRQ);
|
||||
|
||||
for (i = 0; i <= LASATINT_END; i++) {
|
||||
irq_desc[i].status = IRQ_DISABLED;
|
||||
irq_desc[i].action = 0;
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* Interrupt exception dispatch code.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.align 5
|
||||
NESTED(lasatIRQ, PT_SIZE, sp)
|
||||
.set noat
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
.set noreorder
|
||||
|
||||
mfc0 s0, CP0_CAUSE # get irq mask
|
||||
|
||||
/* First we check for r4k counter/timer IRQ. */
|
||||
andi a0, s0, CAUSEF_IP7
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
|
||||
|
||||
/* Wheee, a timer interrupt. */
|
||||
li a0, 7
|
||||
jal ll_timer_interrupt
|
||||
move a1, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
1:
|
||||
/* Wheee, combined hardware level zero interrupt. */
|
||||
jal lasat_hw0_irqdispatch
|
||||
move a0, sp # delay slot
|
||||
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
/*
|
||||
* Here by mistake? This is possible, what can happen is that by the
|
||||
* time we take the exception the IRQ pin goes low, so just leave if
|
||||
* this is the case.
|
||||
*/
|
||||
move a1,s0
|
||||
mfc0 a1, CP0_EPC
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
END(lasatIRQ)
|
@ -16,5 +16,5 @@
|
||||
# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
obj-y := atlas_int.o atlas-irq.o atlas_setup.o
|
||||
obj-y := atlas_int.o atlas_setup.o
|
||||
obj-$(CONFIG_KGDB) += atlas_gdb.o
|
||||
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* Interrupt exception dispatch code.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/mips-boards/atlasint.h>
|
||||
|
||||
/*
|
||||
* Furthermore, the IRQs on the MIPS board look basically (barring software
|
||||
* IRQs which we don't use at all and all external interrupt sources are
|
||||
* combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Combined hardware interrupt (hw0)
|
||||
* 3 Hardware (ignored)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* Note: On the SEAD board thing are a little bit different.
|
||||
* Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
|
||||
* wired to UART1.
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(mipsIRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 s0, CP0_CAUSE # get irq bits
|
||||
mfc0 s1, CP0_STATUS # get irq mask
|
||||
andi s0, ST0_IM # CAUSE.CE may be non-zero!
|
||||
and s0, s1
|
||||
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
.set mips32
|
||||
clz a0, s0
|
||||
.set mips0
|
||||
negu a0
|
||||
addu a0, 31-CAUSEB_IP
|
||||
bltz a0, spurious
|
||||
#else
|
||||
beqz s0, spurious
|
||||
li a0, 7
|
||||
|
||||
and t0, s0, 0xf000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 2
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0xc000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 1
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0x8000
|
||||
sltiu t0, t0, 1
|
||||
# sll t0, 0
|
||||
subu a0, t0
|
||||
# sll s0, t0
|
||||
#endif
|
||||
|
||||
li a1, MIPSCPU_INT_ATLAS
|
||||
bne a0, a1, 1f
|
||||
addu a0, MIPSCPU_INT_BASE
|
||||
|
||||
jal atlas_hw0_irqdispatch
|
||||
move a0, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
1: jal do_IRQ
|
||||
move a1, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
spurious:
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(mipsIRQ)
|
@ -39,8 +39,6 @@
|
||||
|
||||
static struct atlas_ictrl_regs *atlas_hw0_icregs;
|
||||
|
||||
extern asmlinkage void mipsIRQ(void);
|
||||
|
||||
#if 0
|
||||
#define DEBUG_INT(x...) printk(x)
|
||||
#else
|
||||
@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x)
|
||||
return b;
|
||||
}
|
||||
|
||||
void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
||||
static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long int_status;
|
||||
int irq;
|
||||
@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
||||
do_IRQ(irq, regs);
|
||||
}
|
||||
|
||||
static inline int clz(unsigned long x)
|
||||
{
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips32 \n"
|
||||
" clz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (x)
|
||||
: "r" (x));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of ffs that only looks at bits 12..15.
|
||||
*/
|
||||
static inline unsigned int irq_ffs(unsigned int pending)
|
||||
{
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
return -clz(pending) + 31 - CAUSEB_IP;
|
||||
#else
|
||||
unsigned int a0 = 7;
|
||||
unsigned int t0;
|
||||
|
||||
t0 = s0 & 0xf000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0xc000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 1;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0x8000;
|
||||
t0 = t0 < 1;
|
||||
//t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
//s0 = s0 << t0;
|
||||
|
||||
return a0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQs on the Atlas board look basically (barring software IRQs which we
|
||||
* don't use at all and all external interrupt sources are combined together
|
||||
* on hardware interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Combined hardware interrupt (hw0)
|
||||
* 3 Hardware (ignored)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
int irq;
|
||||
|
||||
irq = irq_ffs(pending);
|
||||
|
||||
if (irq == MIPSCPU_INT_ATLAS)
|
||||
atlas_hw0_irqdispatch(regs);
|
||||
else if (irq > 0)
|
||||
do_IRQ(MIPSCPU_INT_BASE + irq, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
int i;
|
||||
@ -128,9 +211,6 @@ void __init arch_init_irq(void)
|
||||
*/
|
||||
atlas_hw0_icregs->intrsten = 0xffffffff;
|
||||
|
||||
/* Now safe to set the exception vector. */
|
||||
set_except_vector(0, mipsIRQ);
|
||||
|
||||
for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
|
||||
irq_desc[i].status = IRQ_DISABLED;
|
||||
irq_desc[i].action = 0;
|
||||
|
@ -19,4 +19,4 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y := malta_int.o malta-irq.o malta_setup.o
|
||||
obj-y := malta_int.o malta_setup.o
|
||||
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* Interrupt exception dispatch code.
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/mips-boards/maltaint.h>
|
||||
|
||||
/*
|
||||
* IRQs on the Malta board look basically (barring software IRQs which we
|
||||
* don't use at all and all external interrupt sources are combined together
|
||||
* on hardware interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Combined hardware interrupt (hw0)
|
||||
* 3 Hardware (ignored)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(mipsIRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 s0, CP0_CAUSE # get irq bits
|
||||
mfc0 s1, CP0_STATUS # get irq mask
|
||||
andi s0, ST0_IM # CAUSE.CE may be non-zero!
|
||||
and s0, s1
|
||||
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
.set mips32
|
||||
clz a0, s0
|
||||
.set mips0
|
||||
negu a0
|
||||
addu a0, 31-CAUSEB_IP
|
||||
bltz a0, spurious
|
||||
#else
|
||||
beqz s0, spurious
|
||||
li a0, 7
|
||||
|
||||
and t0, s0, 0xf000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 2
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0xc000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 1
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0x8000
|
||||
sltiu t0, t0, 1
|
||||
# sll t0, 0
|
||||
subu a0, t0
|
||||
# sll s0, t0
|
||||
#endif
|
||||
|
||||
li a1, MIPSCPU_INT_I8259A
|
||||
bne a0, a1, 1f
|
||||
addu a0, MIPSCPU_INT_BASE
|
||||
|
||||
jal malta_hw0_irqdispatch
|
||||
move a0, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
1:
|
||||
|
||||
jal do_IRQ
|
||||
move a1, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
spurious:
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(mipsIRQ)
|
@ -40,7 +40,6 @@
|
||||
#include <asm/mips-boards/msc01_pci.h>
|
||||
#include <asm/msc01_ic.h>
|
||||
|
||||
extern asmlinkage void mipsIRQ(void);
|
||||
extern void mips_timer_interrupt(void);
|
||||
|
||||
static DEFINE_SPINLOCK(mips_irq_lock);
|
||||
@ -114,7 +113,7 @@ static inline int get_int(void)
|
||||
return irq;
|
||||
}
|
||||
|
||||
void malta_hw0_irqdispatch(struct pt_regs *regs)
|
||||
static void malta_hw0_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
int irq;
|
||||
|
||||
@ -182,6 +181,92 @@ void corehi_irqdispatch(struct pt_regs *regs)
|
||||
die("CoreHi interrupt", regs);
|
||||
}
|
||||
|
||||
static inline int clz(unsigned long x)
|
||||
{
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips32 \n"
|
||||
" clz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (x)
|
||||
: "r" (x));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of ffs that only looks at bits 12..15.
|
||||
*/
|
||||
static inline unsigned int irq_ffs(unsigned int pending)
|
||||
{
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
return -clz(pending) + 31 - CAUSEB_IP;
|
||||
#else
|
||||
unsigned int a0 = 7;
|
||||
unsigned int t0;
|
||||
|
||||
t0 = s0 & 0xf000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0xc000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 1;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0x8000;
|
||||
t0 = t0 < 1;
|
||||
//t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
//s0 = s0 << t0;
|
||||
|
||||
return a0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQs on the Malta board look basically (barring software IRQs which we
|
||||
* don't use at all and all external interrupt sources are combined together
|
||||
* on hardware interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Combined hardware interrupt (hw0)
|
||||
* 3 Hardware (ignored)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
int irq;
|
||||
|
||||
irq = irq_ffs(pending);
|
||||
|
||||
if (irq == MIPSCPU_INT_I8259A)
|
||||
malta_hw0_irqdispatch(regs);
|
||||
else if (irq > 0)
|
||||
do_IRQ(MIPSCPU_INT_BASE + irq, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
static struct irqaction i8259irq = {
|
||||
.handler = no_action,
|
||||
.name = "XT-PIC cascade"
|
||||
@ -214,7 +299,6 @@ int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
set_except_vector(0, mipsIRQ);
|
||||
init_i8259_irqs();
|
||||
|
||||
if (!cpu_has_veic)
|
||||
@ -245,7 +329,6 @@ void __init arch_init_irq(void)
|
||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
||||
}
|
||||
else {
|
||||
set_except_vector(0, mipsIRQ);
|
||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
|
||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
||||
}
|
||||
|
@ -23,4 +23,4 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y := sead_int.o sead-irq.o sead_setup.o
|
||||
obj-y := sead_int.o sead_setup.o
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* Interrupt exception dispatch code.
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/mips-boards/seadint.h>
|
||||
|
||||
/*
|
||||
* IRQs on the SEAD board look basically are combined together on hardware
|
||||
* interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 UART0 (hw0)
|
||||
* 3 UART1 (hw1)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(mipsIRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 s0, CP0_CAUSE # get irq bits
|
||||
mfc0 s1, CP0_STATUS # get irq mask
|
||||
andi s0, ST0_IM # CAUSE.CE may be non-zero!
|
||||
and s0, s1
|
||||
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
.set mips32
|
||||
clz a0, s0
|
||||
.set mips0
|
||||
negu a0
|
||||
addu a0, 31-CAUSEB_IP
|
||||
bltz a0, spurious
|
||||
#else
|
||||
beqz s0, spurious
|
||||
li a0, 7
|
||||
|
||||
and t0, s0, 0xf000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 2
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0xc000
|
||||
sltiu t0, t0, 1
|
||||
sll t0, 1
|
||||
subu a0, t0
|
||||
sll s0, t0
|
||||
|
||||
and t0, s0, 0x8000
|
||||
sltiu t0, t0, 1
|
||||
# sll t0, 0
|
||||
subu a0, t0
|
||||
# sll s0, t0
|
||||
#endif
|
||||
|
||||
addu a0, MIPSCPU_INT_BASE
|
||||
jal do_IRQ
|
||||
move a1, sp
|
||||
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
spurious:
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(mipsIRQ)
|
@ -24,16 +24,94 @@
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include <asm/mips-boards/seadint.h>
|
||||
|
||||
extern asmlinkage void mipsIRQ(void);
|
||||
static inline int clz(unsigned long x)
|
||||
{
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips32 \n"
|
||||
" clz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (x)
|
||||
: "r" (x));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of ffs that only looks at bits 12..15.
|
||||
*/
|
||||
static inline unsigned int irq_ffs(unsigned int pending)
|
||||
{
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
return -clz(pending) + 31 - CAUSEB_IP;
|
||||
#else
|
||||
unsigned int a0 = 7;
|
||||
unsigned int t0;
|
||||
|
||||
t0 = s0 & 0xf000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0xc000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 1;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0x8000;
|
||||
t0 = t0 < 1;
|
||||
//t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
//s0 = s0 << t0;
|
||||
|
||||
return a0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQs on the SEAD board look basically are combined together on hardware
|
||||
* interrupt 0 (MIPS IRQ 2)) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 UART0 (hw0)
|
||||
* 3 UART1 (hw1)
|
||||
* 4 Hardware (ignored)
|
||||
* 5 Hardware (ignored)
|
||||
* 6 Hardware (ignored)
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Lowest ---- Combined hardware interrupt
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
int irq;
|
||||
|
||||
irq = irq_ffs(pending);
|
||||
|
||||
if (irq >= 0)
|
||||
do_IRQ(MIPSCPU_INT_BASE + irq, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
mips_cpu_irq_init(MIPSCPU_INT_BASE);
|
||||
|
||||
/* Now safe to set the exception vector. */
|
||||
set_except_vector(0, mipsIRQ);
|
||||
}
|
||||
|
@ -25,17 +25,71 @@
|
||||
|
||||
extern void mips_cpu_irq_init(int);
|
||||
|
||||
extern asmlinkage void simIRQ(void);
|
||||
static inline int clz(unsigned long x)
|
||||
{
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips32 \n"
|
||||
" clz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (x)
|
||||
: "r" (x));
|
||||
|
||||
asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of ffs that only looks at bits 12..15.
|
||||
*/
|
||||
static inline unsigned int irq_ffs(unsigned int pending)
|
||||
{
|
||||
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||
return -clz(pending) + 31 - CAUSEB_IP;
|
||||
#else
|
||||
unsigned int a0 = 7;
|
||||
unsigned int t0;
|
||||
|
||||
t0 = s0 & 0xf000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0xc000;
|
||||
t0 = t0 < 1;
|
||||
t0 = t0 << 1;
|
||||
a0 = a0 - t0;
|
||||
s0 = s0 << t0;
|
||||
|
||||
t0 = s0 & 0x8000;
|
||||
t0 = t0 < 1;
|
||||
//t0 = t0 << 2;
|
||||
a0 = a0 - t0;
|
||||
//s0 = s0 << t0;
|
||||
|
||||
return a0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void sim_hw0_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
do_IRQ(2, regs);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
int irq;
|
||||
|
||||
irq = irq_ffs(pending);
|
||||
|
||||
if (irq > 0)
|
||||
do_IRQ(MIPSCPU_INT_BASE + irq, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/* Now safe to set the exception vector. */
|
||||
set_except_vector(0, simIRQ);
|
||||
|
||||
mips_cpu_irq_init(MIPSCPU_INT_BASE);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o prom.o reset.o setup.o
|
||||
obj-y += irq.o prom.o reset.o setup.o
|
||||
|
||||
obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
|
||||
obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
|
||||
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 Momentum Computer Inc.
|
||||
* Author: Matthew Dharm <mdharm@momenco.com>
|
||||
*
|
||||
* Based on work:
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for Jaguar-ATX board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* First level interrupt dispatcher for Ocelot-CS board
|
||||
*/
|
||||
.align 5
|
||||
NESTED(jaguar_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */
|
||||
bnez t1, ll_sw0_irq
|
||||
andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */
|
||||
bnez t1, ll_sw1_irq
|
||||
andi t1, t0, STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1, ll_pcixa_irq
|
||||
andi t1, t0, STATUSF_IP3 /* int1 hardware line */
|
||||
bnez t1, ll_pcixb_irq
|
||||
andi t1, t0, STATUSF_IP4 /* int2 hardware line */
|
||||
bnez t1, ll_pcia_irq
|
||||
andi t1, t0, STATUSF_IP5 /* int3 hardware line */
|
||||
bnez t1, ll_pcib_irq
|
||||
andi t1, t0, STATUSF_IP6 /* int4 hardware line */
|
||||
bnez t1, ll_uart_irq
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cputimer_irq
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
/* now look at extended interrupts */
|
||||
mfc0 t0, CP0_CAUSE
|
||||
cfc0 t1, CP0_S1_INTCONTROL
|
||||
|
||||
/* shift the mask 8 bits left to line up the bits */
|
||||
sll t2, t1, 8
|
||||
|
||||
and t0, t2
|
||||
srl t0, t0, 16
|
||||
|
||||
andi t1, t0, STATUSF_IP8 /* int6 hardware line */
|
||||
bnez t1, ll_mv64340_decode_irq
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(jaguar_handle_int)
|
||||
|
||||
.align 5
|
||||
ll_sw0_irq:
|
||||
li a0, 0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
ll_sw1_irq:
|
||||
li a0, 1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
ll_pcixa_irq:
|
||||
li a0, 2
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pcixb_irq:
|
||||
li a0, 3
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pcia_irq:
|
||||
li a0, 4
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pcib_irq:
|
||||
li a0, 5
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart_irq:
|
||||
li a0, 6
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, 7
|
||||
move a1, sp
|
||||
jal ll_timer_interrupt
|
||||
j ret_from_irq
|
||||
|
||||
ll_mv64340_decode_irq:
|
||||
move a0, sp
|
||||
jal ll_mv64340_irq
|
||||
j ret_from_irq
|
@ -10,7 +10,7 @@
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
|
||||
* Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@ -38,8 +38,37 @@
|
||||
#include <linux/types.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
extern asmlinkage void jaguar_handle_int(void);
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP0)
|
||||
do_IRQ(0, regs);
|
||||
else if (pending & STATUSF_IP1)
|
||||
do_IRQ(1, regs);
|
||||
else if (pending & STATUSF_IP2)
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP3)
|
||||
do_IRQ(3, regs);
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(5, regs);
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(6, regs);
|
||||
else if (pending & STATUSF_IP7)
|
||||
ll_timer_interrupt(7, regs);
|
||||
else {
|
||||
/*
|
||||
* Now look at the extended interrupts
|
||||
*/
|
||||
pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
|
||||
if (pending & STATUSF_IP8)
|
||||
ll_mv64340_irq(regs);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irqaction cascade_mv64340 = {
|
||||
no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
|
||||
@ -53,8 +82,6 @@ void __init arch_init_irq(void)
|
||||
*/
|
||||
clear_c0_status(ST0_IM);
|
||||
|
||||
/* Sets the first-level interrupt dispatcher. */
|
||||
set_except_vector(0, jaguar_handle_int);
|
||||
mips_cpu_irq_init(0);
|
||||
rm7k_cpu_irq_init(8);
|
||||
|
||||
|
@ -5,4 +5,4 @@
|
||||
# removes any old dependencies. DON'T put your own dependencies here
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
obj-y += int-handler.o irq.o prom.o reset.o setup.o
|
||||
obj-y += irq.o prom.o reset.o setup.o
|
||||
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 Momentum Computer Inc.
|
||||
* Author: Matthew Dharm <mdharm@momenco.com>
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* Copyright 2004 PMC-Sierra
|
||||
* Author: Manish Lachwani (lachwani@pmc-sierra.com)
|
||||
*
|
||||
* Copyright (C) 2004 MontaVista Software Inc.
|
||||
* Author: Manish Lachwani, mlachwani@mvista.com
|
||||
*
|
||||
* First-level interrupt dispatcher for Ocelot-3 board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* First level interrupt dispatcher for Ocelot-3 board
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ocelot3_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP0 /* sw0 software interrupt (IRQ0) */
|
||||
bnez t1, ll_sw0_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP1 /* sw1 software interrupt (IRQ1) */
|
||||
bnez t1, ll_sw1_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP2 /* int0 hardware line (IRQ2) */
|
||||
bnez t1, ll_pci0slot1_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP3 /* int1 hardware line (IRQ3) */
|
||||
bnez t1, ll_pci0slot2_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP4 /* int2 hardware line (IRQ4) */
|
||||
bnez t1, ll_pci1slot1_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP5 /* int3 hardware line (IRQ5) */
|
||||
bnez t1, ll_pci1slot2_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP6 /* int4 hardware line (IRQ6) */
|
||||
bnez t1, ll_uart_irq
|
||||
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer (IRQ7) */
|
||||
bnez t1, ll_cputimer_irq
|
||||
|
||||
/* now look at extended interrupts */
|
||||
mfc0 t0, CP0_CAUSE
|
||||
cfc0 t1, CP0_S1_INTCONTROL
|
||||
|
||||
/* shift the mask 8 bits left to line up the bits */
|
||||
sll t2, t1, 8
|
||||
|
||||
and t0, t2
|
||||
srl t0, t0, 16
|
||||
|
||||
andi t1, t0, STATUSF_IP8 /* int6 hardware line (IRQ9) */
|
||||
bnez t1, ll_mv64340_decode_irq
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
END(ocelot3_handle_int)
|
||||
|
||||
.align 5
|
||||
ll_sw0_irq:
|
||||
li a0, 0 /* IRQ 1 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
ll_sw1_irq:
|
||||
li a0, 1 /* IRQ 2 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pci0slot1_irq:
|
||||
li a0, 2 /* IRQ 3 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pci0slot2_irq:
|
||||
li a0, 3 /* IRQ 4 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pci1slot1_irq:
|
||||
li a0, 4 /* IRQ 5 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pci1slot2_irq:
|
||||
li a0, 5 /* IRQ 6 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart_irq:
|
||||
li a0, 6 /* IRQ 7 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, 7 /* IRQ 8 */
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_mv64340_decode_irq:
|
||||
move a0, sp
|
||||
jal ll_mv64340_irq
|
||||
j ret_from_irq
|
||||
|
@ -53,8 +53,6 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
extern asmlinkage void ocelot3_handle_int(void);
|
||||
|
||||
static struct irqaction cascade_mv64340 = {
|
||||
no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
|
||||
};
|
||||
@ -67,9 +65,6 @@ void __init arch_init_irq(void)
|
||||
*/
|
||||
clear_c0_status(ST0_IM | ST0_BEV);
|
||||
|
||||
/* Sets the first-level interrupt dispatcher. */
|
||||
set_except_vector(0, ocelot3_handle_int);
|
||||
mips_cpu_irq_init(0);
|
||||
rm7k_cpu_irq_init(8);
|
||||
|
||||
/* set up the cascading interrupts */
|
||||
@ -79,3 +74,36 @@ void __init arch_init_irq(void)
|
||||
set_c0_status(ST0_IM); /* IE in the status register */
|
||||
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP0)
|
||||
do_IRQ(0, regs);
|
||||
else if (pending & STATUSF_IP1)
|
||||
do_IRQ(1, regs);
|
||||
else if (pending & STATUSF_IP2)
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP3)
|
||||
do_IRQ(3, regs);
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(5, regs);
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(6, regs);
|
||||
else if (pending & STATUSF_IP7)
|
||||
do_IRQ(7, regs);
|
||||
else {
|
||||
/*
|
||||
* Now look at the extended interrupts
|
||||
*/
|
||||
pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
|
||||
|
||||
if (pending & STATUSF_IP8)
|
||||
ll_mv64340_irq(regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for Momentum Computer's Ocelot-C and -CS boards.
|
||||
#
|
||||
|
||||
obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \
|
||||
obj-y += cpci-irq.o irq.o prom.o reset.o \
|
||||
setup.o uart-irq.o
|
||||
|
||||
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 Momentum Computer Inc.
|
||||
* Author: Matthew Dharm <mdharm@momenco.com>
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for Ocelot-CS board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include "ocelot_c_fpga.h"
|
||||
|
||||
/*
|
||||
* First level interrupt dispatcher for Ocelot-CS board
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ocelot_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */
|
||||
bnez t1, ll_sw0_irq
|
||||
andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */
|
||||
bnez t1, ll_sw1_irq
|
||||
andi t1, t0, STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1, ll_scsi_irq
|
||||
andi t1, t0, STATUSF_IP3 /* int1 hardware line */
|
||||
bnez t1, ll_uart_decode_irq
|
||||
andi t1, t0, STATUSF_IP4 /* int2 hardware line */
|
||||
bnez t1, ll_pmc_irq
|
||||
andi t1, t0, STATUSF_IP5 /* int3 hardware line */
|
||||
bnez t1, ll_cpci_decode_irq
|
||||
andi t1, t0, STATUSF_IP6 /* int4 hardware line */
|
||||
bnez t1, ll_mv64340_decode_irq
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cputimer_irq
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
END(ocelot_handle_int)
|
||||
|
||||
.align 5
|
||||
ll_sw0_irq:
|
||||
li a0, 0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
ll_sw1_irq:
|
||||
li a0, 1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
ll_scsi_irq:
|
||||
li a0, 2
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart_decode_irq:
|
||||
move a0, sp
|
||||
jal ll_uart_irq
|
||||
j ret_from_irq
|
||||
|
||||
ll_pmc_irq:
|
||||
li a0, 4
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpci_decode_irq:
|
||||
move a0, sp
|
||||
jal ll_cpci_irq
|
||||
j ret_from_irq
|
||||
|
||||
ll_mv64340_decode_irq:
|
||||
move a0, sp
|
||||
jal ll_mv64340_irq
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, 7
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
extern asmlinkage void ocelot_handle_int(void);
|
||||
extern void uart_irq_init(void);
|
||||
extern void cpci_irq_init(void);
|
||||
|
||||
@ -60,6 +59,33 @@ static struct irqaction cascade_mv64340 = {
|
||||
no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
|
||||
};
|
||||
|
||||
extern void ll_uart_irq(struct pt_regs *regs);
|
||||
extern void ll_cpci_irq(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP0)
|
||||
do_IRQ(0, regs);
|
||||
else if (pending & STATUSF_IP1)
|
||||
do_IRQ(1, regs);
|
||||
else if (pending & STATUSF_IP2)
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP3)
|
||||
ll_uart_irq(regs);
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP5)
|
||||
ll_cpci_irq(regs);
|
||||
else if (pending & STATUSF_IP6)
|
||||
ll_mv64340_irq(regs);
|
||||
else if (pending & STATUSF_IP7)
|
||||
do_IRQ(7, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/*
|
||||
@ -68,8 +94,6 @@ void __init arch_init_irq(void)
|
||||
*/
|
||||
clear_c0_status(ST0_IM);
|
||||
|
||||
/* Sets the first-level interrupt dispatcher. */
|
||||
set_except_vector(0, ocelot_handle_int);
|
||||
mips_cpu_irq_init(0);
|
||||
|
||||
/* set up the cascading interrupts */
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Makefile for Momentum Computer's Ocelot-G board.
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o
|
||||
obj-y += irq.o gt-irq.o prom.o reset.o setup.o
|
||||
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* First-level interrupt dispatcher for ocelot board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* first level interrupt dispatcher for ocelot board -
|
||||
* We check for the timer first, then check PCI ints A and D.
|
||||
* Then check for serial IRQ and fall through.
|
||||
*/
|
||||
.align 5
|
||||
NESTED(ocelot_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t1, t0, STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1, ll_pri_enet_irq
|
||||
andi t1, t0, STATUSF_IP3 /* int1 hardware line */
|
||||
bnez t1, ll_sec_enet_irq
|
||||
andi t1, t0, STATUSF_IP4 /* int2 hardware line */
|
||||
bnez t1, ll_uart_irq
|
||||
andi t1, t0, STATUSF_IP5 /* int3 hardware line */
|
||||
bnez t1, ll_cpci_irq
|
||||
andi t1, t0, STATUSF_IP6 /* int4 hardware line */
|
||||
bnez t1, ll_galileo_p0_irq
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_cputimer_irq
|
||||
|
||||
/* now look at the extended interrupts */
|
||||
mfc0 t0, CP0_CAUSE
|
||||
cfc0 t1, CP0_S1_INTCONTROL
|
||||
|
||||
/* shift the mask 8 bits left to line up the bits */
|
||||
sll t2, t1, 8
|
||||
|
||||
and t0, t2
|
||||
srl t0, t0, 16
|
||||
|
||||
andi t1, t0, STATUSF_IP8 /* int6 hardware line */
|
||||
bnez t1, ll_galileo_p1_irq
|
||||
andi t1, t0, STATUSF_IP9 /* int7 hardware line */
|
||||
bnez t1, ll_pmc_irq
|
||||
andi t1, t0, STATUSF_IP10 /* int8 hardware line */
|
||||
bnez t1, ll_cpci_abcd_irq
|
||||
andi t1, t0, STATUSF_IP11 /* int9 hardware line */
|
||||
bnez t1, ll_testpoint_irq
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
j spurious_interrupt
|
||||
nop
|
||||
END(ocelot_handle_int)
|
||||
|
||||
.align 5
|
||||
ll_pri_enet_irq:
|
||||
li a0, 2
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_sec_enet_irq:
|
||||
li a0, 3
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_uart_irq:
|
||||
li a0, 4
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpci_irq:
|
||||
li a0, 5
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_galileo_p0_irq:
|
||||
li a0, 6
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cputimer_irq:
|
||||
li a0, 7
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_galileo_p1_irq:
|
||||
li a0, 8
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_pmc_irq:
|
||||
li a0, 9
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_cpci_abcd_irq:
|
||||
li a0, 10
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_testpoint_irq:
|
||||
li a0, 11
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
@ -48,7 +48,41 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
extern asmlinkage void ocelot_handle_int(void);
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP2)
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP3)
|
||||
do_IRQ(3, regs);
|
||||
else if (pending & STATUSF_IP4)
|
||||
do_IRQ(4, regs);
|
||||
else if (pending & STATUSF_IP5)
|
||||
do_IRQ(5, regs);
|
||||
else if (pending & STATUSF_IP6)
|
||||
do_IRQ(6, regs);
|
||||
else if (pending & STATUSF_IP7)
|
||||
do_IRQ(7, regs);
|
||||
else {
|
||||
/*
|
||||
* Now look at the extended interrupts
|
||||
*/
|
||||
pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
|
||||
|
||||
if (pending & STATUSF_IP8)
|
||||
do_IRQ(8, regs);
|
||||
else if (pending & STATUSF_IP9)
|
||||
do_IRQ(9, regs);
|
||||
else if (pending & STATUSF_IP10)
|
||||
do_IRQ(10, regs);
|
||||
else if (pending & STATUSF_IP11)
|
||||
do_IRQ(11, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
}
|
||||
|
||||
extern void gt64240_irq_init(void);
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
@ -60,8 +94,6 @@ void __init arch_init_irq(void)
|
||||
clear_c0_status(ST0_IM);
|
||||
local_irq_disable();
|
||||
|
||||
/* Sets the first-level interrupt dispatcher. */
|
||||
set_except_vector(0, ocelot_handle_int);
|
||||
mips_cpu_irq_init(0);
|
||||
rm7k_cpu_irq_init(8);
|
||||
|
||||
|
@ -22,6 +22,6 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
|
||||
obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
obj-$(CONFIG_KGDB) += gdb_hook.o
|
||||
|
@ -38,8 +38,6 @@
|
||||
#include <int.h>
|
||||
#include <uart.h>
|
||||
|
||||
extern asmlinkage void cp0_irqdispatch(void);
|
||||
|
||||
static DEFINE_SPINLOCK(irq_lock);
|
||||
|
||||
/* default prio for interrupts */
|
||||
@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
|
||||
1 // 70
|
||||
};
|
||||
|
||||
void hw0_irqdispatch(int irq, struct pt_regs *regs)
|
||||
static void hw0_irqdispatch(int irq, struct pt_regs *regs)
|
||||
{
|
||||
/* find out which interrupt */
|
||||
irq = PNX8550_GIC_VECTOR_0 >> 3;
|
||||
@ -68,7 +66,7 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
|
||||
void timer_irqdispatch(int irq, struct pt_regs *regs)
|
||||
static void timer_irqdispatch(int irq, struct pt_regs *regs)
|
||||
{
|
||||
irq = (0x01c0 & read_c0_config7()) >> 6;
|
||||
|
||||
@ -88,6 +86,20 @@ void timer_irqdispatch(int irq, struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
if (pending & STATUSF_IP2)
|
||||
do_IRQ(2, regs);
|
||||
else if (pending & STATUSF_IP7) {
|
||||
if (read_c0_config7() & 0x01c0)
|
||||
timer_irqdispatch(7, regs);
|
||||
}
|
||||
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
|
||||
{
|
||||
unsigned long status = read_c0_status();
|
||||
@ -223,9 +235,6 @@ void __init arch_init_irq(void)
|
||||
int i;
|
||||
int configPR;
|
||||
|
||||
/* init of cp0 interrupts */
|
||||
set_except_vector(0, cp0_irqdispatch);
|
||||
|
||||
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
|
||||
irq_desc[i].handler = &level_irq_type;
|
||||
pnx8550_ack(i); /* mask the irq just in case */
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Philips, Inc. All rights.
|
||||
* Copyright (c) 2002 Red Hat, Inc. All rights.
|
||||
*
|
||||
* This software may be freely redistributed under the terms of the
|
||||
* GNU General Public License.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Based upon arch/mips/galileo-boards/ev64240/int-handler.S
|
||||
*
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* cp0_irqdispatch
|
||||
*
|
||||
* Code to handle in-core interrupt exception.
|
||||
*/
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
.set noat
|
||||
NESTED(cp0_irqdispatch, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 t0,CP0_CAUSE
|
||||
mfc0 t2,CP0_STATUS
|
||||
|
||||
and t0,t2
|
||||
|
||||
andi t1,t0,STATUSF_IP2 /* int0 hardware line */
|
||||
bnez t1,ll_hw0_irq
|
||||
nop
|
||||
|
||||
andi t1,t0,STATUSF_IP7 /* int5 hardware line */
|
||||
bnez t1,ll_timer_irq
|
||||
nop
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
END(cp0_irqdispatch)
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_hw0_irq:
|
||||
li a0,2
|
||||
move a1,sp
|
||||
jal hw0_irqdispatch
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
.align 5
|
||||
.set reorder
|
||||
ll_timer_irq:
|
||||
mfc0 t3,CP0_CONFIG,7
|
||||
andi t4,t3,0x01c0
|
||||
beqz t4,ll_timer_out
|
||||
nop
|
||||
li a0,7
|
||||
move a1,sp
|
||||
jal timer_irqdispatch
|
||||
nop
|
||||
|
||||
ll_timer_out: j ret_from_irq
|
||||
nop
|
@ -2,7 +2,7 @@
|
||||
# Makefile for the PMC-Sierra Titan
|
||||
#
|
||||
|
||||
obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o
|
||||
obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o
|
||||
|
||||
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003, 04 PMC-Sierra Inc.
|
||||
* Author: Manish Lachwani (lachwani@pmc-sierra.com
|
||||
* Copyright 2004 Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* First-level interrupt router for the PMC-Sierra Titan board
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Titan supports Hypertransport or PCI but not both. Hence, one interrupt
|
||||
* line is shared between the PCI slot A and Hypertransport. This is the
|
||||
* Processor INTB #0.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.align 5
|
||||
NESTED(titan_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
.set noreorder
|
||||
la ra, ret_from_irq
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t2, CP0_STATUS
|
||||
|
||||
and t0, t2
|
||||
|
||||
andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */
|
||||
bnez t2, ll_timer_irq /* Timer */
|
||||
andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */
|
||||
bnez t1, ll_pcia_irq /* 64-bit PCI */
|
||||
andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */
|
||||
bnez t2, ll_pcib_irq /* second 64-bit PCI slot */
|
||||
andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */
|
||||
bnez t1, ll_duart_irq /* UART */
|
||||
andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */
|
||||
bnez t2, ll_smp_irq
|
||||
andi t1, t0, STATUSF_IP6
|
||||
bnez t1, ll_ht_irq /* Hypertransport */
|
||||
|
||||
move a0, sp
|
||||
j do_extended_irq
|
||||
END(titan_handle_int)
|
||||
|
||||
.set reorder
|
||||
.align 5
|
||||
|
||||
ll_pcia_irq:
|
||||
li a0, 2
|
||||
move a1, sp
|
||||
#ifdef CONFIG_HYPERTRANSPORT
|
||||
j ll_ht_smp_irq_handler
|
||||
#else
|
||||
j do_IRQ
|
||||
#endif
|
||||
|
||||
ll_pcib_irq:
|
||||
li a0, 3
|
||||
move a1, sp
|
||||
j do_IRQ
|
||||
|
||||
ll_duart_irq:
|
||||
li a0, 4
|
||||
move a1, sp
|
||||
j do_IRQ
|
||||
|
||||
ll_smp_irq:
|
||||
li a0, 5
|
||||
move a1, sp
|
||||
#ifdef CONFIG_SMP
|
||||
j titan_mailbox_irq
|
||||
#else
|
||||
j do_IRQ
|
||||
#endif
|
||||
|
||||
ll_ht_irq:
|
||||
li a0, 6
|
||||
move a1, sp
|
||||
j ll_ht_smp_irq_handler
|
||||
|
||||
ll_timer_irq:
|
||||
li a0, 7
|
||||
move a1, sp
|
||||
j do_IRQ
|
@ -2,6 +2,8 @@
|
||||
* Copyright (C) 2003 PMC-Sierra Inc.
|
||||
* Author: Manish Lachwani (lachwani@pmc-sierra.com)
|
||||
*
|
||||
* Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
@ -55,7 +57,6 @@
|
||||
#define HYPERTRANSPORT_INTC 0x7a /* INTC# */
|
||||
#define HYPERTRANSPORT_INTD 0x7b /* INTD# */
|
||||
|
||||
extern asmlinkage void titan_handle_int(void);
|
||||
extern void jaguar_mailbox_irq(struct pt_regs *);
|
||||
|
||||
/*
|
||||
@ -125,6 +126,35 @@ asmlinkage void do_extended_irq(struct pt_regs *regs)
|
||||
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int cause = read_c0_cause();
|
||||
unsigned int status = read_c0_status();
|
||||
unsigned int pending = cause & status;
|
||||
|
||||
if (pending & STATUSF_IP7) {
|
||||
do_IRQ(7, regs);
|
||||
} else if (pending & STATUSF_IP2) {
|
||||
#ifdef CONFIG_HYPERTRANSPORT
|
||||
ll_ht_smp_irq_handler(2, regs);
|
||||
#else
|
||||
do_IRQ(2, regs);
|
||||
#endif
|
||||
} else if (pending & STATUSF_IP3) {
|
||||
do_IRQ(3, regs);
|
||||
} else if (pending & STATUSF_IP4) {
|
||||
do_IRQ(4, regs);
|
||||
} else if (pending & STATUSF_IP5) {
|
||||
#ifdef CONFIG_SMP
|
||||
titan_mailbox_irq(regs);
|
||||
#else
|
||||
do_IRQ(5, regs);
|
||||
#endif
|
||||
} else if (pending & STATUSF_IP6) {
|
||||
do_IRQ(4, regs);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
extern void init_second_port(void);
|
||||
#endif
|
||||
@ -136,7 +166,6 @@ void __init arch_init_irq(void)
|
||||
{
|
||||
clear_c0_status(ST0_IM);
|
||||
|
||||
set_except_vector(0, titan_handle_int);
|
||||
mips_cpu_irq_init(0);
|
||||
rm7k_cpu_irq_init(8);
|
||||
rm9k_cpu_irq_init(12);
|
||||
|
@ -2,6 +2,6 @@
|
||||
# Makefile for Qemu specific kernel interface routines under Linux.
|
||||
#
|
||||
|
||||
obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o
|
||||
obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o
|
||||
|
||||
obj-$(CONFIG_SMP) += q-smp.o
|
||||
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Qemu interrupt handler code.
|
||||
*
|
||||
* Copyright (C) 2005 by Ralf Baechle
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.align 5
|
||||
NESTED(qemu_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
move a0, sp
|
||||
PTR_LA ra, ret_from_irq
|
||||
j do_qemu_int
|
||||
END(qemu_handle_int)
|
@ -9,7 +9,7 @@
|
||||
|
||||
extern asmlinkage void qemu_handle_int(void);
|
||||
|
||||
asmlinkage void do_qemu_int(struct pt_regs *regs)
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
@ -29,7 +29,6 @@ asmlinkage void do_qemu_int(struct pt_regs *regs)
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
set_except_vector(0, qemu_handle_int);
|
||||
mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
|
||||
|
||||
init_i8259_irqs();
|
||||
|
@ -3,7 +3,7 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \
|
||||
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
|
||||
ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
|
||||
|
||||
obj-$(CONFIG_EISA) += ip22-eisa.o
|
||||
|
@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256];
|
||||
static char lc2msk_to_irqnr[256];
|
||||
static char lc3msk_to_irqnr[256];
|
||||
|
||||
extern asmlinkage void indyIRQ(void);
|
||||
extern int ip22_eisa_init(void);
|
||||
|
||||
static void enable_local0_irq(unsigned int irq)
|
||||
@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = {
|
||||
.end = end_local3_irq,
|
||||
};
|
||||
|
||||
void indy_local0_irqdispatch(struct pt_regs *regs)
|
||||
static void indy_local0_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
u8 mask = sgint->istat0 & sgint->imask0;
|
||||
u8 mask2;
|
||||
@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
|
||||
return;
|
||||
}
|
||||
|
||||
void indy_local1_irqdispatch(struct pt_regs *regs)
|
||||
static void indy_local1_irqdispatch(struct pt_regs *regs)
|
||||
{
|
||||
u8 mask = sgint->istat1 & sgint->imask1;
|
||||
u8 mask2;
|
||||
@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
|
||||
|
||||
extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
|
||||
|
||||
void indy_buserror_irq(struct pt_regs *regs)
|
||||
static void indy_buserror_irq(struct pt_regs *regs)
|
||||
{
|
||||
int irq = SGI_BUSERR_IRQ;
|
||||
|
||||
@ -307,6 +306,56 @@ static struct irqaction map1_cascade = {
|
||||
#define SGI_INTERRUPTS SGINT_LOCAL3
|
||||
#endif
|
||||
|
||||
extern void indy_r4k_timer_interrupt(struct pt_regs *regs);
|
||||
extern void indy_8254timer_irq(struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* IRQs on the INDY look basically (barring software IRQs which we don't use
|
||||
* at all) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Local IRQ level zero
|
||||
* 3 Local IRQ level one
|
||||
* 4 8254 Timer zero
|
||||
* 5 8254 Timer one
|
||||
* 6 Bus Error
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Local IRQ zero
|
||||
* Local IRQ one
|
||||
* Bus Error
|
||||
* 8254 Timer zero
|
||||
* Lowest ---- 8254 Timer one
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause();
|
||||
|
||||
/*
|
||||
* First we check for r4k counter/timer IRQ.
|
||||
*/
|
||||
if (pending & CAUSEF_IP7)
|
||||
indy_r4k_timer_interrupt(regs);
|
||||
else if (pending & CAUSEF_IP2)
|
||||
indy_local0_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP3)
|
||||
indy_local1_irqdispatch(regs);
|
||||
else if (pending & CAUSEF_IP6)
|
||||
indy_buserror_irq(regs);
|
||||
else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
|
||||
indy_8254timer_irq(regs);
|
||||
}
|
||||
|
||||
extern void mips_cpu_irq_init(unsigned int irq_base);
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
@ -369,8 +418,6 @@ void __init arch_init_irq(void)
|
||||
sgint->cmeimask0 = 0;
|
||||
sgint->cmeimask1 = 0;
|
||||
|
||||
set_except_vector(0, indyIRQ);
|
||||
|
||||
/* init CPU irqs */
|
||||
mips_cpu_irq_init(SGINT_CPU);
|
||||
|
||||
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* ip22-irq.S: Interrupt exception dispatch code for FullHouse and
|
||||
* Guiness.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
|
||||
*/
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/* A lot of complication here is taken away because:
|
||||
*
|
||||
* 1) We handle one interrupt and return, sitting in a loop and moving across
|
||||
* all the pending IRQ bits in the cause register is _NOT_ the answer, the
|
||||
* common case is one pending IRQ so optimize in that direction.
|
||||
*
|
||||
* 2) We need not check against bits in the status register IRQ mask, that
|
||||
* would make this routine slow as hell.
|
||||
*
|
||||
* 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
|
||||
* between like BSD spl() brain-damage.
|
||||
*
|
||||
* Furthermore, the IRQs on the INDY look basically (barring software IRQs
|
||||
* which we don't use at all) like:
|
||||
*
|
||||
* MIPS IRQ Source
|
||||
* -------- ------
|
||||
* 0 Software (ignored)
|
||||
* 1 Software (ignored)
|
||||
* 2 Local IRQ level zero
|
||||
* 3 Local IRQ level one
|
||||
* 4 8254 Timer zero
|
||||
* 5 8254 Timer one
|
||||
* 6 Bus Error
|
||||
* 7 R4k timer (what we use)
|
||||
*
|
||||
* We handle the IRQ according to _our_ priority which is:
|
||||
*
|
||||
* Highest ---- R4k Timer
|
||||
* Local IRQ zero
|
||||
* Local IRQ one
|
||||
* Bus Error
|
||||
* 8254 Timer zero
|
||||
* Lowest ---- 8254 Timer one
|
||||
*
|
||||
* then we just return, if multiple IRQs are pending then we will just take
|
||||
* another exception, big deal.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(indyIRQ, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
mfc0 s0, CP0_CAUSE # get irq mask
|
||||
|
||||
/* First we check for r4k counter/timer IRQ. */
|
||||
andi a0, s0, CAUSEF_IP7
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
|
||||
|
||||
/* Wheee, a timer interrupt. */
|
||||
jal indy_r4k_timer_interrupt
|
||||
move a0, sp # delay slot
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
|
||||
|
||||
/* Wheee, local level zero interrupt. */
|
||||
jal indy_local0_irqdispatch
|
||||
move a0, sp # delay slot
|
||||
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
|
||||
|
||||
/* Wheee, local level one interrupt. */
|
||||
jal indy_local1_irqdispatch
|
||||
move a0, sp # delay slot
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
beq a0, zero, 1f
|
||||
andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot
|
||||
|
||||
/* Wheee, an asynchronous bus error... */
|
||||
jal indy_buserror_irq
|
||||
move a0, sp # delay slot
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
|
||||
1:
|
||||
/* Here by mistake? It is possible, that by the time we take
|
||||
* the exception the IRQ pin goes low, so just leave if this
|
||||
* is the case.
|
||||
*/
|
||||
beq a0, zero, 1f
|
||||
nop # delay slot
|
||||
|
||||
/* Must be one of the 8254 timers... */
|
||||
jal indy_8254timer_irq
|
||||
move a0, sp # delay slot
|
||||
1:
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
END(indyIRQ)
|
@ -2,7 +2,7 @@
|
||||
# Makefile for the IP27 specific kernel interface routines under Linux.
|
||||
#
|
||||
|
||||
obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
|
||||
obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \
|
||||
ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
|
||||
ip27-timer.o ip27-hubio.o ip27-xtalk.o
|
||||
|
||||
|
@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE
|
||||
in irix?
|
||||
6. Investigate why things do not work without the setup_test() call
|
||||
being invoked on all nodes in ip27-memory.c.
|
||||
7. Too many CLIs in the locore handlers :
|
||||
For the low level handlers set up by set_except_vector(),
|
||||
__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
|
||||
investigate whether the code should do CLI, STI or KMODE.
|
||||
8. Too many do_page_faults invoked - investigate.
|
||||
9. start_thread must turn off UX64 ... and define tlb_refill_debug.
|
||||
10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 1999 Ralf Baechle
|
||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.align 5
|
||||
NESTED(ip27_irq, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
|
||||
mfc0 s0, CP0_CAUSE
|
||||
mfc0 t0, CP0_STATUS
|
||||
and s0, t0
|
||||
move a0, sp
|
||||
PTR_LA ra, ret_from_irq
|
||||
|
||||
/* First check for RT interrupt. */
|
||||
andi t0, s0, CAUSEF_IP4
|
||||
bnez t0, ip4
|
||||
andi t0, s0, CAUSEF_IP2
|
||||
bnez t0, ip2
|
||||
andi t0, s0, CAUSEF_IP3
|
||||
bnez t0, ip3
|
||||
andi t0, s0, CAUSEF_IP5
|
||||
bnez t0, ip5
|
||||
andi t0, s0, CAUSEF_IP6
|
||||
bnez t0, ip6
|
||||
j ra
|
||||
|
||||
ip2: j ip27_do_irq_mask0 # PI_INT_PEND_0 or CC_PEND_{A|B}
|
||||
ip3: j ip27_do_irq_mask1 # PI_INT_PEND_1
|
||||
ip4: j ip27_rt_timer_interrupt
|
||||
ip5: j ip27_prof_timer
|
||||
ip6: j ip27_hub_error
|
||||
|
||||
END(ip27_irq)
|
@ -130,7 +130,7 @@ static int ms1bit(unsigned long x)
|
||||
* Kanoj 05.13.00
|
||||
*/
|
||||
|
||||
void ip27_do_irq_mask0(struct pt_regs *regs)
|
||||
static void ip27_do_irq_mask0(struct pt_regs *regs)
|
||||
{
|
||||
int irq, swlevel;
|
||||
hubreg_t pend0, mask0;
|
||||
@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs)
|
||||
LOCAL_HUB_L(PI_INT_PEND0);
|
||||
}
|
||||
|
||||
void ip27_do_irq_mask1(struct pt_regs *regs)
|
||||
static void ip27_do_irq_mask1(struct pt_regs *regs)
|
||||
{
|
||||
int irq, swlevel;
|
||||
hubreg_t pend1, mask1;
|
||||
@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs)
|
||||
LOCAL_HUB_L(PI_INT_PEND1);
|
||||
}
|
||||
|
||||
void ip27_prof_timer(struct pt_regs *regs)
|
||||
static void ip27_prof_timer(struct pt_regs *regs)
|
||||
{
|
||||
panic("CPU %d got a profiling interrupt", smp_processor_id());
|
||||
}
|
||||
|
||||
void ip27_hub_error(struct pt_regs *regs)
|
||||
static void ip27_hub_error(struct pt_regs *regs)
|
||||
{
|
||||
panic("CPU %d got a hub error interrupt", smp_processor_id());
|
||||
}
|
||||
@ -421,9 +421,26 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
|
||||
return irq;
|
||||
}
|
||||
|
||||
extern void ip27_rt_timer_interrupt(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & CAUSEF_IP4)
|
||||
ip27_rt_timer_interrupt(regs);
|
||||
else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
|
||||
ip27_do_irq_mask0(regs);
|
||||
else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
|
||||
ip27_do_irq_mask1(regs);
|
||||
else if (pending & CAUSEF_IP5)
|
||||
ip27_prof_timer(regs);
|
||||
else if (pending & CAUSEF_IP6)
|
||||
ip27_hub_error(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
set_except_vector(0, ip27_irq);
|
||||
}
|
||||
|
||||
void install_ipi(void)
|
||||
|
@ -3,7 +3,7 @@
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
|
||||
obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \
|
||||
crime.o ip32-memory.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2000 Harald Koerfgen
|
||||
* Copyright (C) 2001 Keith M Wesolowski
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/addrspace.h>
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(ip32_handle_int, PT_SIZE, ra)
|
||||
.set noat
|
||||
SAVE_ALL
|
||||
CLI # TEST: interrupts should be off
|
||||
.set at
|
||||
.set noreorder
|
||||
|
||||
mfc0 s0,CP0_CAUSE
|
||||
|
||||
andi t1, s0, IE_IRQ0
|
||||
bnez t1, handle_irq0
|
||||
andi t1, s0, IE_IRQ1
|
||||
bnez t1, handle_irq1
|
||||
andi t1, s0, IE_IRQ2
|
||||
bnez t1, handle_irq2
|
||||
andi t1, s0, IE_IRQ3
|
||||
bnez t1, handle_irq3
|
||||
andi t1, s0, IE_IRQ4
|
||||
bnez t1, handle_irq4
|
||||
andi t1, s0, IE_IRQ5
|
||||
bnez t1, handle_irq5
|
||||
nop
|
||||
|
||||
/* Either someone has triggered the "software interrupts"
|
||||
* or we lost an interrupt somehow. Ignore it.
|
||||
*/
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq0:
|
||||
jal ip32_irq0
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq1:
|
||||
jal ip32_irq1
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq2:
|
||||
jal ip32_irq2
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq3:
|
||||
jal ip32_irq3
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq4:
|
||||
jal ip32_irq4
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq5:
|
||||
jal ip32_irq5
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
END(ip32_handle_int)
|
@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
|
||||
struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
|
||||
CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
|
||||
|
||||
extern void ip32_handle_int(void);
|
||||
|
||||
/*
|
||||
* For interrupts wired from a single device to the CPU. Only the clock
|
||||
* uses this it seems, which is IRQ 0 and IP7.
|
||||
@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs)
|
||||
|
||||
/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
|
||||
/* change this to loop over all edge-triggered irqs, exception masked out ones */
|
||||
void ip32_irq0(struct pt_regs *regs)
|
||||
static void ip32_irq0(struct pt_regs *regs)
|
||||
{
|
||||
uint64_t crime_int;
|
||||
int irq = 0;
|
||||
@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs)
|
||||
do_IRQ(irq, regs);
|
||||
}
|
||||
|
||||
void ip32_irq1(struct pt_regs *regs)
|
||||
static void ip32_irq1(struct pt_regs *regs)
|
||||
{
|
||||
ip32_unknown_interrupt(regs);
|
||||
}
|
||||
|
||||
void ip32_irq2(struct pt_regs *regs)
|
||||
static void ip32_irq2(struct pt_regs *regs)
|
||||
{
|
||||
ip32_unknown_interrupt(regs);
|
||||
}
|
||||
|
||||
void ip32_irq3(struct pt_regs *regs)
|
||||
static void ip32_irq3(struct pt_regs *regs)
|
||||
{
|
||||
ip32_unknown_interrupt(regs);
|
||||
}
|
||||
|
||||
void ip32_irq4(struct pt_regs *regs)
|
||||
static void ip32_irq4(struct pt_regs *regs)
|
||||
{
|
||||
ip32_unknown_interrupt(regs);
|
||||
}
|
||||
|
||||
void ip32_irq5(struct pt_regs *regs)
|
||||
static void ip32_irq5(struct pt_regs *regs)
|
||||
{
|
||||
ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause();
|
||||
|
||||
if (likely(pending & IE_IRQ0))
|
||||
ip32_irq0(regs);
|
||||
else if (unlikely(pending & IE_IRQ1))
|
||||
ip32_irq1(regs);
|
||||
else if (unlikely(pending & IE_IRQ2))
|
||||
ip32_irq2(regs);
|
||||
else if (unlikely(pending & IE_IRQ3))
|
||||
ip32_irq3(regs);
|
||||
else if (unlikely(pending & IE_IRQ4))
|
||||
ip32_irq4(regs);
|
||||
else if (likely(pending & IE_IRQ5))
|
||||
ip32_irq5(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
unsigned int irq;
|
||||
@ -556,7 +572,6 @@ void __init arch_init_irq(void)
|
||||
crime->soft_int = 0;
|
||||
mace->perif.ctrl.istat = 0;
|
||||
mace->perif.ctrl.imask = 0;
|
||||
set_except_vector(0, ip32_handle_int);
|
||||
|
||||
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
|
||||
hw_irq_controller *controller;
|
||||
|
@ -1,4 +1,4 @@
|
||||
obj-y := setup.o irq.o irq_handler.o time.o
|
||||
obj-y := setup.o irq.o time.o
|
||||
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
|
||||
|
@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
|
||||
#endif
|
||||
|
||||
|
||||
/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
|
||||
extern void bcm1480_irq_handler(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static unsigned int startup_bcm1480_irq(unsigned int irq)
|
||||
@ -422,7 +419,6 @@ void __init arch_init_irq(void)
|
||||
#endif
|
||||
/* Enable necessary IPs, disable the rest */
|
||||
change_c0_status(ST0_IM, imask);
|
||||
set_except_vector(0, bcm1480_irq_handler);
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
if (kgdb_flag) {
|
||||
@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_KGDB */
|
||||
|
||||
static inline int dclz(unsigned long long x)
|
||||
{
|
||||
int lz;
|
||||
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips64 \n"
|
||||
" dclz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (lz)
|
||||
: "r" (x));
|
||||
|
||||
return lz;
|
||||
}
|
||||
|
||||
extern void bcm1480_timer_interrupt(struct pt_regs *regs);
|
||||
extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
|
||||
extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending;
|
||||
|
||||
#ifdef CONFIG_SIBYTE_BCM1480_PROF
|
||||
/* Set compare to count to silence count/compare timer interrupts */
|
||||
write_c0_compare(read_c0_count());
|
||||
#endif
|
||||
|
||||
pending = read_c0_cause();
|
||||
|
||||
#ifdef CONFIG_SIBYTE_BCM1480_PROF
|
||||
if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
|
||||
sbprof_cpu_intr(exception_epc(regs));
|
||||
#endif
|
||||
|
||||
if (pending & CAUSEF_IP4)
|
||||
bcm1480_timer_interrupt(regs);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (pending & CAUSEF_IP3)
|
||||
bcm1480_mailbox_interrupt(regs);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
if (pending & CAUSEF_IP6)
|
||||
bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */
|
||||
#endif
|
||||
|
||||
if (pending & CAUSEF_IP2) {
|
||||
unsigned long long mask_h, mask_l;
|
||||
unsigned long base;
|
||||
|
||||
/*
|
||||
* Default...we've hit an IP[2] interrupt, which means we've
|
||||
* got to check the 1480 interrupt registers to figure out what
|
||||
* to do. Need to detect which CPU we're on, now that
|
||||
* smp_affinity is supported.
|
||||
*/
|
||||
base = A_BCM1480_IMR_MAPPER(smp_processor_id());
|
||||
mask_h = __raw_readq(
|
||||
IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
|
||||
mask_l = __raw_readq(
|
||||
IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
|
||||
|
||||
if (!mask_h) {
|
||||
if (mask_h ^ 1)
|
||||
do_IRQ(63 - dclz(mask_h), regs);
|
||||
else
|
||||
do_IRQ(127 - dclz(mask_l), regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bcm1480_irq_handler() is the routine that is actually called when an
|
||||
* interrupt occurs. It is installed as the exception vector handler in
|
||||
* init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
|
||||
*
|
||||
* In the handle we figure out which interrupts need handling, and use that
|
||||
* to call the dispatcher, which will take care of actually calling
|
||||
* registered handlers
|
||||
*
|
||||
* Note that we take care of all raised interrupts in one go at the handler.
|
||||
* This is more BSDish than the Indy code, and also, IMHO, more sane.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/sibyte/sb1250_defs.h>
|
||||
#include <asm/sibyte/bcm1480_regs.h>
|
||||
#include <asm/sibyte/bcm1480_int.h>
|
||||
|
||||
/*
|
||||
* What a pain. We have to be really careful saving the upper 32 bits of any
|
||||
* register across function calls if we don't want them trashed--since were
|
||||
* running in -o32, the calling routing never saves the full 64 bits of a
|
||||
* register across a function call. Being the interrupt handler, we're
|
||||
* guaranteed that interrupts are disabled during this code so we don't have
|
||||
* to worry about random interrupts blasting the high 32 bits.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set push
|
||||
.set noreorder
|
||||
.set noat
|
||||
.set mips64
|
||||
#.set mips4
|
||||
.align 5
|
||||
NESTED(bcm1480_irq_handler, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
|
||||
#ifdef CONFIG_SIBYTE_BCM1480_PROF
|
||||
/* Set compare to count to silence count/compare timer interrupts */
|
||||
mfc0 t1, CP0_COUNT
|
||||
mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
|
||||
#endif
|
||||
/* Read cause */
|
||||
mfc0 s0, CP0_CAUSE
|
||||
|
||||
#ifdef CONFIG_SIBYTE_BCM1480_PROF
|
||||
/* Cpu performance counter interrupt is routed to IP[7] */
|
||||
andi t1, s0, CAUSEF_IP7
|
||||
beqz t1, 0f
|
||||
srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
|
||||
and t1, t1, 0x4 /* mask to get just BD bit */
|
||||
#ifdef CONFIG_MIPS64
|
||||
dmfc0 a0, CP0_EPC
|
||||
daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
|
||||
#else
|
||||
mfc0 a0, CP0_EPC
|
||||
addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
|
||||
#endif
|
||||
jal sbprof_cpu_intr
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
0:
|
||||
#endif
|
||||
|
||||
/* Timer interrupt is routed to IP[4] */
|
||||
andi t1, s0, CAUSEF_IP4
|
||||
beqz t1, 1f
|
||||
nop
|
||||
jal bcm1480_timer_interrupt
|
||||
move a0, sp /* Pass the registers along */
|
||||
j ret_from_irq
|
||||
nop /* delay slot */
|
||||
1:
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Mailbox interrupt is routed to IP[3] */
|
||||
andi t1, s0, CAUSEF_IP3
|
||||
beqz t1, 2f
|
||||
nop
|
||||
jal bcm1480_mailbox_interrupt
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop /* delay slot */
|
||||
2:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
/* KGDB (uart 1) interrupt is routed to IP[6] */
|
||||
andi t1, s0, CAUSEF_IP6
|
||||
beqz t1, 3f
|
||||
nop /* delay slot */
|
||||
jal bcm1480_kgdb_interrupt
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop /* delay slot */
|
||||
3:
|
||||
#endif
|
||||
|
||||
and t1, s0, CAUSEF_IP2
|
||||
beqz t1, 9f
|
||||
nop
|
||||
|
||||
/*
|
||||
* Default...we've hit an IP[2] interrupt, which means we've got
|
||||
* to check the 1480 interrupt registers to figure out what to do
|
||||
* Need to detect which CPU we're on, now that smp_affinity is
|
||||
* supported.
|
||||
*/
|
||||
PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
|
||||
#ifdef CONFIG_SMP
|
||||
lw t1, TI_CPU($28)
|
||||
sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
|
||||
addu v0, v0, t1
|
||||
#endif
|
||||
|
||||
/* Read IP[2] status (get both high and low halves of status) */
|
||||
ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
|
||||
ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
|
||||
|
||||
move s2, zero /* intr number */
|
||||
li s3, 64
|
||||
|
||||
beqz s0, 9f /* No interrupts. Return. */
|
||||
move a1, sp
|
||||
|
||||
xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */
|
||||
movz s2, s3, s4 /* start the intr number at 64, and */
|
||||
movz s0, s1, s4 /* look at the low status value. */
|
||||
|
||||
dclz s1, s0 /* Find the next interrupt. */
|
||||
dsubu a0, zero, s1
|
||||
daddiu a0, a0, 63
|
||||
jal do_IRQ
|
||||
daddu a0, a0, s2
|
||||
|
||||
9: j ret_from_irq
|
||||
nop
|
||||
|
||||
.set pop
|
||||
END(bcm1480_irq_handler)
|
@ -1,4 +1,4 @@
|
||||
obj-y := setup.o irq.o irq_handler.o time.o
|
||||
obj-y := setup.o irq.o time.o
|
||||
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o
|
||||
|
@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
|
||||
extern void sb1250_irq_handler(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static unsigned int startup_sb1250_irq(unsigned int irq)
|
||||
@ -379,7 +375,6 @@ void __init arch_init_irq(void)
|
||||
#endif
|
||||
/* Enable necessary IPs, disable the rest */
|
||||
change_c0_status(ST0_IM, imask);
|
||||
set_except_vector(0, sb1250_irq_handler);
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
if (kgdb_flag) {
|
||||
@ -409,7 +404,7 @@ void __init arch_init_irq(void)
|
||||
#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
|
||||
#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
|
||||
|
||||
void sb1250_kgdb_interrupt(struct pt_regs *regs)
|
||||
static void sb1250_kgdb_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Clear break-change status (allow some time for the remote
|
||||
@ -424,3 +419,74 @@ void sb1250_kgdb_interrupt(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_KGDB */
|
||||
|
||||
static inline int dclz(unsigned long long x)
|
||||
{
|
||||
int lz;
|
||||
|
||||
__asm__ (
|
||||
" .set push \n"
|
||||
" .set mips64 \n"
|
||||
" dclz %0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (lz)
|
||||
: "r" (x));
|
||||
|
||||
return lz;
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending;
|
||||
|
||||
#ifdef CONFIG_SIBYTE_SB1250_PROF
|
||||
/* Set compare to count to silence count/compare timer interrupts */
|
||||
write_c0_count(read_c0_count());
|
||||
#endif
|
||||
|
||||
/*
|
||||
* What a pain. We have to be really careful saving the upper 32 bits
|
||||
* of any * register across function calls if we don't want them
|
||||
* trashed--since were running in -o32, the calling routing never saves
|
||||
* the full 64 bits of a register across a function call. Being the
|
||||
* interrupt handler, we're guaranteed that interrupts are disabled
|
||||
* during this code so we don't have to worry about random interrupts
|
||||
* blasting the high 32 bits.
|
||||
*/
|
||||
|
||||
pending = read_c0_cause();
|
||||
|
||||
#ifdef CONFIG_SIBYTE_SB1250_PROF
|
||||
if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */
|
||||
sbprof_cpu_intr(exception_epc(regs));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pending & CAUSEF_IP4)
|
||||
sb1250_timer_interrupt(regs);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (pending & CAUSEF_IP3)
|
||||
sb1250_mailbox_interrupt(regs);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
if (pending & CAUSEF_IP6) /* KGDB (uart 1) */
|
||||
sb1250_kgdb_interrupt(regs);
|
||||
#endif
|
||||
|
||||
if (pending & CAUSEF_IP2) {
|
||||
unsigned long long mask;
|
||||
|
||||
/*
|
||||
* Default...we've hit an IP[2] interrupt, which means we've
|
||||
* got to check the 1250 interrupt registers to figure out what
|
||||
* to do. Need to detect which CPU we're on, now that
|
||||
~ smp_affinity is supported.
|
||||
*/
|
||||
mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
|
||||
R_IMR_INTERRUPT_STATUS_BASE)));
|
||||
if (mask)
|
||||
do_IRQ(63 - dclz(mask), regs);
|
||||
}
|
||||
}
|
||||
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sb1250_handle_int() is the routine that is actually called when an interrupt
|
||||
* occurs. It is installed as the exception vector handler in arch_init_irq()
|
||||
* in arch/mips/sibyte/sb1250/irq.c
|
||||
*
|
||||
* In the handle we figure out which interrupts need handling, and use that to
|
||||
* call the dispatcher, which will take care of actually calling registered
|
||||
* handlers
|
||||
*
|
||||
* Note that we take care of all raised interrupts in one go at the handler.
|
||||
* This is more BSDish than the Indy code, and also, IMHO, more sane.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/sibyte/sb1250_defs.h>
|
||||
#include <asm/sibyte/sb1250_regs.h>
|
||||
#include <asm/sibyte/sb1250_int.h>
|
||||
|
||||
/*
|
||||
* What a pain. We have to be really careful saving the upper 32 bits of any
|
||||
* register across function calls if we don't want them trashed--since were
|
||||
* running in -o32, the calling routing never saves the full 64 bits of a
|
||||
* register across a function call. Being the interrupt handler, we're
|
||||
* guaranteed that interrupts are disabled during this code so we don't have
|
||||
* to worry about random interrupts blasting the high 32 bits.
|
||||
*/
|
||||
|
||||
.text
|
||||
.set push
|
||||
.set noreorder
|
||||
.set noat
|
||||
.set mips64
|
||||
.align 5
|
||||
NESTED(sb1250_irq_handler, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
|
||||
#ifdef CONFIG_SIBYTE_SB1250_PROF
|
||||
/* Set compare to count to silence count/compare timer interrupts */
|
||||
mfc0 t1, CP0_COUNT
|
||||
mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
|
||||
#endif
|
||||
/* Read cause */
|
||||
mfc0 s0, CP0_CAUSE
|
||||
|
||||
#ifdef CONFIG_SIBYTE_SB1250_PROF
|
||||
/* Cpu performance counter interrupt is routed to IP[7] */
|
||||
andi t1, s0, CAUSEF_IP7
|
||||
beqz t1, 0f
|
||||
srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
|
||||
and t1, t1, 0x4 /* mask to get just BD bit */
|
||||
mfc0 a0, CP0_EPC
|
||||
jal sbprof_cpu_intr
|
||||
addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
|
||||
j ret_from_irq
|
||||
nop
|
||||
0:
|
||||
#endif
|
||||
|
||||
/* Timer interrupt is routed to IP[4] */
|
||||
andi t1, s0, CAUSEF_IP4
|
||||
beqz t1, 1f
|
||||
nop
|
||||
jal sb1250_timer_interrupt
|
||||
move a0, sp /* Pass the registers along */
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
1:
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Mailbox interrupt is routed to IP[3] */
|
||||
andi t1, s0, CAUSEF_IP3
|
||||
beqz t1, 2f
|
||||
nop
|
||||
jal sb1250_mailbox_interrupt
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
2:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
/* KGDB (uart 1) interrupt is routed to IP[6] */
|
||||
andi t1, s0, CAUSEF_IP6
|
||||
beqz t1, 1f
|
||||
nop # delay slot
|
||||
jal sb1250_kgdb_interrupt
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop # delay slot
|
||||
1:
|
||||
#endif
|
||||
|
||||
and t1, s0, CAUSEF_IP2
|
||||
beqz t1, 4f
|
||||
nop
|
||||
|
||||
/*
|
||||
* Default...we've hit an IP[2] interrupt, which means we've got to
|
||||
* check the 1250 interrupt registers to figure out what to do
|
||||
* Need to detect which CPU we're on, now that smp_affinity is supported.
|
||||
*/
|
||||
PTR_LA v0, CKSEG1 + A_IMR_CPU0_BASE
|
||||
#ifdef CONFIG_SMP
|
||||
lw t1, TI_CPU($28)
|
||||
sll t1, IMR_REGISTER_SPACING_SHIFT
|
||||
addu v0, t1
|
||||
#endif
|
||||
ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */
|
||||
|
||||
beqz s0, 4f /* No interrupts. Return */
|
||||
move a1, sp
|
||||
|
||||
3: dclz s1, s0 /* Find the next interrupt */
|
||||
dsubu a0, zero, s1
|
||||
daddiu a0, a0, 63
|
||||
jal do_IRQ
|
||||
nop
|
||||
|
||||
4: j ret_from_irq
|
||||
nop
|
||||
|
||||
.set pop
|
||||
END(sb1250_irq_handler)
|
@ -2,6 +2,6 @@
|
||||
# Makefile for the SNI specific part of the kernel
|
||||
#
|
||||
|
||||
obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o
|
||||
obj-y += irq.o pcimt_scache.o reset.o setup.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* SNI RM200 PCI specific interrupt handler code.
|
||||
*
|
||||
* Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
/*
|
||||
* The PCI ASIC has the nasty property that it may delay writes if it is busy.
|
||||
* As a consequence from writes that have not graduated when we exit from the
|
||||
* interrupt handler we might catch a spurious interrupt. To avoid this we
|
||||
* force the PCI ASIC to graduate all writes by executing a read from the
|
||||
* PCI bus.
|
||||
*/
|
||||
.set noreorder
|
||||
.set noat
|
||||
.align 5
|
||||
NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
/* Blinken light ... */
|
||||
lb t0, led_cache
|
||||
addiu t0, 1
|
||||
sb t0, led_cache
|
||||
sb t0, PCIMT_CSLED # write only register
|
||||
.data
|
||||
led_cache: .byte 0
|
||||
.text
|
||||
|
||||
mfc0 t0, CP0_STATUS
|
||||
mfc0 t1, CP0_CAUSE
|
||||
and t0, t1
|
||||
|
||||
andi t1, t0, 0x0800 # hardware interrupt 1
|
||||
bnez t1, _hwint1
|
||||
andi t1, t0, 0x4000 # hardware interrupt 4
|
||||
bnez t1, _hwint4
|
||||
andi t1, t0, 0x2000 # hardware interrupt 3
|
||||
bnez t1, _hwint3
|
||||
andi t1, t0, 0x1000 # hardware interrupt 2
|
||||
bnez t1, _hwint2
|
||||
andi t1, t0, 0x8000 # hardware interrupt 5
|
||||
bnez t1, _hwint5
|
||||
andi t1, t0, 0x0400 # hardware interrupt 0
|
||||
bnez t1, _hwint0
|
||||
nop
|
||||
|
||||
j restore_all # spurious interrupt
|
||||
nop
|
||||
|
||||
##############################################################################
|
||||
|
||||
/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
|
||||
button interrupts. */
|
||||
_hwint0: jal pciasic_hwint0
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/*
|
||||
* hwint 1 deals with EISA and SCSI interrupts
|
||||
*/
|
||||
_hwint1: jal pciasic_hwint1
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
|
||||
/*
|
||||
* This interrupt was used for the com1 console on the first prototypes;
|
||||
* it's unsed otherwise
|
||||
*/
|
||||
_hwint2: jal pciasic_hwint2
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/*
|
||||
* hwint 3 are the PCI interrupts A - D
|
||||
*/
|
||||
_hwint3: jal pciasic_hwint3
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/*
|
||||
* hwint 4 is used for only the onboard PCnet 32.
|
||||
*/
|
||||
_hwint4: jal pciasic_hwint4
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
/* hwint5 is the r4k count / compare interrupt */
|
||||
_hwint5: jal pciasic_hwint5
|
||||
move a0, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
END(sni_rm200_pci_handle_int)
|
@ -19,8 +19,6 @@
|
||||
|
||||
DEFINE_SPINLOCK(pciasic_lock);
|
||||
|
||||
extern asmlinkage void sni_rm200_pci_handle_int(void);
|
||||
|
||||
static void enable_pciasic_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
|
||||
@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = {
|
||||
* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
|
||||
* button interrupts. Later ...
|
||||
*/
|
||||
void pciasic_hwint0(struct pt_regs *regs)
|
||||
static void pciasic_hwint0(struct pt_regs *regs)
|
||||
{
|
||||
panic("Received int0 but no handler yet ...");
|
||||
}
|
||||
|
||||
/* This interrupt was used for the com1 console on the first prototypes. */
|
||||
void pciasic_hwint2(struct pt_regs *regs)
|
||||
static void pciasic_hwint2(struct pt_regs *regs)
|
||||
{
|
||||
/* I think this shouldn't happen on production machines. */
|
||||
panic("hwint2 and no handler yet");
|
||||
}
|
||||
|
||||
/* hwint5 is the r4k count / compare interrupt */
|
||||
void pciasic_hwint5(struct pt_regs *regs)
|
||||
static void pciasic_hwint5(struct pt_regs *regs)
|
||||
{
|
||||
panic("hwint5 and no handler yet");
|
||||
}
|
||||
@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x)
|
||||
*
|
||||
* The EISA_INT bit in CSITPEND is high active, all others are low active.
|
||||
*/
|
||||
void pciasic_hwint1(struct pt_regs *regs)
|
||||
static void pciasic_hwint1(struct pt_regs *regs)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
unsigned long flags;
|
||||
@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs)
|
||||
/*
|
||||
* hwint 3 should deal with the PCI A - D interrupts,
|
||||
*/
|
||||
void pciasic_hwint3(struct pt_regs *regs)
|
||||
static void pciasic_hwint3(struct pt_regs *regs)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
int irq;
|
||||
@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs)
|
||||
/*
|
||||
* hwint 4 is used for only the onboard PCnet 32.
|
||||
*/
|
||||
void pciasic_hwint4(struct pt_regs *regs)
|
||||
static void pciasic_hwint4(struct pt_regs *regs)
|
||||
{
|
||||
clear_c0_status(IE_IRQ4);
|
||||
do_IRQ(PCIMT_IRQ_ETHERNET, regs);
|
||||
set_c0_status(IE_IRQ4);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
static unsigned char led_cache;
|
||||
|
||||
*(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
|
||||
|
||||
if (pending & 0x0800)
|
||||
pciasic_hwint1(regs);
|
||||
else if (pending & 0x4000)
|
||||
pciasic_hwint4(regs);
|
||||
else if (pending & 0x2000)
|
||||
pciasic_hwint3(regs);
|
||||
else if (pending & 0x1000)
|
||||
pciasic_hwint2(regs);
|
||||
else if (pending & 0x8000)
|
||||
pciasic_hwint5(regs);
|
||||
else if (pending & 0x0400)
|
||||
pciasic_hwint0(regs);
|
||||
}
|
||||
|
||||
void __init init_pciasic(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -176,8 +195,6 @@ void __init arch_init_irq(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
set_except_vector(0, sni_rm200_pci_handle_int);
|
||||
|
||||
init_i8259_irqs(); /* Integrated i8259 */
|
||||
init_pciasic();
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
|
||||
obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o
|
||||
obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o
|
||||
|
||||
obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
|
||||
obj-$(CONFIG_KGDB) += tx4927_dbgio.o
|
||||
|
@ -525,8 +525,6 @@ static void tx4927_irq_pic_end(unsigned int irq)
|
||||
*/
|
||||
void __init tx4927_irq_init(void)
|
||||
{
|
||||
extern asmlinkage void tx4927_irq_handler(void);
|
||||
|
||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n");
|
||||
|
||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n");
|
||||
@ -535,16 +533,12 @@ void __init tx4927_irq_init(void)
|
||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n");
|
||||
tx4927_irq_pic_init();
|
||||
|
||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT,
|
||||
"=Calling set_except_vector(tx4927_irq_handler)\n");
|
||||
set_except_vector(0, tx4927_irq_handler);
|
||||
|
||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int tx4927_irq_nested(void)
|
||||
static int tx4927_irq_nested(void)
|
||||
{
|
||||
int sw_irq = 0;
|
||||
u32 level2;
|
||||
@ -582,3 +576,25 @@ int tx4927_irq_nested(void)
|
||||
|
||||
return (sw_irq);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
|
||||
if (pending & STATUSF_IP7) /* cpu timer */
|
||||
do_IRQ(TX4927_IRQ_CPU_TIMER, regs);
|
||||
else if (pending & STATUSF_IP2) { /* tx4927 pic */
|
||||
unsigned int irq = tx4927_irq_nested();
|
||||
|
||||
if (unlikely(irq == 0)) {
|
||||
spurious_interrupt(regs);
|
||||
return;
|
||||
}
|
||||
do_IRQ(irq, regs);
|
||||
} else if (pending & STATUSF_IP0) /* user line 0 */
|
||||
do_IRQ(TX4927_IRQ_USER0, regs);
|
||||
else if (pending & STATUSF_IP1) /* user line 1 */
|
||||
do_IRQ(TX4927_IRQ_USER1, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* linux/arch/mips/tx4927/common/tx4927_irq_handler.S
|
||||
*
|
||||
* Primary interrupt handler for tx4927 based systems
|
||||
*
|
||||
* Author: MontaVista Software, Inc.
|
||||
* Author: jsun@mvista.com or jsun@junsun.net
|
||||
* source@mvista.com
|
||||
*
|
||||
* Copyright 2001-2002 MontaVista Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/tx4927/tx4927.h>
|
||||
|
||||
.align 5
|
||||
NESTED(tx4927_irq_handler, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t1, CP0_STATUS
|
||||
and t0, t1
|
||||
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_ip7
|
||||
|
||||
/* IP6..IP3 multiplexed -- do not use */
|
||||
|
||||
andi t1, t0, STATUSF_IP2 /* tx4927 pic */
|
||||
bnez t1, ll_ip2
|
||||
|
||||
andi t1, t0, STATUSF_IP0 /* user line 0 */
|
||||
bnez t1, ll_ip0
|
||||
|
||||
andi t1, t0, STATUSF_IP1 /* user line 1 */
|
||||
bnez t1, ll_ip1
|
||||
|
||||
.set reorder
|
||||
|
||||
/* wrong alarm or masked ... */
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
END(tx4927_irq_handler)
|
||||
|
||||
.align 5
|
||||
|
||||
|
||||
ll_ip7:
|
||||
li a0, TX4927_IRQ_CPU_TIMER
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_ip2:
|
||||
jal tx4927_irq_nested
|
||||
nop
|
||||
beqz v0, goto_spurious_interrupt
|
||||
nop
|
||||
move a0, v0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
goto_spurious_interrupt:
|
||||
j spurious_interrupt
|
||||
nop
|
||||
|
||||
ll_ip1:
|
||||
li a0, TX4927_IRQ_USER1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_ip0:
|
||||
li a0, TX4927_IRQ_USER0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
@ -6,6 +6,6 @@
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
|
||||
obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
|
||||
obj-y += prom.o setup.o irq.o rtc_rx5c348.o
|
||||
obj-$(CONFIG_KGDB) += dbgio.o
|
||||
|
||||
|
@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq)
|
||||
void __init
|
||||
tx4938_irq_init(void)
|
||||
{
|
||||
extern asmlinkage void tx4938_irq_handler(void);
|
||||
|
||||
tx4938_irq_cp0_init();
|
||||
tx4938_irq_pic_init();
|
||||
set_except_vector(0, tx4938_irq_handler);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -422,3 +419,21 @@ tx4938_irq_nested(void)
|
||||
wbflush();
|
||||
return (sw_irq);
|
||||
}
|
||||
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status();
|
||||
|
||||
if (pending & STATUSF_IP7)
|
||||
do_IRQ(TX4938_IRQ_CPU_TIMER, regs);
|
||||
else if (pending & STATUSF_IP2) {
|
||||
int irq = tx4938_irq_nested();
|
||||
if (irq)
|
||||
do_IRQ(irq, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
} else if (pending & STATUSF_IP1)
|
||||
do_IRQ(TX4938_IRQ_USER1, regs);
|
||||
else if (pending & STATUSF_IP0)
|
||||
do_IRQ(TX4938_IRQ_USER0, regs);
|
||||
}
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* linux/arch/mips/tx4938/common/handler.S
|
||||
*
|
||||
* Primary interrupt handler for tx4938 based systems
|
||||
* Copyright (C) 2000-2001 Toshiba Corporation
|
||||
*
|
||||
* 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
|
||||
* terms of the GNU General Public License version 2. This program is
|
||||
* licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*
|
||||
* Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/tx4938/rbtx4938.h>
|
||||
|
||||
|
||||
.align 5
|
||||
NESTED(tx4938_irq_handler, PT_SIZE, sp)
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t1, CP0_STATUS
|
||||
and t0, t1
|
||||
|
||||
andi t1, t0, STATUSF_IP7 /* cpu timer */
|
||||
bnez t1, ll_ip7
|
||||
|
||||
/* IP6..IP3 multiplexed -- do not use */
|
||||
|
||||
andi t1, t0, STATUSF_IP2 /* tx4938 pic */
|
||||
bnez t1, ll_ip2
|
||||
|
||||
andi t1, t0, STATUSF_IP1 /* user line 1 */
|
||||
bnez t1, ll_ip1
|
||||
|
||||
andi t1, t0, STATUSF_IP0 /* user line 0 */
|
||||
bnez t1, ll_ip0
|
||||
|
||||
.set reorder
|
||||
|
||||
nop
|
||||
END(tx4938_irq_handler)
|
||||
|
||||
.align 5
|
||||
|
||||
|
||||
ll_ip7:
|
||||
li a0, TX4938_IRQ_CPU_TIMER
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
|
||||
ll_ip2:
|
||||
jal tx4938_irq_nested
|
||||
nop
|
||||
beqz v0, goto_spurious_interrupt
|
||||
nop
|
||||
move a0, v0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
goto_spurious_interrupt:
|
||||
j ret_from_irq
|
||||
|
||||
ll_ip1:
|
||||
li a0, TX4938_IRQ_USER1
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
||||
|
||||
ll_ip0:
|
||||
li a0, TX4938_IRQ_USER0
|
||||
move a1, sp
|
||||
jal do_IRQ
|
||||
j ret_from_irq
|
@ -2,7 +2,7 @@
|
||||
# Makefile for common code of the NEC VR4100 series.
|
||||
#
|
||||
|
||||
obj-y += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o
|
||||
obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o
|
||||
obj-$(CONFIG_VRC4173) += vrc4173.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* FILE NAME
|
||||
* arch/mips/vr41xx/common/int-handler.S
|
||||
*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Interrupt dispatcher for the NEC VR4100 series.
|
||||
*
|
||||
* Author: Yoichi Yuasa
|
||||
* yyuasa@mvista.com or source@mvista.com
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Changes:
|
||||
* MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
|
||||
* - New creation, NEC VR4100 series are supported.
|
||||
*
|
||||
* Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
|
||||
* - Coped with INTASSIGN of NEC VR4133.
|
||||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
|
||||
.align 5
|
||||
NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
|
||||
.set noat
|
||||
SAVE_ALL
|
||||
CLI
|
||||
.set at
|
||||
.set noreorder
|
||||
|
||||
/*
|
||||
* Get the pending interrupts
|
||||
*/
|
||||
mfc0 t0, CP0_CAUSE
|
||||
mfc0 t1, CP0_STATUS
|
||||
andi t0, 0xff00
|
||||
and t0, t0, t1
|
||||
|
||||
andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt
|
||||
bnez t1, handle_irq
|
||||
li a0, 7
|
||||
|
||||
andi t1, t0, 0x7800 # check for Int1-4
|
||||
beqz t1, 1f
|
||||
|
||||
andi t1, t0, CAUSEF_IP3 # check for Int1
|
||||
bnez t1, handle_int
|
||||
li a0, 3
|
||||
|
||||
andi t1, t0, CAUSEF_IP4 # check for Int2
|
||||
bnez t1, handle_int
|
||||
li a0, 4
|
||||
|
||||
andi t1, t0, CAUSEF_IP5 # check for Int3
|
||||
bnez t1, handle_int
|
||||
li a0, 5
|
||||
|
||||
andi t1, t0, CAUSEF_IP6 # check for Int4
|
||||
bnez t1, handle_int
|
||||
li a0, 6
|
||||
|
||||
1:
|
||||
andi t1, t0, CAUSEF_IP2 # check for Int0
|
||||
bnez t1, handle_int
|
||||
li a0, 2
|
||||
|
||||
andi t1, t0, CAUSEF_IP0 # check for IP0
|
||||
bnez t1, handle_irq
|
||||
li a0, 0
|
||||
|
||||
andi t1, t0, CAUSEF_IP1 # check for IP1
|
||||
bnez t1, handle_irq
|
||||
li a0, 1
|
||||
|
||||
jal spurious_interrupt
|
||||
nop
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_int:
|
||||
jal irq_dispatch
|
||||
move a1, sp
|
||||
j ret_from_irq
|
||||
nop
|
||||
|
||||
handle_irq:
|
||||
jal do_IRQ
|
||||
move a1, sp
|
||||
j ret_from_irq
|
||||
END(vr41xx_handle_interrupt)
|
@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)
|
||||
|
||||
EXPORT_SYMBOL_GPL(cascade_irq);
|
||||
|
||||
asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
|
||||
static void irq_dispatch(unsigned int irq, struct pt_regs *regs)
|
||||
{
|
||||
irq_cascade_t *cascade;
|
||||
irq_desc_t *desc;
|
||||
@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
|
||||
do_IRQ(irq, regs);
|
||||
}
|
||||
|
||||
extern asmlinkage void vr41xx_handle_interrupt(void);
|
||||
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
|
||||
|
||||
if (pending & CAUSEF_IP7)
|
||||
do_IRQ(7, regs);
|
||||
else if (pending & 0x7800) {
|
||||
if (pending & CAUSEF_IP3)
|
||||
irq_dispatch(3, regs);
|
||||
else if (pending & CAUSEF_IP4)
|
||||
irq_dispatch(4, regs);
|
||||
else if (pending & CAUSEF_IP5)
|
||||
irq_dispatch(5, regs);
|
||||
else if (pending & CAUSEF_IP6)
|
||||
irq_dispatch(6, regs);
|
||||
} else if (pending & CAUSEF_IP2)
|
||||
irq_dispatch(2, regs);
|
||||
else if (pending & CAUSEF_IP0)
|
||||
do_IRQ(0, regs);
|
||||
else if (pending & CAUSEF_IP1)
|
||||
do_IRQ(1, regs);
|
||||
else
|
||||
spurious_interrupt(regs);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
|
||||
|
||||
set_except_vector(0, vr41xx_handle_interrupt);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user