📄 icu.c
字号:
/* * icu.c, Interrupt Control Unit routines for the NEC VR4100 series. * * Copyright (C) 2001-2002 MontaVista Software Inc. * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> * Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> * * 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 *//* * Changes: * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> * - Coped with INTASSIGN of NEC VR4133. */#include <linux/config.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/module.h>#include <linux/smp.h>#include <linux/types.h>#include <asm/cpu.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/irq_cpu.h>#include <asm/vr41xx/vr41xx.h>extern asmlinkage void vr41xx_handle_interrupt(void);extern void init_vr41xx_giuint_irq(void);extern void giuint_irq_dispatch(struct pt_regs *regs);static uint32_t icu1_base;static uint32_t icu2_base;static unsigned char sysint1_assign[16] = { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };static unsigned char sysint2_assign[16] = { 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };#define SYSINT1REG_TYPE1 KSEG1ADDR(0x0b000080)#define SYSINT2REG_TYPE1 KSEG1ADDR(0x0b000200)#define SYSINT1REG_TYPE2 KSEG1ADDR(0x0f000080)#define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0)#define SYSINT1REG 0x00#define PIUINTREG 0x02#define INTASSIGN0 0x04#define INTASSIGN1 0x06#define GIUINTLREG 0x08#define DSIUINTREG 0x0a#define MSYSINT1REG 0x0c#define MPIUINTREG 0x0e#define MAIUINTREG 0x10#define MKIUINTREG 0x12#define MGIUINTLREG 0x14#define MDSIUINTREG 0x16#define NMIREG 0x18#define SOFTREG 0x1a#define INTASSIGN2 0x1c#define INTASSIGN3 0x1e#define SYSINT2REG 0x00#define GIUINTHREG 0x02#define FIRINTREG 0x04#define MSYSINT2REG 0x06#define MGIUINTHREG 0x08#define MFIRINTREG 0x0a#define PCIINTREG 0x0c #define PCIINT0 0x0001#define SCUINTREG 0x0e #define SCUINT0 0x0001#define CSIINTREG 0x10#define MPCIINTREG 0x12#define MSCUINTREG 0x14#define MCSIINTREG 0x16#define BCUINTREG 0x18 #define BCUINTR 0x0001#define MBCUINTREG 0x1a#define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */#define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */#define read_icu1(offset) readw(icu1_base + (offset))#define write_icu1(val, offset) writew((val), icu1_base + (offset))#define read_icu2(offset) readw(icu2_base + (offset))#define write_icu2(val, offset) writew((val), icu2_base + (offset))#define INTASSIGN_MAX 4#define INTASSIGN_MASK 0x0007static inline uint16_t set_icu1(uint8_t offset, uint16_t set){ uint16_t res; res = read_icu1(offset); res |= set; write_icu1(res, offset); return res;}static inline uint16_t clear_icu1(uint8_t offset, uint16_t clear){ uint16_t res; res = read_icu1(offset); res &= ~clear; write_icu1(res, offset); return res;}static inline uint16_t set_icu2(uint8_t offset, uint16_t set){ uint16_t res; res = read_icu2(offset); res |= set; write_icu2(res, offset); return res;}static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear){ uint16_t res; res = read_icu2(offset); res &= ~clear; write_icu2(res, offset); return res;}/*=======================================================================*/void vr41xx_enable_piuint(uint16_t mask){ irq_desc_t *desc = irq_desc + PIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MPIUINTREG); val |= mask; write_icu1(val, MPIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_piuint(uint16_t mask){ irq_desc_t *desc = irq_desc + PIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MPIUINTREG); val &= ~mask; write_icu1(val, MPIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_aiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + AIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MAIUINTREG); val |= mask; write_icu1(val, MAIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_aiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + AIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MAIUINTREG); val &= ~mask; write_icu1(val, MAIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_kiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + KIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MKIUINTREG); val |= mask; write_icu1(val, MKIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_kiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + KIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MKIUINTREG); val &= ~mask; write_icu1(val, MKIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_dsiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + DSIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MDSIUINTREG); val |= mask; write_icu1(val, MDSIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_dsiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + DSIU_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu1(MDSIUINTREG); val &= ~mask; write_icu1(val, MDSIUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_firint(uint16_t mask){ irq_desc_t *desc = irq_desc + FIR_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu2(MFIRINTREG); val |= mask; write_icu2(val, MFIRINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_firint(uint16_t mask){ irq_desc_t *desc = irq_desc + FIR_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu2(MFIRINTREG); val &= ~mask; write_icu2(val, MFIRINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_pciint(void){ irq_desc_t *desc = irq_desc + PCI_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); write_icu2(PCIINT0, MPCIINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_pciint(void){ irq_desc_t *desc = irq_desc + PCI_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); write_icu2(0, MPCIINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_scuint(void){ irq_desc_t *desc = irq_desc + SCU_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); write_icu2(SCUINT0, MSCUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_scuint(void){ irq_desc_t *desc = irq_desc + SCU_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); write_icu2(0, MSCUINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_csiint(uint16_t mask){ irq_desc_t *desc = irq_desc + CSI_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu2(MCSIINTREG); val |= mask; write_icu2(val, MCSIINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_csiint(uint16_t mask){ irq_desc_t *desc = irq_desc + CSI_IRQ; unsigned long flags; uint16_t val; spin_lock_irqsave(&desc->lock, flags); val = read_icu2(MCSIINTREG); val &= ~mask; write_icu2(val, MCSIINTREG); spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_enable_bcuint(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -