|
From: Paul M. <le...@us...> - 2002-06-14 14:06:48
|
Update of /cvsroot/linux-mips/linux/arch/mips/vr41xx/vr4181/common
In directory usw-pr-cvs1:/tmp/cvs-serv334
Modified Files:
Makefile
Added Files:
icu.c icu.h
Removed Files:
int_handler.S irq.c
Log Message:
Nuke the old interrupt handling code, use the new common interface.
--- NEW FILE: icu.c ---
/*
* FILE NAME
* arch/mips/vr41xx/vr4111/common/icu.c
*
* BRIEF MODULE DESCRIPTION
* Interrupt Control Unit routines for the NEC VR4111.
*
* Author: Yoichi Yuasa
* yy...@mv... or so...@mv...
*
* 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.
*/
/*
* Changes:
* Paul Mundt <le...@ch...>
* - kgdb support.
*
* MontaVista Software Inc. <yy...@mv...> or <so...@mv...>
* - New creation, NEC VR4122 and VR4131 are supported.
*
* Yoichi Yuasa <yu...@hh...> Tue, 5 Mar 2002
* - This file was copied from arch/mips/vr41xx/vr4122/common/icu.c.
* Only FILE NAME and BRIEF MODULE DESCRIPTION modified this file.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/vr41xx.h>
#include <asm/gdb-stub.h>
#include "icu.h"
extern asmlinkage void vr41xx_handle_interrupt(void);
extern void __init init_generic_irq(void);
extern void mips_cpu_irq_init(u32 irq_base);
extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
/*=======================================================================*/
static void enable_sysint1_irq(unsigned int irq)
{
u16 val;
val = readw(MSYSINT1REG);
val |= (u16)1 << (irq - SYSINT1_IRQ_BASE);
writew(val, MSYSINT1REG);
}
static void disable_sysint1_irq(unsigned int irq)
{
u16 val;
val = readw(MSYSINT1REG);
val &= ~((u16)1 << (irq - SYSINT1_IRQ_BASE));
writew(val, MSYSINT1REG);
}
static unsigned int startup_sysint1_irq(unsigned int irq)
{
enable_sysint1_irq(irq);
return 0; /* never anything pending */
}
#define shutdown_sysint1_irq disable_sysint1_irq
#define ack_sysint1_irq disable_sysint1_irq
static void end_sysint1_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_sysint1_irq(irq);
}
static struct hw_interrupt_type sysint1_irq_type = {
"SYSINT1",
startup_sysint1_irq,
shutdown_sysint1_irq,
enable_sysint1_irq,
disable_sysint1_irq,
ack_sysint1_irq,
end_sysint1_irq,
NULL
};
/*=======================================================================*/
static void enable_sysint2_irq(unsigned int irq)
{
u16 val;
val = readw(MSYSINT2REG);
val |= (u16)1 << (irq - SYSINT2_IRQ_BASE);
writew(val, MSYSINT2REG);
}
static void disable_sysint2_irq(unsigned int irq)
{
u16 val;
val = readw(MSYSINT2REG);
val &= ~((u16)1 << (irq - SYSINT2_IRQ_BASE));
writew(val, MSYSINT2REG);
}
static unsigned int startup_sysint2_irq(unsigned int irq)
{
enable_sysint2_irq(irq);
return 0; /* never anything pending */
}
#define shutdown_sysint2_irq disable_sysint2_irq
#define ack_sysint2_irq disable_sysint2_irq
static void end_sysint2_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_sysint2_irq(irq);
}
static struct hw_interrupt_type sysint2_irq_type = {
"SYSINT2",
startup_sysint2_irq,
shutdown_sysint2_irq,
enable_sysint2_irq,
disable_sysint2_irq,
ack_sysint2_irq,
end_sysint2_irq,
NULL
};
/*=======================================================================*/
static void enable_giuintl_irq(unsigned int irq)
{
u16 val, mask;
mask = (u16)1 << (irq - GIUINTL_IRQ_BASE);
writew(mask, GIUINTSTATL);
val = readw(MGIUINTLREG);
val |= mask;
writew(val, MGIUINTLREG);
val = readw(GIUINTENL);
val |= mask;
writew(val, GIUINTENL);
}
static void disable_giuintl_irq(unsigned int irq)
{
u16 val, mask;
mask = (u16)1 << (irq - GIUINTL_IRQ_BASE);
val = readw(GIUINTENL);
val &= ~mask;
writew(val, GIUINTENL);
val = readw(MGIUINTLREG);
val &= ~mask;
writew(val, MGIUINTLREG);
writew(mask, GIUINTSTATL);
}
static unsigned int startup_giuintl_irq(unsigned int irq)
{
enable_giuintl_irq(irq);
return 0; /* never anything pending */
}
#define shutdown_giuintl_irq disable_giuintl_irq
#define ack_giuintl_irq disable_giuintl_irq
static void end_giuintl_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_giuintl_irq(irq);
}
static struct hw_interrupt_type giuintl_irq_type = {
"GIUINTL",
startup_giuintl_irq,
shutdown_giuintl_irq,
enable_giuintl_irq,
disable_giuintl_irq,
ack_giuintl_irq,
end_giuintl_irq,
NULL
};
/*=======================================================================*/
static void enable_giuinth_irq(unsigned int irq)
{
unsigned short val, mask;
mask = (u16)1 << (irq - GIUINTH_IRQ_BASE);
writew(mask, GIUINTSTATH);
val = readw(MGIUINTHREG);
val |= mask;
writew(val, MGIUINTHREG);
val = readw(GIUINTENH);
val |= mask;
writew(val, GIUINTENH);
}
static void disable_giuinth_irq(unsigned int irq)
{
unsigned short val, mask;
mask = (u16)1 << (irq - GIUINTH_IRQ_BASE);
val= readw(GIUINTENH);
val &= ~mask;
writew(val, GIUINTENH);
val = readw(MGIUINTHREG);
val &= ~mask;
writew(val, MGIUINTHREG);
writew(mask, GIUINTSTATH);
}
static unsigned int startup_giuinth_irq(unsigned int irq)
{
enable_giuinth_irq(irq);
return 0; /* never anything pending */
}
#define shutdown_giuinth_irq disable_giuinth_irq
#define ack_giuinth_irq disable_giuinth_irq
static void end_giuinth_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_giuinth_irq(irq);
}
static struct hw_interrupt_type giuinth_irq_type = {
"GIUINTH",
startup_giuinth_irq,
shutdown_giuinth_irq,
enable_giuinth_irq,
disable_giuinth_irq,
ack_giuinth_irq,
end_giuinth_irq,
NULL
};
/*=======================================================================*/
static struct irqcascade vr41xx_irqcascade[32];
static struct irqaction cascade = {no_action, 0, 0, "cascade", NULL, NULL};
static int no_cascade_get_irq_number(int irq) { return -1; }
void vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq))
{
if (GIUINTL_IRQ_BASE <= irq < GIUINTH_IRQ_LAST) {
vr41xx_irqcascade[irq - GIUINTL_IRQ_BASE].cascade = 1;
vr41xx_irqcascade[irq - GIUINTL_IRQ_BASE].get_irq_number = get_irq_number;
setup_irq(irq, &cascade);
}
}
static void __init vr41xx_icu_irq_init(void)
{
int i;
writew(0, MSYSINT1REG);
writew(0, MSYSINT2REG);
writew(0, MGIUINTLREG);
writew(0, MGIUINTHREG);
writew(0, GIUINTENL);
writew(0, GIUINTENH);
writew(0xffff, GIUINTSTATL);
writew(0xffff, GIUINTSTATH);
for (i = SYSINT1_IRQ_BASE; i <= GIUINTH_IRQ_LAST; i++) {
if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST)
irq_desc[i].handler = &sysint1_irq_type;
else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST)
irq_desc[i].handler = &sysint2_irq_type;
else if (i >= GIUINTL_IRQ_BASE && i <= GIUINTL_IRQ_LAST)
irq_desc[i].handler = &giuintl_irq_type;
else if (i >= GIUINTH_IRQ_BASE && i <= GIUINTH_IRQ_LAST)
irq_desc[i].handler = &giuinth_irq_type;
}
for (i = 0; i < 32; i++) {
vr41xx_irqcascade[i].cascade = 0;
vr41xx_irqcascade[i].get_irq_number = no_cascade_get_irq_number;
}
}
void __init init_IRQ(void)
{
memset(irq_desc, 0, sizeof(irq_desc));
init_generic_irq();
mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
vr41xx_icu_irq_init();
vr41xx_board_irq_init();
setup_irq(ICU_IRQ, &cascade);
setup_irq(GIU_IRQ, &cascade);
set_except_vector(0, vr41xx_handle_interrupt);
#ifdef CONFIG_REMOTE_DEBUG
printk("Setting debug traps - please connect the remote debugger.\n");
set_debug_traps();
breakpoint();
#endif
}
/*=======================================================================*/
static void giuint_do_IRQ(int giuint_irq, struct pt_regs *regs)
{
struct irqcascade *irq;
int cascade_irq;
irq = &vr41xx_irqcascade[giuint_irq - GIUINTL_IRQ_BASE];
if (irq->cascade) {
cascade_irq = irq->get_irq_number(giuint_irq);
disable_irq(giuint_irq);
if (cascade_irq > 0)
do_IRQ(cascade_irq, regs);
enable_irq(giuint_irq);
}
else
do_IRQ(giuint_irq, regs);
}
static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs)
{
int i;
if (pendl) {
for (i = 0; i < 16; i++) {
if (pendl & (0x0001 << i)) {
giuint_do_IRQ(GIUINTL_IRQ_BASE + i, regs);
return;
}
}
}
else if (pendh) {
for (i = 0; i < 16; i++) {
if (pendh & (0x0001 << i)) {
giuint_do_IRQ(GIUINTH_IRQ_BASE + i, regs);
return;
}
}
}
}
asmlinkage void icu_irqdispatch(struct pt_regs *regs)
{
u16 pend1, pend2, pendl, pendh;
u16 mask1, mask2, maskl, maskh;
int i;
pend1 = readw(SYSINT1REG);
mask1 = readw(MSYSINT1REG);
pend2 = readw(SYSINT2REG);
mask2 = readw(MSYSINT2REG);
pendl = readw(GIUINTLREG);
maskl = readw(MGIUINTLREG);
pendh = readw(GIUINTHREG);
maskh = readw(MGIUINTHREG);
pend1 &= mask1;
pend2 &= mask2;
pendl &= maskl;
pendh &= maskh;
if (pend1) {
if ((pend1 & 0x01ff) == 0x0100) {
giuint_irqdispatch(pendl, pendh, regs);
}
else {
for (i = 0; i < 16; i++) {
if (pend1 & (0x0001 << i)) {
do_IRQ(SYSINT1_IRQ_BASE + i, regs);
break;
}
}
}
return;
}
else if (pend2) {
for (i = 0; i < 16; i++) {
if (pend2 & (0x0001 << i)) {
do_IRQ(SYSINT2_IRQ_BASE + i, regs);
break;
}
}
}
}
--- NEW FILE: icu.h ---
/*
* FILE NAME
* arch/mips/vr41xx/vr4111/common/icu.h
*
* BRIEF MODULE DESCRIPTION
* Include file for Interrupt Control Unit of the NEC VR4111.
*
* Author: Yoichi Yuasa
* yy...@mv... or so...@mv...
*
* Copyright 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.
*/
/*
* Changes:
* MontaVista Software Inc. <yy...@mv...> or <so...@mv...>
* - New creation, NEC VR4122 and VR4131 are supported.
*
* Yoichi Yuasa <yu...@hh...> Tue, 5 Mar 2002
* - Modified this code for VR4121 support.
*
* Yoichi Yuasa <yu...@hh...> Tue, 5 Mar 2002
* - This file was copied from arch/mips/vr41xx/vr4121/common/icu.h.
* Only FILE NAME and BRIEF MODULE DESCRIPTION modified this file.
*/
#ifndef __VR41XX_ICU_H
#define __VR41XX_ICU_H
#include <linux/config.h>
#include <asm/addrspace.h>
#define SYSINT1REG KSEG1ADDR(0x0b000080)
#define GIUINTLREG KSEG1ADDR(0x0b000088)
#define MSYSINT1REG KSEG1ADDR(0x0b00008c)
#define MGIUINTLREG KSEG1ADDR(0x0b000094)
#define NMIREG KSEG1ADDR(0x0b000098)
#define SOFTINTREG KSEG1ADDR(0x0b00009a)
#define SYSINT2REG KSEG1ADDR(0x0b000200)
#define GIUINTHREG KSEG1ADDR(0x0b000202)
#define MSYSINT2REG KSEG1ADDR(0x0b000206)
#define MGIUINTHREG KSEG1ADDR(0x0b000208)
#define GIUINTSTATL KSEG1ADDR(0x0b000108)
#define GIUINTSTATH KSEG1ADDR(0x0b00010a)
#define GIUINTENL KSEG1ADDR(0x0b00010c)
#define GIUINTENH KSEG1ADDR(0x0b00010e)
#define GIUINTTYPL KSEG1ADDR(0x0b000110)
#define GIUINTTYPH KSEG1ADDR(0x0b000112)
#define GIUINTALSELL KSEG1ADDR(0x0b000114)
#define GIUINTALSELH KSEG1ADDR(0x0b000116)
#define GIUINTHTSELL KSEG1ADDR(0x0b000118)
#define GIUINTHTSELH KSEG1ADDR(0x0b00011a)
#define MIPS_CPU_IRQ_BASE 0
#define SYSINT1_IRQ_BASE 8
#define SYSINT1_IRQ_LAST 23
#define SYSINT2_IRQ_BASE 24
#define SYSINT2_IRQ_LAST 39
#define GIUINTL_IRQ_BASE 40
#define GIUINTL_IRQ_LAST 55
#define GIUINTH_IRQ_BASE 56
#define GIUINTH_IRQ_LAST 71
#define ICU_IRQ 2
#define GIU_IRQ (SYSINT1_IRQ_BASE + 8)
#endif /* __VR41XX_ICU_H */
Index: Makefile
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/vr41xx/vr4181/common/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Makefile 14 Jun 2002 13:54:59 -0000 1.1
+++ Makefile 14 Jun 2002 14:06:46 -0000 1.2
@@ -13,6 +13,6 @@
O_TARGET:= vr4181.o
-obj-y := irq.o int_handler.o serial.o time.o
+obj-y := icu.o serial.o time.o
include $(TOPDIR)/Rules.make
--- int_handler.S DELETED ---
--- irq.c DELETED ---
|