root/arch/mips/vr41xx/common/icu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. icu1_set
  2. icu1_clear
  3. icu2_set
  4. icu2_clear
  5. vr41xx_enable_piuint
  6. vr41xx_disable_piuint
  7. vr41xx_enable_aiuint
  8. vr41xx_disable_aiuint
  9. vr41xx_enable_kiuint
  10. vr41xx_disable_kiuint
  11. vr41xx_enable_macint
  12. vr41xx_disable_macint
  13. vr41xx_enable_dsiuint
  14. vr41xx_disable_dsiuint
  15. vr41xx_enable_firint
  16. vr41xx_disable_firint
  17. vr41xx_enable_pciint
  18. vr41xx_disable_pciint
  19. vr41xx_enable_scuint
  20. vr41xx_disable_scuint
  21. vr41xx_enable_csiint
  22. vr41xx_disable_csiint
  23. vr41xx_enable_bcuint
  24. vr41xx_disable_bcuint
  25. disable_sysint1_irq
  26. enable_sysint1_irq
  27. disable_sysint2_irq
  28. enable_sysint2_irq
  29. set_sysint1_assign
  30. set_sysint2_assign
  31. vr41xx_set_intassign
  32. icu_get_irq
  33. vr41xx_icu_init

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

/* [<][>][^][v][top][bottom][index][help] */