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);