Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / arch / mips / vr41xx / common / icu.c
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
31 static void __iomem *icu1_base;
32 static void __iomem *icu2_base;
33
34 static unsigned char sysint1_assign[16] = {
35         0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
36 static 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
98 static 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
109 static 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
120 static 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
131 static 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
142 void 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
155 EXPORT_SYMBOL(vr41xx_enable_piuint);
156
157 void 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
170 EXPORT_SYMBOL(vr41xx_disable_piuint);
171
172 void 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
185 EXPORT_SYMBOL(vr41xx_enable_aiuint);
186
187 void 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
200 EXPORT_SYMBOL(vr41xx_disable_aiuint);
201
202 void 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
215 EXPORT_SYMBOL(vr41xx_enable_kiuint);
216
217 void 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
230 EXPORT_SYMBOL(vr41xx_disable_kiuint);
231
232 void 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
242 EXPORT_SYMBOL(vr41xx_enable_macint);
243
244 void 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
254 EXPORT_SYMBOL(vr41xx_disable_macint);
255
256 void 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
266 EXPORT_SYMBOL(vr41xx_enable_dsiuint);
267
268 void 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
278 EXPORT_SYMBOL(vr41xx_disable_dsiuint);
279
280 void 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
290 EXPORT_SYMBOL(vr41xx_enable_firint);
291
292 void 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
302 EXPORT_SYMBOL(vr41xx_disable_firint);
303
304 void 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
318 EXPORT_SYMBOL(vr41xx_enable_pciint);
319
320 void 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
334 EXPORT_SYMBOL(vr41xx_disable_pciint);
335
336 void 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
350 EXPORT_SYMBOL(vr41xx_enable_scuint);
351
352 void 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
366 EXPORT_SYMBOL(vr41xx_disable_scuint);
367
368 void 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
382 EXPORT_SYMBOL(vr41xx_enable_csiint);
383
384 void 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
398 EXPORT_SYMBOL(vr41xx_disable_csiint);
399
400 void 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
414 EXPORT_SYMBOL(vr41xx_enable_bcuint);
415
416 void 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
430 EXPORT_SYMBOL(vr41xx_disable_bcuint);
431
432 static void disable_sysint1_irq(struct irq_data *d)
433 {
434         icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
435 }
436
437 static void enable_sysint1_irq(struct irq_data *d)
438 {
439         icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
440 }
441
442 static struct irq_chip sysint1_irq_type = {
443         .name           = "SYSINT1",
444         .irq_mask       = disable_sysint1_irq,
445         .irq_unmask     = enable_sysint1_irq,
446 };
447
448 static void disable_sysint2_irq(struct irq_data *d)
449 {
450         icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
451 }
452
453 static void enable_sysint2_irq(struct irq_data *d)
454 {
455         icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
456 }
457
458 static struct irq_chip sysint2_irq_type = {
459         .name           = "SYSINT2",
460         .irq_mask       = disable_sysint2_irq,
461         .irq_unmask     = enable_sysint2_irq,
462 };
463
464 static 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
524 static 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
592 int 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
610 EXPORT_SYMBOL(vr41xx_set_intassign);
611
612 static 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         atomic_inc(&irq_err_count);
644
645         return -1;
646 }
647
648 static int __init vr41xx_icu_init(void)
649 {
650         unsigned long icu1_start, icu2_start;
651         int i;
652
653         switch (current_cpu_type()) {
654         case CPU_VR4111:
655         case CPU_VR4121:
656                 icu1_start = ICU1_TYPE1_BASE;
657                 icu2_start = ICU2_TYPE1_BASE;
658                 break;
659         case CPU_VR4122:
660         case CPU_VR4131:
661         case CPU_VR4133:
662                 icu1_start = ICU1_TYPE2_BASE;
663                 icu2_start = ICU2_TYPE2_BASE;
664                 break;
665         default:
666                 printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n");
667                 return -ENODEV;
668         }
669
670         if (request_mem_region(icu1_start, ICU1_SIZE, "ICU") == NULL)
671                 return -EBUSY;
672
673         if (request_mem_region(icu2_start, ICU2_SIZE, "ICU") == NULL) {
674                 release_mem_region(icu1_start, ICU1_SIZE);
675                 return -EBUSY;
676         }
677
678         icu1_base = ioremap(icu1_start, ICU1_SIZE);
679         if (icu1_base == NULL) {
680                 release_mem_region(icu1_start, ICU1_SIZE);
681                 release_mem_region(icu2_start, ICU2_SIZE);
682                 return -ENOMEM;
683         }
684
685         icu2_base = ioremap(icu2_start, ICU2_SIZE);
686         if (icu2_base == NULL) {
687                 iounmap(icu1_base);
688                 release_mem_region(icu1_start, ICU1_SIZE);
689                 release_mem_region(icu2_start, ICU2_SIZE);
690                 return -ENOMEM;
691         }
692
693         icu1_write(MSYSINT1REG, 0);
694         icu1_write(MGIUINTLREG, 0xffff);
695
696         icu2_write(MSYSINT2REG, 0);
697         icu2_write(MGIUINTHREG, 0xffff);
698
699         for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)
700                 irq_set_chip_and_handler(i, &sysint1_irq_type,
701                                          handle_level_irq);
702
703         for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)
704                 irq_set_chip_and_handler(i, &sysint2_irq_type,
705                                          handle_level_irq);
706
707         cascade_irq(INT0_IRQ, icu_get_irq);
708         cascade_irq(INT1_IRQ, icu_get_irq);
709         cascade_irq(INT2_IRQ, icu_get_irq);
710         cascade_irq(INT3_IRQ, icu_get_irq);
711         cascade_irq(INT4_IRQ, icu_get_irq);
712
713         return 0;
714 }
715
716 core_initcall(vr41xx_icu_init);