cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

icu.c (16719B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  icu.c, Interrupt Control Unit routines for the NEC VR4100 series.
      4 *
      5 *  Copyright (C) 2001-2002  MontaVista Software Inc.
      6 *    Author: Yoichi Yuasa <source@mvista.com>
      7 *  Copyright (C) 2003-2006  Yoichi Yuasa <yuasa@linux-mips.org>
      8 */
      9/*
     10 * Changes:
     11 *  MontaVista Software Inc. <source@mvista.com>
     12 *  - New creation, NEC VR4122 and VR4131 are supported.
     13 *  - Added support for NEC VR4111 and VR4121.
     14 *
     15 *  Yoichi Yuasa <yuasa@linux-mips.org>
     16 *  - Coped with INTASSIGN of NEC VR4133.
     17 */
     18#include <linux/errno.h>
     19#include <linux/export.h>
     20#include <linux/init.h>
     21#include <linux/ioport.h>
     22#include <linux/irq.h>
     23#include <linux/smp.h>
     24#include <linux/types.h>
     25
     26#include <asm/cpu.h>
     27#include <asm/io.h>
     28#include <asm/vr41xx/irq.h>
     29#include <asm/vr41xx/vr41xx.h>
     30
     31static void __iomem *icu1_base;
     32static void __iomem *icu2_base;
     33
     34static unsigned char sysint1_assign[16] = {
     35	0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     36static unsigned char sysint2_assign[16] = {
     37	2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     38
     39#define ICU1_TYPE1_BASE 0x0b000080UL
     40#define ICU2_TYPE1_BASE 0x0b000200UL
     41
     42#define ICU1_TYPE2_BASE 0x0f000080UL
     43#define ICU2_TYPE2_BASE 0x0f0000a0UL
     44
     45#define ICU1_SIZE	0x20
     46#define ICU2_SIZE	0x1c
     47
     48#define SYSINT1REG	0x00
     49#define PIUINTREG	0x02
     50#define INTASSIGN0	0x04
     51#define INTASSIGN1	0x06
     52#define GIUINTLREG	0x08
     53#define DSIUINTREG	0x0a
     54#define MSYSINT1REG	0x0c
     55#define MPIUINTREG	0x0e
     56#define MAIUINTREG	0x10
     57#define MKIUINTREG	0x12
     58#define MMACINTREG	0x12
     59#define MGIUINTLREG	0x14
     60#define MDSIUINTREG	0x16
     61#define NMIREG		0x18
     62#define SOFTREG		0x1a
     63#define INTASSIGN2	0x1c
     64#define INTASSIGN3	0x1e
     65
     66#define SYSINT2REG	0x00
     67#define GIUINTHREG	0x02
     68#define FIRINTREG	0x04
     69#define MSYSINT2REG	0x06
     70#define MGIUINTHREG	0x08
     71#define MFIRINTREG	0x0a
     72#define PCIINTREG	0x0c
     73 #define PCIINT0	0x0001
     74#define SCUINTREG	0x0e
     75 #define SCUINT0	0x0001
     76#define CSIINTREG	0x10
     77#define MPCIINTREG	0x12
     78#define MSCUINTREG	0x14
     79#define MCSIINTREG	0x16
     80#define BCUINTREG	0x18
     81 #define BCUINTR	0x0001
     82#define MBCUINTREG	0x1a
     83
     84#define SYSINT1_IRQ_TO_PIN(x)	((x) - SYSINT1_IRQ_BASE)	/* Pin 0-15 */
     85#define SYSINT2_IRQ_TO_PIN(x)	((x) - SYSINT2_IRQ_BASE)	/* Pin 0-15 */
     86
     87#define INT_TO_IRQ(x)		((x) + 2)	/* Int0-4 -> IRQ2-6 */
     88
     89#define icu1_read(offset)		readw(icu1_base + (offset))
     90#define icu1_write(offset, value)	writew((value), icu1_base + (offset))
     91
     92#define icu2_read(offset)		readw(icu2_base + (offset))
     93#define icu2_write(offset, value)	writew((value), icu2_base + (offset))
     94
     95#define INTASSIGN_MAX	4
     96#define INTASSIGN_MASK	0x0007
     97
     98static inline uint16_t icu1_set(uint8_t offset, uint16_t set)
     99{
    100	uint16_t data;
    101
    102	data = icu1_read(offset);
    103	data |= set;
    104	icu1_write(offset, data);
    105
    106	return data;
    107}
    108
    109static inline uint16_t icu1_clear(uint8_t offset, uint16_t clear)
    110{
    111	uint16_t data;
    112
    113	data = icu1_read(offset);
    114	data &= ~clear;
    115	icu1_write(offset, data);
    116
    117	return data;
    118}
    119
    120static inline uint16_t icu2_set(uint8_t offset, uint16_t set)
    121{
    122	uint16_t data;
    123
    124	data = icu2_read(offset);
    125	data |= set;
    126	icu2_write(offset, data);
    127
    128	return data;
    129}
    130
    131static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear)
    132{
    133	uint16_t data;
    134
    135	data = icu2_read(offset);
    136	data &= ~clear;
    137	icu2_write(offset, data);
    138
    139	return data;
    140}
    141
    142void vr41xx_enable_piuint(uint16_t mask)
    143{
    144	struct irq_desc *desc = irq_to_desc(PIU_IRQ);
    145	unsigned long flags;
    146
    147	if (current_cpu_type() == CPU_VR4111 ||
    148	    current_cpu_type() == CPU_VR4121) {
    149		raw_spin_lock_irqsave(&desc->lock, flags);
    150		icu1_set(MPIUINTREG, mask);
    151		raw_spin_unlock_irqrestore(&desc->lock, flags);
    152	}
    153}
    154
    155EXPORT_SYMBOL(vr41xx_enable_piuint);
    156
    157void vr41xx_disable_piuint(uint16_t mask)
    158{
    159	struct irq_desc *desc = irq_to_desc(PIU_IRQ);
    160	unsigned long flags;
    161
    162	if (current_cpu_type() == CPU_VR4111 ||
    163	    current_cpu_type() == CPU_VR4121) {
    164		raw_spin_lock_irqsave(&desc->lock, flags);
    165		icu1_clear(MPIUINTREG, mask);
    166		raw_spin_unlock_irqrestore(&desc->lock, flags);
    167	}
    168}
    169
    170EXPORT_SYMBOL(vr41xx_disable_piuint);
    171
    172void vr41xx_enable_aiuint(uint16_t mask)
    173{
    174	struct irq_desc *desc = irq_to_desc(AIU_IRQ);
    175	unsigned long flags;
    176
    177	if (current_cpu_type() == CPU_VR4111 ||
    178	    current_cpu_type() == CPU_VR4121) {
    179		raw_spin_lock_irqsave(&desc->lock, flags);
    180		icu1_set(MAIUINTREG, mask);
    181		raw_spin_unlock_irqrestore(&desc->lock, flags);
    182	}
    183}
    184
    185EXPORT_SYMBOL(vr41xx_enable_aiuint);
    186
    187void vr41xx_disable_aiuint(uint16_t mask)
    188{
    189	struct irq_desc *desc = irq_to_desc(AIU_IRQ);
    190	unsigned long flags;
    191
    192	if (current_cpu_type() == CPU_VR4111 ||
    193	    current_cpu_type() == CPU_VR4121) {
    194		raw_spin_lock_irqsave(&desc->lock, flags);
    195		icu1_clear(MAIUINTREG, mask);
    196		raw_spin_unlock_irqrestore(&desc->lock, flags);
    197	}
    198}
    199
    200EXPORT_SYMBOL(vr41xx_disable_aiuint);
    201
    202void vr41xx_enable_kiuint(uint16_t mask)
    203{
    204	struct irq_desc *desc = irq_to_desc(KIU_IRQ);
    205	unsigned long flags;
    206
    207	if (current_cpu_type() == CPU_VR4111 ||
    208	    current_cpu_type() == CPU_VR4121) {
    209		raw_spin_lock_irqsave(&desc->lock, flags);
    210		icu1_set(MKIUINTREG, mask);
    211		raw_spin_unlock_irqrestore(&desc->lock, flags);
    212	}
    213}
    214
    215EXPORT_SYMBOL(vr41xx_enable_kiuint);
    216
    217void vr41xx_disable_kiuint(uint16_t mask)
    218{
    219	struct irq_desc *desc = irq_to_desc(KIU_IRQ);
    220	unsigned long flags;
    221
    222	if (current_cpu_type() == CPU_VR4111 ||
    223	    current_cpu_type() == CPU_VR4121) {
    224		raw_spin_lock_irqsave(&desc->lock, flags);
    225		icu1_clear(MKIUINTREG, mask);
    226		raw_spin_unlock_irqrestore(&desc->lock, flags);
    227	}
    228}
    229
    230EXPORT_SYMBOL(vr41xx_disable_kiuint);
    231
    232void vr41xx_enable_macint(uint16_t mask)
    233{
    234	struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
    235	unsigned long flags;
    236
    237	raw_spin_lock_irqsave(&desc->lock, flags);
    238	icu1_set(MMACINTREG, mask);
    239	raw_spin_unlock_irqrestore(&desc->lock, flags);
    240}
    241
    242EXPORT_SYMBOL(vr41xx_enable_macint);
    243
    244void vr41xx_disable_macint(uint16_t mask)
    245{
    246	struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
    247	unsigned long flags;
    248
    249	raw_spin_lock_irqsave(&desc->lock, flags);
    250	icu1_clear(MMACINTREG, mask);
    251	raw_spin_unlock_irqrestore(&desc->lock, flags);
    252}
    253
    254EXPORT_SYMBOL(vr41xx_disable_macint);
    255
    256void vr41xx_enable_dsiuint(uint16_t mask)
    257{
    258	struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
    259	unsigned long flags;
    260
    261	raw_spin_lock_irqsave(&desc->lock, flags);
    262	icu1_set(MDSIUINTREG, mask);
    263	raw_spin_unlock_irqrestore(&desc->lock, flags);
    264}
    265
    266EXPORT_SYMBOL(vr41xx_enable_dsiuint);
    267
    268void vr41xx_disable_dsiuint(uint16_t mask)
    269{
    270	struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
    271	unsigned long flags;
    272
    273	raw_spin_lock_irqsave(&desc->lock, flags);
    274	icu1_clear(MDSIUINTREG, mask);
    275	raw_spin_unlock_irqrestore(&desc->lock, flags);
    276}
    277
    278EXPORT_SYMBOL(vr41xx_disable_dsiuint);
    279
    280void vr41xx_enable_firint(uint16_t mask)
    281{
    282	struct irq_desc *desc = irq_to_desc(FIR_IRQ);
    283	unsigned long flags;
    284
    285	raw_spin_lock_irqsave(&desc->lock, flags);
    286	icu2_set(MFIRINTREG, mask);
    287	raw_spin_unlock_irqrestore(&desc->lock, flags);
    288}
    289
    290EXPORT_SYMBOL(vr41xx_enable_firint);
    291
    292void vr41xx_disable_firint(uint16_t mask)
    293{
    294	struct irq_desc *desc = irq_to_desc(FIR_IRQ);
    295	unsigned long flags;
    296
    297	raw_spin_lock_irqsave(&desc->lock, flags);
    298	icu2_clear(MFIRINTREG, mask);
    299	raw_spin_unlock_irqrestore(&desc->lock, flags);
    300}
    301
    302EXPORT_SYMBOL(vr41xx_disable_firint);
    303
    304void vr41xx_enable_pciint(void)
    305{
    306	struct irq_desc *desc = irq_to_desc(PCI_IRQ);
    307	unsigned long flags;
    308
    309	if (current_cpu_type() == CPU_VR4122 ||
    310	    current_cpu_type() == CPU_VR4131 ||
    311	    current_cpu_type() == CPU_VR4133) {
    312		raw_spin_lock_irqsave(&desc->lock, flags);
    313		icu2_write(MPCIINTREG, PCIINT0);
    314		raw_spin_unlock_irqrestore(&desc->lock, flags);
    315	}
    316}
    317
    318EXPORT_SYMBOL(vr41xx_enable_pciint);
    319
    320void vr41xx_disable_pciint(void)
    321{
    322	struct irq_desc *desc = irq_to_desc(PCI_IRQ);
    323	unsigned long flags;
    324
    325	if (current_cpu_type() == CPU_VR4122 ||
    326	    current_cpu_type() == CPU_VR4131 ||
    327	    current_cpu_type() == CPU_VR4133) {
    328		raw_spin_lock_irqsave(&desc->lock, flags);
    329		icu2_write(MPCIINTREG, 0);
    330		raw_spin_unlock_irqrestore(&desc->lock, flags);
    331	}
    332}
    333
    334EXPORT_SYMBOL(vr41xx_disable_pciint);
    335
    336void vr41xx_enable_scuint(void)
    337{
    338	struct irq_desc *desc = irq_to_desc(SCU_IRQ);
    339	unsigned long flags;
    340
    341	if (current_cpu_type() == CPU_VR4122 ||
    342	    current_cpu_type() == CPU_VR4131 ||
    343	    current_cpu_type() == CPU_VR4133) {
    344		raw_spin_lock_irqsave(&desc->lock, flags);
    345		icu2_write(MSCUINTREG, SCUINT0);
    346		raw_spin_unlock_irqrestore(&desc->lock, flags);
    347	}
    348}
    349
    350EXPORT_SYMBOL(vr41xx_enable_scuint);
    351
    352void vr41xx_disable_scuint(void)
    353{
    354	struct irq_desc *desc = irq_to_desc(SCU_IRQ);
    355	unsigned long flags;
    356
    357	if (current_cpu_type() == CPU_VR4122 ||
    358	    current_cpu_type() == CPU_VR4131 ||
    359	    current_cpu_type() == CPU_VR4133) {
    360		raw_spin_lock_irqsave(&desc->lock, flags);
    361		icu2_write(MSCUINTREG, 0);
    362		raw_spin_unlock_irqrestore(&desc->lock, flags);
    363	}
    364}
    365
    366EXPORT_SYMBOL(vr41xx_disable_scuint);
    367
    368void vr41xx_enable_csiint(uint16_t mask)
    369{
    370	struct irq_desc *desc = irq_to_desc(CSI_IRQ);
    371	unsigned long flags;
    372
    373	if (current_cpu_type() == CPU_VR4122 ||
    374	    current_cpu_type() == CPU_VR4131 ||
    375	    current_cpu_type() == CPU_VR4133) {
    376		raw_spin_lock_irqsave(&desc->lock, flags);
    377		icu2_set(MCSIINTREG, mask);
    378		raw_spin_unlock_irqrestore(&desc->lock, flags);
    379	}
    380}
    381
    382EXPORT_SYMBOL(vr41xx_enable_csiint);
    383
    384void vr41xx_disable_csiint(uint16_t mask)
    385{
    386	struct irq_desc *desc = irq_to_desc(CSI_IRQ);
    387	unsigned long flags;
    388
    389	if (current_cpu_type() == CPU_VR4122 ||
    390	    current_cpu_type() == CPU_VR4131 ||
    391	    current_cpu_type() == CPU_VR4133) {
    392		raw_spin_lock_irqsave(&desc->lock, flags);
    393		icu2_clear(MCSIINTREG, mask);
    394		raw_spin_unlock_irqrestore(&desc->lock, flags);
    395	}
    396}
    397
    398EXPORT_SYMBOL(vr41xx_disable_csiint);
    399
    400void vr41xx_enable_bcuint(void)
    401{
    402	struct irq_desc *desc = irq_to_desc(BCU_IRQ);
    403	unsigned long flags;
    404
    405	if (current_cpu_type() == CPU_VR4122 ||
    406	    current_cpu_type() == CPU_VR4131 ||
    407	    current_cpu_type() == CPU_VR4133) {
    408		raw_spin_lock_irqsave(&desc->lock, flags);
    409		icu2_write(MBCUINTREG, BCUINTR);
    410		raw_spin_unlock_irqrestore(&desc->lock, flags);
    411	}
    412}
    413
    414EXPORT_SYMBOL(vr41xx_enable_bcuint);
    415
    416void vr41xx_disable_bcuint(void)
    417{
    418	struct irq_desc *desc = irq_to_desc(BCU_IRQ);
    419	unsigned long flags;
    420
    421	if (current_cpu_type() == CPU_VR4122 ||
    422	    current_cpu_type() == CPU_VR4131 ||
    423	    current_cpu_type() == CPU_VR4133) {
    424		raw_spin_lock_irqsave(&desc->lock, flags);
    425		icu2_write(MBCUINTREG, 0);
    426		raw_spin_unlock_irqrestore(&desc->lock, flags);
    427	}
    428}
    429
    430EXPORT_SYMBOL(vr41xx_disable_bcuint);
    431
    432static void disable_sysint1_irq(struct irq_data *d)
    433{
    434	icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
    435}
    436
    437static void enable_sysint1_irq(struct irq_data *d)
    438{
    439	icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
    440}
    441
    442static struct irq_chip sysint1_irq_type = {
    443	.name		= "SYSINT1",
    444	.irq_mask	= disable_sysint1_irq,
    445	.irq_unmask	= enable_sysint1_irq,
    446};
    447
    448static void disable_sysint2_irq(struct irq_data *d)
    449{
    450	icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
    451}
    452
    453static void enable_sysint2_irq(struct irq_data *d)
    454{
    455	icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
    456}
    457
    458static struct irq_chip sysint2_irq_type = {
    459	.name		= "SYSINT2",
    460	.irq_mask	= disable_sysint2_irq,
    461	.irq_unmask	= enable_sysint2_irq,
    462};
    463
    464static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
    465{
    466	struct irq_desc *desc = irq_to_desc(irq);
    467	uint16_t intassign0, intassign1;
    468	unsigned int pin;
    469
    470	pin = SYSINT1_IRQ_TO_PIN(irq);
    471
    472	raw_spin_lock_irq(&desc->lock);
    473
    474	intassign0 = icu1_read(INTASSIGN0);
    475	intassign1 = icu1_read(INTASSIGN1);
    476
    477	switch (pin) {
    478	case 0:
    479		intassign0 &= ~INTASSIGN_MASK;
    480		intassign0 |= (uint16_t)assign;
    481		break;
    482	case 1:
    483		intassign0 &= ~(INTASSIGN_MASK << 3);
    484		intassign0 |= (uint16_t)assign << 3;
    485		break;
    486	case 2:
    487		intassign0 &= ~(INTASSIGN_MASK << 6);
    488		intassign0 |= (uint16_t)assign << 6;
    489		break;
    490	case 3:
    491		intassign0 &= ~(INTASSIGN_MASK << 9);
    492		intassign0 |= (uint16_t)assign << 9;
    493		break;
    494	case 8:
    495		intassign0 &= ~(INTASSIGN_MASK << 12);
    496		intassign0 |= (uint16_t)assign << 12;
    497		break;
    498	case 9:
    499		intassign1 &= ~INTASSIGN_MASK;
    500		intassign1 |= (uint16_t)assign;
    501		break;
    502	case 11:
    503		intassign1 &= ~(INTASSIGN_MASK << 6);
    504		intassign1 |= (uint16_t)assign << 6;
    505		break;
    506	case 12:
    507		intassign1 &= ~(INTASSIGN_MASK << 9);
    508		intassign1 |= (uint16_t)assign << 9;
    509		break;
    510	default:
    511		raw_spin_unlock_irq(&desc->lock);
    512		return -EINVAL;
    513	}
    514
    515	sysint1_assign[pin] = assign;
    516	icu1_write(INTASSIGN0, intassign0);
    517	icu1_write(INTASSIGN1, intassign1);
    518
    519	raw_spin_unlock_irq(&desc->lock);
    520
    521	return 0;
    522}
    523
    524static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
    525{
    526	struct irq_desc *desc = irq_to_desc(irq);
    527	uint16_t intassign2, intassign3;
    528	unsigned int pin;
    529
    530	pin = SYSINT2_IRQ_TO_PIN(irq);
    531
    532	raw_spin_lock_irq(&desc->lock);
    533
    534	intassign2 = icu1_read(INTASSIGN2);
    535	intassign3 = icu1_read(INTASSIGN3);
    536
    537	switch (pin) {
    538	case 0:
    539		intassign2 &= ~INTASSIGN_MASK;
    540		intassign2 |= (uint16_t)assign;
    541		break;
    542	case 1:
    543		intassign2 &= ~(INTASSIGN_MASK << 3);
    544		intassign2 |= (uint16_t)assign << 3;
    545		break;
    546	case 3:
    547		intassign2 &= ~(INTASSIGN_MASK << 6);
    548		intassign2 |= (uint16_t)assign << 6;
    549		break;
    550	case 4:
    551		intassign2 &= ~(INTASSIGN_MASK << 9);
    552		intassign2 |= (uint16_t)assign << 9;
    553		break;
    554	case 5:
    555		intassign2 &= ~(INTASSIGN_MASK << 12);
    556		intassign2 |= (uint16_t)assign << 12;
    557		break;
    558	case 6:
    559		intassign3 &= ~INTASSIGN_MASK;
    560		intassign3 |= (uint16_t)assign;
    561		break;
    562	case 7:
    563		intassign3 &= ~(INTASSIGN_MASK << 3);
    564		intassign3 |= (uint16_t)assign << 3;
    565		break;
    566	case 8:
    567		intassign3 &= ~(INTASSIGN_MASK << 6);
    568		intassign3 |= (uint16_t)assign << 6;
    569		break;
    570	case 9:
    571		intassign3 &= ~(INTASSIGN_MASK << 9);
    572		intassign3 |= (uint16_t)assign << 9;
    573		break;
    574	case 10:
    575		intassign3 &= ~(INTASSIGN_MASK << 12);
    576		intassign3 |= (uint16_t)assign << 12;
    577		break;
    578	default:
    579		raw_spin_unlock_irq(&desc->lock);
    580		return -EINVAL;
    581	}
    582
    583	sysint2_assign[pin] = assign;
    584	icu1_write(INTASSIGN2, intassign2);
    585	icu1_write(INTASSIGN3, intassign3);
    586
    587	raw_spin_unlock_irq(&desc->lock);
    588
    589	return 0;
    590}
    591
    592int vr41xx_set_intassign(unsigned int irq, unsigned char intassign)
    593{
    594	int retval = -EINVAL;
    595
    596	if (current_cpu_type() != CPU_VR4133)
    597		return -EINVAL;
    598
    599	if (intassign > INTASSIGN_MAX)
    600		return -EINVAL;
    601
    602	if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST)
    603		retval = set_sysint1_assign(irq, intassign);
    604	else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST)
    605		retval = set_sysint2_assign(irq, intassign);
    606
    607	return retval;
    608}
    609
    610EXPORT_SYMBOL(vr41xx_set_intassign);
    611
    612static int icu_get_irq(unsigned int irq)
    613{
    614	uint16_t pend1, pend2;
    615	uint16_t mask1, mask2;
    616	int i;
    617
    618	pend1 = icu1_read(SYSINT1REG);
    619	mask1 = icu1_read(MSYSINT1REG);
    620
    621	pend2 = icu2_read(SYSINT2REG);
    622	mask2 = icu2_read(MSYSINT2REG);
    623
    624	mask1 &= pend1;
    625	mask2 &= pend2;
    626
    627	if (mask1) {
    628		for (i = 0; i < 16; i++) {
    629			if (irq == INT_TO_IRQ(sysint1_assign[i]) && (mask1 & (1 << i)))
    630				return SYSINT1_IRQ(i);
    631		}
    632	}
    633
    634	if (mask2) {
    635		for (i = 0; i < 16; i++) {
    636			if (irq == INT_TO_IRQ(sysint2_assign[i]) && (mask2 & (1 << i)))
    637				return SYSINT2_IRQ(i);
    638		}
    639	}
    640
    641	printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);
    642
    643	return -1;
    644}
    645
    646static int __init vr41xx_icu_init(void)
    647{
    648	unsigned long icu1_start, icu2_start;
    649	int i;
    650
    651	switch (current_cpu_type()) {
    652	case CPU_VR4111:
    653	case CPU_VR4121:
    654		icu1_start = ICU1_TYPE1_BASE;
    655		icu2_start = ICU2_TYPE1_BASE;
    656		break;
    657	case CPU_VR4122:
    658	case CPU_VR4131:
    659	case CPU_VR4133:
    660		icu1_start = ICU1_TYPE2_BASE;
    661		icu2_start = ICU2_TYPE2_BASE;
    662		break;
    663	default:
    664		printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n");
    665		return -ENODEV;
    666	}
    667
    668	if (request_mem_region(icu1_start, ICU1_SIZE, "ICU") == NULL)
    669		return -EBUSY;
    670
    671	if (request_mem_region(icu2_start, ICU2_SIZE, "ICU") == NULL) {
    672		release_mem_region(icu1_start, ICU1_SIZE);
    673		return -EBUSY;
    674	}
    675
    676	icu1_base = ioremap(icu1_start, ICU1_SIZE);
    677	if (icu1_base == NULL) {
    678		release_mem_region(icu1_start, ICU1_SIZE);
    679		release_mem_region(icu2_start, ICU2_SIZE);
    680		return -ENOMEM;
    681	}
    682
    683	icu2_base = ioremap(icu2_start, ICU2_SIZE);
    684	if (icu2_base == NULL) {
    685		iounmap(icu1_base);
    686		release_mem_region(icu1_start, ICU1_SIZE);
    687		release_mem_region(icu2_start, ICU2_SIZE);
    688		return -ENOMEM;
    689	}
    690
    691	icu1_write(MSYSINT1REG, 0);
    692	icu1_write(MGIUINTLREG, 0xffff);
    693
    694	icu2_write(MSYSINT2REG, 0);
    695	icu2_write(MGIUINTHREG, 0xffff);
    696
    697	for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)
    698		irq_set_chip_and_handler(i, &sysint1_irq_type,
    699					 handle_level_irq);
    700
    701	for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)
    702		irq_set_chip_and_handler(i, &sysint2_irq_type,
    703					 handle_level_irq);
    704
    705	cascade_irq(INT0_IRQ, icu_get_irq);
    706	cascade_irq(INT1_IRQ, icu_get_irq);
    707	cascade_irq(INT2_IRQ, icu_get_irq);
    708	cascade_irq(INT3_IRQ, icu_get_irq);
    709	cascade_irq(INT4_IRQ, icu_get_irq);
    710
    711	return 0;
    712}
    713
    714core_initcall(vr41xx_icu_init);