📄 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-2005 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/errno.h>#include <linux/init.h>#include <linux/ioport.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/vr41xx/vr41xx.h>static void __iomem *icu1_base;static void __iomem *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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };#define ICU1_TYPE1_BASE 0x0b000080UL#define ICU2_TYPE1_BASE 0x0b000200UL#define ICU1_TYPE2_BASE 0x0f000080UL#define ICU2_TYPE2_BASE 0x0f0000a0UL#define ICU1_SIZE 0x20#define ICU2_SIZE 0x1c#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 INT_TO_IRQ(x) ((x) + 2) /* Int0-4 -> IRQ2-6 */#define icu1_read(offset) readw(icu1_base + (offset))#define icu1_write(offset, value) writew((value), icu1_base + (offset))#define icu2_read(offset) readw(icu2_base + (offset))#define icu2_write(offset, value) writew((value), icu2_base + (offset))#define INTASSIGN_MAX 4#define INTASSIGN_MASK 0x0007static inline uint16_t icu1_set(uint8_t offset, uint16_t set){ uint16_t data; data = icu1_read(offset); data |= set; icu1_write(offset, data); return data;}static inline uint16_t icu1_clear(uint8_t offset, uint16_t clear){ uint16_t data; data = icu1_read(offset); data &= ~clear; icu1_write(offset, data); return data;}static inline uint16_t icu2_set(uint8_t offset, uint16_t set){ uint16_t data; data = icu2_read(offset); data |= set; icu2_write(offset, data); return data;}static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear){ uint16_t data; data = icu2_read(offset); data &= ~clear; icu2_write(offset, data); return data;}void vr41xx_enable_piuint(uint16_t mask){ irq_desc_t *desc = irq_desc + PIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_set(MPIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_piuint);void vr41xx_disable_piuint(uint16_t mask){ irq_desc_t *desc = irq_desc + PIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_clear(MPIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_disable_piuint);void vr41xx_enable_aiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + AIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_set(MAIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_aiuint);void vr41xx_disable_aiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + AIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_clear(MAIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_disable_aiuint);void vr41xx_enable_kiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + KIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_set(MKIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_kiuint);void vr41xx_disable_kiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + KIU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4111 || current_cpu_data.cputype == CPU_VR4121) { spin_lock_irqsave(&desc->lock, flags); icu1_clear(MKIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_disable_kiuint);void vr41xx_enable_dsiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + DSIU_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); icu1_set(MDSIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags);}EXPORT_SYMBOL(vr41xx_enable_dsiuint);void vr41xx_disable_dsiuint(uint16_t mask){ irq_desc_t *desc = irq_desc + DSIU_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); icu1_clear(MDSIUINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags);}EXPORT_SYMBOL(vr41xx_disable_dsiuint);void vr41xx_enable_firint(uint16_t mask){ irq_desc_t *desc = irq_desc + FIR_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); icu2_set(MFIRINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags);}EXPORT_SYMBOL(vr41xx_enable_firint);void vr41xx_disable_firint(uint16_t mask){ irq_desc_t *desc = irq_desc + FIR_IRQ; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); icu2_clear(MFIRINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags);}EXPORT_SYMBOL(vr41xx_disable_firint);void vr41xx_enable_pciint(void){ irq_desc_t *desc = irq_desc + PCI_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4122 || current_cpu_data.cputype == CPU_VR4131 || current_cpu_data.cputype == CPU_VR4133) { spin_lock_irqsave(&desc->lock, flags); icu2_write(MPCIINTREG, PCIINT0); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_pciint);void vr41xx_disable_pciint(void){ irq_desc_t *desc = irq_desc + PCI_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4122 || current_cpu_data.cputype == CPU_VR4131 || current_cpu_data.cputype == CPU_VR4133) { spin_lock_irqsave(&desc->lock, flags); icu2_write(MPCIINTREG, 0); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_disable_pciint);void vr41xx_enable_scuint(void){ irq_desc_t *desc = irq_desc + SCU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4122 || current_cpu_data.cputype == CPU_VR4131 || current_cpu_data.cputype == CPU_VR4133) { spin_lock_irqsave(&desc->lock, flags); icu2_write(MSCUINTREG, SCUINT0); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_scuint);void vr41xx_disable_scuint(void){ irq_desc_t *desc = irq_desc + SCU_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4122 || current_cpu_data.cputype == CPU_VR4131 || current_cpu_data.cputype == CPU_VR4133) { spin_lock_irqsave(&desc->lock, flags); icu2_write(MSCUINTREG, 0); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_disable_scuint);void vr41xx_enable_csiint(uint16_t mask){ irq_desc_t *desc = irq_desc + CSI_IRQ; unsigned long flags; if (current_cpu_data.cputype == CPU_VR4122 || current_cpu_data.cputype == CPU_VR4131 || current_cpu_data.cputype == CPU_VR4133) { spin_lock_irqsave(&desc->lock, flags); icu2_set(MCSIINTREG, mask); spin_unlock_irqrestore(&desc->lock, flags); }}EXPORT_SYMBOL(vr41xx_enable_csiint);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -