mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
[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
100 changed files with 1113 additions and 3387 deletions
|
@ -6,7 +6,7 @@
|
||||||
# Makefile for the Alchemy Au1000 CPU, generic files.
|
# 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 \
|
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
|
||||||
sleeper.o cputable.o dma.o dbdma.o gpio.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 EXT_INTC1_REQ1 5 /* IP 5 */
|
||||||
#define MIPS_TIMER_IP 7 /* IP 7 */
|
#define MIPS_TIMER_IP 7 /* IP 7 */
|
||||||
|
|
||||||
extern asmlinkage void au1000_IRQ(void);
|
|
||||||
extern void set_debug_traps(void);
|
extern void set_debug_traps(void);
|
||||||
extern irq_cpustat_t irq_stat [NR_CPUS];
|
extern irq_cpustat_t irq_stat [NR_CPUS];
|
||||||
|
|
||||||
|
@ -446,7 +445,6 @@ void __init arch_init_irq(void)
|
||||||
extern int au1xxx_ic0_nr_irqs;
|
extern int au1xxx_ic0_nr_irqs;
|
||||||
|
|
||||||
cp0_status = read_c0_status();
|
cp0_status = read_c0_status();
|
||||||
set_except_vector(0, au1000_IRQ);
|
|
||||||
|
|
||||||
/* Initialize interrupt controllers to a safe state.
|
/* 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();
|
au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PM */
|
#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
|
# 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
|
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>
|
#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
|
* 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
|
* 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);
|
do_IRQ(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void cobalt_irq(struct pt_regs *regs)
|
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned pending;
|
unsigned pending;
|
||||||
|
|
||||||
|
@ -122,8 +120,6 @@ void __init arch_init_irq(void)
|
||||||
*/
|
*/
|
||||||
GALILEO_OUTL(0, GT_INTRMASK_OFS);
|
GALILEO_OUTL(0, GT_INTRMASK_OFS);
|
||||||
|
|
||||||
set_except_vector(0, cobalt_handle_int);
|
|
||||||
|
|
||||||
init_i8259_irqs(); /* 0 ... 15 */
|
init_i8259_irqs(); /* 0 ... 15 */
|
||||||
mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
|
mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
# under Linux.
|
# 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)
|
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>
|
#include <asm/ddb5xxx/ddb5074.h>
|
||||||
|
|
||||||
|
|
||||||
extern asmlinkage void ddbIRQ(void);
|
|
||||||
|
|
||||||
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
||||||
|
|
||||||
#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
|
#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;
|
u32 mask;
|
||||||
int nile4_irq;
|
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");
|
printk("ddb_local1_irqdispatch called\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddb_buserror_irq(void)
|
static void ddb_buserror_irq(void)
|
||||||
{
|
{
|
||||||
printk("ddb_buserror_irq called\n");
|
printk("ddb_buserror_irq called\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddb_8254timer_irq(void)
|
static void ddb_8254timer_irq(void)
|
||||||
{
|
{
|
||||||
printk("ddb_8254timer_irq called\n");
|
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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
/* setup cascade interrupts */
|
/* setup cascade interrupts */
|
||||||
setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade);
|
setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade);
|
||||||
setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
|
setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
|
||||||
|
|
||||||
set_except_vector(0, ddbIRQ);
|
|
||||||
|
|
||||||
nile4_irq_setup(NILE4_IRQ_BASE);
|
nile4_irq_setup(NILE4_IRQ_BASE);
|
||||||
m1543_irq_setup();
|
m1543_irq_setup();
|
||||||
init_i8259_irqs();
|
init_i8259_irqs();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# under Linux.
|
# 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
|
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := $(CFLAGS)
|
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_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
||||||
static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", 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 int setup_irq(unsigned int irq, struct irqaction *irqaction);
|
||||||
extern void mips_cpu_irq_init(u32 irq_base);
|
extern void mips_cpu_irq_init(u32 irq_base);
|
||||||
extern void vrc5476_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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
/* hardware initialization */
|
/* 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_LBRT, &irq_error);
|
||||||
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
|
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
|
||||||
setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &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)
|
vrc5476_irq_dispatch(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for NEC DDB-Vrc5477 board
|
# 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_RUNTIME_DEBUG) += debug.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb_io.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 vrc5477_irq_init(u32 base);
|
||||||
extern void mips_cpu_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);
|
extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
|
||||||
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
|
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 cascade interrupts */
|
||||||
setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
|
setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
|
||||||
setup_irq(CPU_IRQ_BASE + CPU_VRC5477_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)
|
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
|
* the first level int-handler will jump here if it is a vrc5477 irq
|
||||||
*/
|
*/
|
||||||
#define NUM_5477_IRQS 32
|
#define NUM_5477_IRQS 32
|
||||||
asmlinkage void
|
static void
|
||||||
vrc5477_irq_dispatch(struct pt_regs *regs)
|
vrc5477_irq_dispatch(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u32 intStatus;
|
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
|
.text
|
||||||
.set noreorder
|
.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
|
* We follow the model in the Indy interrupt code by David Miller, where he
|
||||||
* says: a lot of complication here is taken away because:
|
* says: a lot of complication here is taken away because:
|
||||||
|
@ -125,11 +125,7 @@
|
||||||
* just take another exception, big deal.
|
* just take another exception, big deal.
|
||||||
*/
|
*/
|
||||||
.align 5
|
.align 5
|
||||||
NESTED(decstation_handle_int, PT_SIZE, ra)
|
NESTED(plat_irq_dispatch, PT_SIZE, ra)
|
||||||
.set noat
|
|
||||||
SAVE_ALL
|
|
||||||
CLI # TEST: interrupts should be off
|
|
||||||
.set at
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -286,7 +282,7 @@ spurious:
|
||||||
nop
|
nop
|
||||||
j ret_from_irq
|
j ret_from_irq
|
||||||
nop
|
nop
|
||||||
END(decstation_handle_int)
|
END(plat_irq_dispatch)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
|
* 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 void dec_machine_power_off(void);
|
||||||
extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
|
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;
|
unsigned long dec_kn_slot_base, dec_kn_slot_size;
|
||||||
|
|
||||||
EXPORT_SYMBOL(dec_kn_slot_base);
|
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!");
|
panic("Don't know how to set this up!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
set_except_vector(0, decstation_handle_int);
|
|
||||||
|
|
||||||
/* Free the FPU interrupt if the exception is present. */
|
/* Free the FPU interrupt if the exception is present. */
|
||||||
if (!cpu_has_nofpuex) {
|
if (!cpu_has_nofpuex) {
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
# Makefile for the Galileo EV96100 board.
|
# 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 <linux/interrupt.h>
|
||||||
#include <asm/irq_cpu.h>
|
#include <asm/irq_cpu.h>
|
||||||
|
|
||||||
extern asmlinkage void ev96100IRQ(void);
|
|
||||||
|
|
||||||
static inline unsigned int ffz8(unsigned int word)
|
static inline unsigned int ffz8(unsigned int word)
|
||||||
{
|
{
|
||||||
unsigned long k;
|
unsigned long k;
|
||||||
|
@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word)
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void mips_timer_interrupt(struct pt_regs *regs);
|
||||||
|
|
||||||
asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
|
asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
do_IRQ(ffz8(pending >> 8), 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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
set_except_vector(0, ev96100IRQ);
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
# Makefile for the Galileo EV64120 board.
|
# 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)
|
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/system.h>
|
||||||
#include <asm/gt64120.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)
|
if (pending & STATUSF_IP4) /* int2 hardware line (timer) */
|
||||||
{
|
do_IRQ(4, regs);
|
||||||
do_IRQ(GT_INTD, 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)
|
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)
|
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 all of the interrupts while we change the able around a bit.
|
||||||
*/
|
*/
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
|
|
||||||
/* Sets the exception_handler array. */
|
|
||||||
set_except_vector(0, galileo_handle_int);
|
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for Momentum's Ocelot board.
|
# 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
|
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/mipsregs.h>
|
||||||
#include <asm/system.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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
|
@ -59,9 +90,6 @@ void __init arch_init_irq(void)
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
/* Sets the first-level interrupt dispatcher. */
|
|
||||||
set_except_vector(0, ocelot_handle_int);
|
|
||||||
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
rm7k_cpu_irq_init(8);
|
rm7k_cpu_irq_init(8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
|
# 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
|
time.o lpc.o puts.o reset.o
|
||||||
|
|
||||||
obj-$(CONFIG_IT8172_CIR)+= it8172_cir.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 set_debug_traps(void);
|
||||||
extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
|
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 *it8172_hw0_icregs =
|
||||||
(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
|
(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;
|
int i;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
set_except_vector(0, it8172_IRQ);
|
|
||||||
|
|
||||||
/* mask all interrupts */
|
/* mask all interrupts */
|
||||||
it8172_hw0_icregs->lb_mask = 0xffff;
|
it8172_hw0_icregs->lb_mask = 0xffff;
|
||||||
it8172_hw0_icregs->lpc_mask = 0xffff;
|
it8172_hw0_icregs->lpc_mask = 0xffff;
|
||||||
|
@ -279,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs)
|
||||||
do_IRQ(irq, 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)
|
void show_pending_irqs(void)
|
||||||
{
|
{
|
||||||
fputs("intstatus: ");
|
fputs("intstatus: ");
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
# Makefile for the Jazz family specific parts of the kernel
|
# 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)
|
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/io.h>
|
||||||
#include <asm/jazz.h>
|
#include <asm/jazz.h>
|
||||||
|
|
||||||
extern asmlinkage void jazz_handle_int(void);
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(r4030_lock);
|
static DEFINE_SPINLOCK(r4030_lock);
|
||||||
|
|
||||||
static void enable_r4030_irq(unsigned int irq)
|
static void enable_r4030_irq(unsigned int irq)
|
||||||
|
@ -90,10 +88,82 @@ void __init init_r4030_ints(void)
|
||||||
*/
|
*/
|
||||||
void __init arch_init_irq(void)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
set_except_vector(0, jazz_handle_int);
|
|
||||||
|
|
||||||
init_i8259_irqs(); /* Integrated i8259 */
|
init_i8259_irqs(); /* Integrated i8259 */
|
||||||
init_r4030_ints();
|
init_r4030_ints();
|
||||||
|
|
||||||
change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
|
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
|
# 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_RUNTIME_DEBUG) += debug.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb_io.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
|
#endif
|
||||||
|
|
||||||
extern asmlinkage void jmr3927_IRQ(void);
|
|
||||||
|
|
||||||
#define irc_dlevel 0
|
#define irc_dlevel 0
|
||||||
#define irc_elevel 1
|
#define irc_elevel 1
|
||||||
|
|
||||||
|
@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs)
|
||||||
regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
|
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;
|
int irq;
|
||||||
|
|
||||||
|
@ -398,8 +396,6 @@ void __init arch_init_irq(void)
|
||||||
|
|
||||||
jmr3927_irq_init(NR_ISA_IRQS);
|
jmr3927_irq_init(NR_ISA_IRQS);
|
||||||
|
|
||||||
set_except_vector(0, jmr3927_IRQ);
|
|
||||||
|
|
||||||
/* setup irq space */
|
/* setup irq space */
|
||||||
add_tb_irq_space(&jmr3927_isac_irqspace);
|
add_tb_irq_space(&jmr3927_isac_irqspace);
|
||||||
add_tb_irq_space(&jmr3927_ioc_irqspace);
|
add_tb_irq_space(&jmr3927_ioc_irqspace);
|
||||||
|
|
|
@ -122,6 +122,20 @@ handle_vcei:
|
||||||
.set pop
|
.set pop
|
||||||
END(except_vec3_r4000)
|
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.
|
* Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
|
||||||
* This is a dedicated interrupt exception vector which reduces the
|
* This is a dedicated interrupt exception vector which reduces the
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <asm/watch.h>
|
#include <asm/watch.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
|
|
||||||
|
extern asmlinkage void handle_int(void);
|
||||||
extern asmlinkage void handle_tlbm(void);
|
extern asmlinkage void handle_tlbm(void);
|
||||||
extern asmlinkage void handle_tlbl(void);
|
extern asmlinkage void handle_tlbl(void);
|
||||||
extern asmlinkage void handle_tlbs(void);
|
extern asmlinkage void handle_tlbs(void);
|
||||||
|
@ -1296,6 +1297,7 @@ void __init trap_init(void)
|
||||||
if (board_be_init)
|
if (board_be_init)
|
||||||
board_be_init();
|
board_be_init();
|
||||||
|
|
||||||
|
set_except_vector(0, handle_int);
|
||||||
set_except_vector(1, handle_tlbm);
|
set_except_vector(1, handle_tlbm);
|
||||||
set_except_vector(2, handle_tlbl);
|
set_except_vector(2, handle_tlbl);
|
||||||
set_except_vector(3, handle_tlbs);
|
set_except_vector(3, handle_tlbs);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y += reset.o setup.o prom.o lasat_board.o \
|
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_LASAT_SYSCTL) += sysctl.o
|
||||||
obj-$(CONFIG_DS1603) += ds1603.o
|
obj-$(CONFIG_DS1603) += ds1603.o
|
||||||
|
|
|
@ -27,14 +27,13 @@
|
||||||
#include <asm/bootinfo.h>
|
#include <asm/bootinfo.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/lasat/lasatint.h>
|
#include <asm/lasat/lasatint.h>
|
||||||
|
#include <asm/time.h>
|
||||||
#include <asm/gdb-stub.h>
|
#include <asm/gdb-stub.h>
|
||||||
|
|
||||||
static volatile int *lasat_int_status = NULL;
|
static volatile int *lasat_int_status = NULL;
|
||||||
static volatile int *lasat_int_mask = NULL;
|
static volatile int *lasat_int_mask = NULL;
|
||||||
static volatile int lasat_int_mask_shift;
|
static volatile int lasat_int_mask_shift;
|
||||||
|
|
||||||
extern asmlinkage void lasatIRQ(void);
|
|
||||||
|
|
||||||
void disable_lasat_irq(unsigned int irq_nr)
|
void disable_lasat_irq(unsigned int irq_nr)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void)
|
||||||
return int_status;
|
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 long int_status;
|
||||||
|
unsigned int cause = read_c0_cause();
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
|
||||||
|
ll_timer_interrupt(7, regs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int_status = get_int_status();
|
int_status = get_int_status();
|
||||||
|
|
||||||
/* if int_status == 0, then the interrupt has already been cleared */
|
/* 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");
|
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++) {
|
for (i = 0; i <= LASATINT_END; i++) {
|
||||||
irq_desc[i].status = IRQ_DISABLED;
|
irq_desc[i].status = IRQ_DISABLED;
|
||||||
irq_desc[i].action = 0;
|
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.
|
# 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
|
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;
|
static struct atlas_ictrl_regs *atlas_hw0_icregs;
|
||||||
|
|
||||||
extern asmlinkage void mipsIRQ(void);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define DEBUG_INT(x...) printk(x)
|
#define DEBUG_INT(x...) printk(x)
|
||||||
#else
|
#else
|
||||||
|
@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x)
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long int_status;
|
unsigned long int_status;
|
||||||
int irq;
|
int irq;
|
||||||
|
@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs)
|
||||||
do_IRQ(irq, 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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -128,9 +211,6 @@ void __init arch_init_irq(void)
|
||||||
*/
|
*/
|
||||||
atlas_hw0_icregs->intrsten = 0xffffffff;
|
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++) {
|
for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
|
||||||
irq_desc[i].status = IRQ_DISABLED;
|
irq_desc[i].status = IRQ_DISABLED;
|
||||||
irq_desc[i].action = 0;
|
irq_desc[i].action = 0;
|
||||||
|
|
|
@ -19,4 +19,4 @@
|
||||||
# under Linux.
|
# 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/mips-boards/msc01_pci.h>
|
||||||
#include <asm/msc01_ic.h>
|
#include <asm/msc01_ic.h>
|
||||||
|
|
||||||
extern asmlinkage void mipsIRQ(void);
|
|
||||||
extern void mips_timer_interrupt(void);
|
extern void mips_timer_interrupt(void);
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(mips_irq_lock);
|
static DEFINE_SPINLOCK(mips_irq_lock);
|
||||||
|
@ -114,7 +113,7 @@ static inline int get_int(void)
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void malta_hw0_irqdispatch(struct pt_regs *regs)
|
static void malta_hw0_irqdispatch(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
@ -182,6 +181,92 @@ void corehi_irqdispatch(struct pt_regs *regs)
|
||||||
die("CoreHi interrupt", 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 = {
|
static struct irqaction i8259irq = {
|
||||||
.handler = no_action,
|
.handler = no_action,
|
||||||
.name = "XT-PIC cascade"
|
.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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
set_except_vector(0, mipsIRQ);
|
|
||||||
init_i8259_irqs();
|
init_i8259_irqs();
|
||||||
|
|
||||||
if (!cpu_has_veic)
|
if (!cpu_has_veic)
|
||||||
|
@ -245,7 +329,6 @@ void __init arch_init_irq(void)
|
||||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_except_vector(0, mipsIRQ);
|
|
||||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
|
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
|
||||||
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,4 @@
|
||||||
# under Linux.
|
# 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 <linux/irq.h>
|
||||||
|
|
||||||
#include <asm/irq_cpu.h>
|
#include <asm/irq_cpu.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
#include <asm/mips-boards/seadint.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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
mips_cpu_irq_init(MIPSCPU_INT_BASE);
|
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 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);
|
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)
|
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);
|
mips_cpu_irq_init(MIPSCPU_INT_BASE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# unless it's something special (ie not a .c file).
|
# 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_SERIAL_8250_CONSOLE) += ja-console.o
|
||||||
obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.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.
|
* Copyright 2001 MontaVista Software Inc.
|
||||||
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
|
* 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
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
@ -38,8 +38,37 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/irq_cpu.h>
|
#include <asm/irq_cpu.h>
|
||||||
#include <asm/mipsregs.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 = {
|
static struct irqaction cascade_mv64340 = {
|
||||||
no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
|
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);
|
clear_c0_status(ST0_IM);
|
||||||
|
|
||||||
/* Sets the first-level interrupt dispatcher. */
|
|
||||||
set_except_vector(0, jaguar_handle_int);
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
rm7k_cpu_irq_init(8);
|
rm7k_cpu_irq_init(8);
|
||||||
|
|
||||||
|
|
|
@ -5,4 +5,4 @@
|
||||||
# removes any old dependencies. DON'T put your own dependencies here
|
# removes any old dependencies. DON'T put your own dependencies here
|
||||||
# unless it's something special (ie not a .c file).
|
# 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/mipsregs.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
extern asmlinkage void ocelot3_handle_int(void);
|
|
||||||
|
|
||||||
static struct irqaction cascade_mv64340 = {
|
static struct irqaction cascade_mv64340 = {
|
||||||
no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
|
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);
|
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);
|
rm7k_cpu_irq_init(8);
|
||||||
|
|
||||||
/* set up the cascading interrupts */
|
/* 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 */
|
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.
|
# 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
|
setup.o uart-irq.o
|
||||||
|
|
||||||
obj-$(CONFIG_KGDB) += dbg_io.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/mipsregs.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
extern asmlinkage void ocelot_handle_int(void);
|
|
||||||
extern void uart_irq_init(void);
|
extern void uart_irq_init(void);
|
||||||
extern void cpci_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
|
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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -68,8 +94,6 @@ void __init arch_init_irq(void)
|
||||||
*/
|
*/
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
|
|
||||||
/* Sets the first-level interrupt dispatcher. */
|
|
||||||
set_except_vector(0, ocelot_handle_int);
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
|
|
||||||
/* set up the cascading interrupts */
|
/* set up the cascading interrupts */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for Momentum Computer's Ocelot-G board.
|
# 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
|
obj-$(CONFIG_KGDB) += dbg_io.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := $(CFLAGS)
|
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/mipsregs.h>
|
||||||
#include <asm/system.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);
|
extern void gt64240_irq_init(void);
|
||||||
|
|
||||||
void __init arch_init_irq(void)
|
void __init arch_init_irq(void)
|
||||||
|
@ -60,8 +94,6 @@ void __init arch_init_irq(void)
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
/* Sets the first-level interrupt dispatcher. */
|
|
||||||
set_except_vector(0, ocelot_handle_int);
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
rm7k_cpu_irq_init(8);
|
rm7k_cpu_irq_init(8);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,6 @@
|
||||||
# under Linux.
|
# 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_PCI) += pci.o
|
||||||
obj-$(CONFIG_KGDB) += gdb_hook.o
|
obj-$(CONFIG_KGDB) += gdb_hook.o
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
#include <uart.h>
|
#include <uart.h>
|
||||||
|
|
||||||
extern asmlinkage void cp0_irqdispatch(void);
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(irq_lock);
|
static DEFINE_SPINLOCK(irq_lock);
|
||||||
|
|
||||||
/* default prio for interrupts */
|
/* default prio for interrupts */
|
||||||
|
@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
|
||||||
1 // 70
|
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 */
|
/* find out which interrupt */
|
||||||
irq = PNX8550_GIC_VECTOR_0 >> 3;
|
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;
|
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)
|
static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
|
||||||
{
|
{
|
||||||
unsigned long status = read_c0_status();
|
unsigned long status = read_c0_status();
|
||||||
|
@ -223,9 +235,6 @@ void __init arch_init_irq(void)
|
||||||
int i;
|
int i;
|
||||||
int configPR;
|
int configPR;
|
||||||
|
|
||||||
/* init of cp0 interrupts */
|
|
||||||
set_except_vector(0, cp0_irqdispatch);
|
|
||||||
|
|
||||||
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
|
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
|
||||||
irq_desc[i].handler = &level_irq_type;
|
irq_desc[i].handler = &level_irq_type;
|
||||||
pnx8550_ack(i); /* mask the irq just in case */
|
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
|
# 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_KGDB) += dbg_io.o
|
||||||
obj-$(CONFIG_SMP) += smp.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.
|
* Copyright (C) 2003 PMC-Sierra Inc.
|
||||||
* Author: Manish Lachwani (lachwani@pmc-sierra.com)
|
* 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
|
* 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
|
* 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
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
@ -55,7 +57,6 @@
|
||||||
#define HYPERTRANSPORT_INTC 0x7a /* INTC# */
|
#define HYPERTRANSPORT_INTC 0x7a /* INTC# */
|
||||||
#define HYPERTRANSPORT_INTD 0x7b /* INTD# */
|
#define HYPERTRANSPORT_INTD 0x7b /* INTD# */
|
||||||
|
|
||||||
extern asmlinkage void titan_handle_int(void);
|
|
||||||
extern void jaguar_mailbox_irq(struct pt_regs *);
|
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
|
#ifdef CONFIG_KGDB
|
||||||
extern void init_second_port(void);
|
extern void init_second_port(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -136,7 +166,6 @@ void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
|
|
||||||
set_except_vector(0, titan_handle_int);
|
|
||||||
mips_cpu_irq_init(0);
|
mips_cpu_irq_init(0);
|
||||||
rm7k_cpu_irq_init(8);
|
rm7k_cpu_irq_init(8);
|
||||||
rm9k_cpu_irq_init(12);
|
rm9k_cpu_irq_init(12);
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
# Makefile for Qemu specific kernel interface routines under Linux.
|
# 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
|
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);
|
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();
|
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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
set_except_vector(0, qemu_handle_int);
|
|
||||||
mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
|
mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
|
||||||
|
|
||||||
init_i8259_irqs();
|
init_i8259_irqs();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# under Linux.
|
# 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
|
ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
|
||||||
|
|
||||||
obj-$(CONFIG_EISA) += ip22-eisa.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 lc2msk_to_irqnr[256];
|
||||||
static char lc3msk_to_irqnr[256];
|
static char lc3msk_to_irqnr[256];
|
||||||
|
|
||||||
extern asmlinkage void indyIRQ(void);
|
|
||||||
extern int ip22_eisa_init(void);
|
extern int ip22_eisa_init(void);
|
||||||
|
|
||||||
static void enable_local0_irq(unsigned int irq)
|
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,
|
.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 mask = sgint->istat0 & sgint->imask0;
|
||||||
u8 mask2;
|
u8 mask2;
|
||||||
|
@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
|
||||||
return;
|
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 mask = sgint->istat1 & sgint->imask1;
|
||||||
u8 mask2;
|
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);
|
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;
|
int irq = SGI_BUSERR_IRQ;
|
||||||
|
|
||||||
|
@ -307,6 +306,56 @@ static struct irqaction map1_cascade = {
|
||||||
#define SGI_INTERRUPTS SGINT_LOCAL3
|
#define SGI_INTERRUPTS SGINT_LOCAL3
|
||||||
#endif
|
#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);
|
extern void mips_cpu_irq_init(unsigned int irq_base);
|
||||||
|
|
||||||
void __init arch_init_irq(void)
|
void __init arch_init_irq(void)
|
||||||
|
@ -369,8 +418,6 @@ void __init arch_init_irq(void)
|
||||||
sgint->cmeimask0 = 0;
|
sgint->cmeimask0 = 0;
|
||||||
sgint->cmeimask1 = 0;
|
sgint->cmeimask1 = 0;
|
||||||
|
|
||||||
set_except_vector(0, indyIRQ);
|
|
||||||
|
|
||||||
/* init CPU irqs */
|
/* init CPU irqs */
|
||||||
mips_cpu_irq_init(SGINT_CPU);
|
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.
|
# 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-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
|
||||||
ip27-timer.o ip27-hubio.o ip27-xtalk.o
|
ip27-timer.o ip27-hubio.o ip27-xtalk.o
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE
|
||||||
in irix?
|
in irix?
|
||||||
6. Investigate why things do not work without the setup_test() call
|
6. Investigate why things do not work without the setup_test() call
|
||||||
being invoked on all nodes in ip27-memory.c.
|
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.
|
8. Too many do_page_faults invoked - investigate.
|
||||||
9. start_thread must turn off UX64 ... and define tlb_refill_debug.
|
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
|
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
|
* 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;
|
int irq, swlevel;
|
||||||
hubreg_t pend0, mask0;
|
hubreg_t pend0, mask0;
|
||||||
|
@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs)
|
||||||
LOCAL_HUB_L(PI_INT_PEND0);
|
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;
|
int irq, swlevel;
|
||||||
hubreg_t pend1, mask1;
|
hubreg_t pend1, mask1;
|
||||||
|
@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs)
|
||||||
LOCAL_HUB_L(PI_INT_PEND1);
|
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());
|
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());
|
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;
|
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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
set_except_vector(0, ip27_irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void install_ipi(void)
|
void install_ipi(void)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# under Linux.
|
# 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
|
crime.o ip32-memory.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := $(CFLAGS)
|
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,
|
struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
|
||||||
CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
|
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
|
* For interrupts wired from a single device to the CPU. Only the clock
|
||||||
* uses this it seems, which is IRQ 0 and IP7.
|
* 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. */
|
/* 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 */
|
/* 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;
|
uint64_t crime_int;
|
||||||
int irq = 0;
|
int irq = 0;
|
||||||
|
@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs)
|
||||||
do_IRQ(irq, regs);
|
do_IRQ(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip32_irq1(struct pt_regs *regs)
|
static void ip32_irq1(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ip32_unknown_interrupt(regs);
|
ip32_unknown_interrupt(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip32_irq2(struct pt_regs *regs)
|
static void ip32_irq2(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ip32_unknown_interrupt(regs);
|
ip32_unknown_interrupt(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip32_irq3(struct pt_regs *regs)
|
static void ip32_irq3(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ip32_unknown_interrupt(regs);
|
ip32_unknown_interrupt(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip32_irq4(struct pt_regs *regs)
|
static void ip32_irq4(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ip32_unknown_interrupt(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);
|
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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
|
@ -556,7 +572,6 @@ void __init arch_init_irq(void)
|
||||||
crime->soft_int = 0;
|
crime->soft_int = 0;
|
||||||
mace->perif.ctrl.istat = 0;
|
mace->perif.ctrl.istat = 0;
|
||||||
mace->perif.ctrl.imask = 0;
|
mace->perif.ctrl.imask = 0;
|
||||||
set_except_vector(0, ip32_handle_int);
|
|
||||||
|
|
||||||
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
|
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
|
||||||
hw_irq_controller *controller;
|
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
|
obj-$(CONFIG_SMP) += smp.o
|
||||||
|
|
||||||
|
|
|
@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
|
||||||
#endif
|
#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)
|
static unsigned int startup_bcm1480_irq(unsigned int irq)
|
||||||
|
@ -422,7 +419,6 @@ void __init arch_init_irq(void)
|
||||||
#endif
|
#endif
|
||||||
/* Enable necessary IPs, disable the rest */
|
/* Enable necessary IPs, disable the rest */
|
||||||
change_c0_status(ST0_IM, imask);
|
change_c0_status(ST0_IM, imask);
|
||||||
set_except_vector(0, bcm1480_irq_handler);
|
|
||||||
|
|
||||||
#ifdef CONFIG_KGDB
|
#ifdef CONFIG_KGDB
|
||||||
if (kgdb_flag) {
|
if (kgdb_flag) {
|
||||||
|
@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_KGDB */
|
#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_SMP) += smp.o
|
||||||
obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o
|
obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o
|
||||||
|
|
|
@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static unsigned int startup_sb1250_irq(unsigned int irq)
|
||||||
|
@ -379,7 +375,6 @@ void __init arch_init_irq(void)
|
||||||
#endif
|
#endif
|
||||||
/* Enable necessary IPs, disable the rest */
|
/* Enable necessary IPs, disable the rest */
|
||||||
change_c0_status(ST0_IM, imask);
|
change_c0_status(ST0_IM, imask);
|
||||||
set_except_vector(0, sb1250_irq_handler);
|
|
||||||
|
|
||||||
#ifdef CONFIG_KGDB
|
#ifdef CONFIG_KGDB
|
||||||
if (kgdb_flag) {
|
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_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)))
|
#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
|
* 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 */
|
#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
|
# 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)
|
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);
|
DEFINE_SPINLOCK(pciasic_lock);
|
||||||
|
|
||||||
extern asmlinkage void sni_rm200_pci_handle_int(void);
|
|
||||||
|
|
||||||
static void enable_pciasic_irq(unsigned int irq)
|
static void enable_pciasic_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
|
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
|
* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
|
||||||
* button interrupts. Later ...
|
* 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 ...");
|
panic("Received int0 but no handler yet ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This interrupt was used for the com1 console on the first prototypes. */
|
/* 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. */
|
/* I think this shouldn't happen on production machines. */
|
||||||
panic("hwint2 and no handler yet");
|
panic("hwint2 and no handler yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hwint5 is the r4k count / compare interrupt */
|
/* 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");
|
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.
|
* 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;
|
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs)
|
||||||
/*
|
/*
|
||||||
* hwint 3 should deal with the PCI A - D interrupts,
|
* 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;
|
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||||
int irq;
|
int irq;
|
||||||
|
@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs)
|
||||||
/*
|
/*
|
||||||
* hwint 4 is used for only the onboard PCnet 32.
|
* 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);
|
clear_c0_status(IE_IRQ4);
|
||||||
do_IRQ(PCIMT_IRQ_ETHERNET, regs);
|
do_IRQ(PCIMT_IRQ_ETHERNET, regs);
|
||||||
set_c0_status(IE_IRQ4);
|
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)
|
void __init init_pciasic(void)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -176,8 +195,6 @@ void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
set_except_vector(0, sni_rm200_pci_handle_int);
|
|
||||||
|
|
||||||
init_i8259_irqs(); /* Integrated i8259 */
|
init_i8259_irqs(); /* Integrated i8259 */
|
||||||
init_pciasic();
|
init_pciasic();
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# unless it's something special (ie not a .c file).
|
# 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_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
|
||||||
obj-$(CONFIG_KGDB) += tx4927_dbgio.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)
|
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, "-\n");
|
||||||
|
|
||||||
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_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_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n");
|
||||||
tx4927_irq_pic_init();
|
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");
|
TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tx4927_irq_nested(void)
|
static int tx4927_irq_nested(void)
|
||||||
{
|
{
|
||||||
int sw_irq = 0;
|
int sw_irq = 0;
|
||||||
u32 level2;
|
u32 level2;
|
||||||
|
@ -582,3 +576,25 @@ int tx4927_irq_nested(void)
|
||||||
|
|
||||||
return (sw_irq);
|
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).
|
# 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
|
obj-$(CONFIG_KGDB) += dbgio.o
|
||||||
|
|
||||||
|
|
|
@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq)
|
||||||
void __init
|
void __init
|
||||||
tx4938_irq_init(void)
|
tx4938_irq_init(void)
|
||||||
{
|
{
|
||||||
extern asmlinkage void tx4938_irq_handler(void);
|
|
||||||
|
|
||||||
tx4938_irq_cp0_init();
|
tx4938_irq_cp0_init();
|
||||||
tx4938_irq_pic_init();
|
tx4938_irq_pic_init();
|
||||||
set_except_vector(0, tx4938_irq_handler);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -422,3 +419,21 @@ tx4938_irq_nested(void)
|
||||||
wbflush();
|
wbflush();
|
||||||
return (sw_irq);
|
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.
|
# 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
|
obj-$(CONFIG_VRC4173) += vrc4173.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := $(CFLAGS)
|
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);
|
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_cascade_t *cascade;
|
||||||
irq_desc_t *desc;
|
irq_desc_t *desc;
|
||||||
|
@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
|
||||||
do_IRQ(irq, 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)
|
void __init arch_init_irq(void)
|
||||||
{
|
{
|
||||||
mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
|
mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
|
||||||
|
|
||||||
set_except_vector(0, vr41xx_handle_interrupt);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue