root/arch/alpha/kernel/irq.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mask_irq
  2. unmask_irq
  3. disable_irq
  4. enable_irq
  5. get_irq_list
  6. ack_irq
  7. request_irq
  8. free_irq
  9. handle_nmi
  10. unexpected_irq
  11. handle_irq
  12. device_interrupt
  13. isa_device_interrupt
  14. cabriolet_and_eb66p_device_interrupt
  15. eb66_and_eb64p_device_interrupt
  16. srm_device_interrupt
  17. probe_irq_on
  18. probe_irq_off
  19. machine_check
  20. do_entInt
  21. init_IRQ

   1 /*
   2  *      linux/arch/alpha/kernel/irq.c
   3  *
   4  *      Copyright (C) 1995 Linus Torvalds
   5  *
   6  * This file contains the code used by various IRQ handling routines:
   7  * asking for different IRQ's should be done through these routines
   8  * instead of just grabbing them. Thus setups with different IRQ numbers
   9  * shouldn't result in any weird surprises, and installing new handlers
  10  * should be easier.
  11  */
  12 
  13 #include <linux/config.h>
  14 #include <linux/ptrace.h>
  15 #include <linux/errno.h>
  16 #include <linux/kernel_stat.h>
  17 #include <linux/signal.h>
  18 #include <linux/sched.h>
  19 #include <linux/interrupt.h>
  20 #include <linux/malloc.h>
  21 #include <linux/random.h>
  22 
  23 #include <asm/system.h>
  24 #include <asm/io.h>
  25 #include <asm/irq.h>
  26 #include <asm/bitops.h>
  27 #include <asm/dma.h>
  28 
  29 extern void timer_interrupt(struct pt_regs * regs);
  30 
  31 static unsigned char cache_21 = 0xff;
  32 static unsigned char cache_A1 = 0xff;
  33 
  34 #if NR_IRQS == 33
  35   static unsigned int  cache_804 = 0x00ffffef;
  36 #elif NR_IRQS == 32
  37   static unsigned char cache_26 = 0xdf;
  38   static unsigned char cache_27 = 0xff;
  39 #endif
  40 
  41 static void mask_irq(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
  42 {
  43         unsigned long mask;
  44 
  45         if (irq < 16) {
  46                 mask = 1 << (irq & 7);
  47                 if (irq < 8) {
  48                         cache_21 |= mask;
  49                         outb(cache_21, 0x21);
  50                 } else {
  51                         cache_A1 |= mask;
  52                         outb(cache_A1, 0xA1);
  53                 }
  54 #if NR_IRQS == 33
  55         } else {
  56                 mask = 1 << (irq - 16);
  57                 cache_804 |= mask;
  58                 outl(cache_804, 0x804);
  59 #elif NR_IRQS == 32
  60         } else {
  61                 mask = 1 << (irq & 7);
  62                 if (irq < 24) {
  63                         cache_26 |= mask;
  64                         outb(cache_26, 0x26);
  65                 } else {
  66                         cache_27 |= mask;
  67                         outb(cache_27, 0x27);
  68                 }
  69 #endif
  70         }
  71 }
  72 
  73 static void unmask_irq(unsigned long irq)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         unsigned long mask;
  76 
  77         if (irq < 16) {
  78                 mask = ~(1 << (irq & 7));
  79                 if (irq < 8) {
  80                         cache_21 &= mask;
  81                         outb(cache_21, 0x21);
  82                 } else {
  83                         cache_A1 &= mask;
  84                         outb(cache_A1, 0xA1);
  85                 }
  86 #if NR_IRQS == 33
  87         } else {
  88                 mask = ~(1 << (irq - 16));
  89                 cache_804 &= mask;
  90                 outl(cache_804, 0x804);
  91 #elif NR_IRQS == 32
  92         } else {
  93                 mask = ~(1 << (irq & 7));
  94 
  95                 if (irq < 24) {
  96                         cache_26 &= mask;
  97                         outb(cache_26, 0x26);
  98                 } else {
  99                         cache_27 &= mask;
 100                         outb(cache_27, 0x27);
 101                 }
 102 #endif
 103         }
 104 }
 105 
 106 void disable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108         unsigned long flags;
 109 
 110         save_flags(flags);
 111         cli();
 112         mask_irq(irq_nr);
 113         restore_flags(flags);
 114 }
 115 
 116 void enable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118         unsigned long flags, mask;
 119 
 120         mask = ~(1 << (irq_nr & 7));
 121         save_flags(flags);
 122         cli();
 123         unmask_irq(irq_nr);
 124         restore_flags(flags);
 125 }
 126 
 127 /*
 128  * Initial irq handlers.
 129  */
 130 static struct irqaction *irq_action[NR_IRQS];
 131 
 132 int get_irq_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134         int i, len = 0;
 135         struct irqaction * action;
 136 
 137         for (i = 0 ; i < NR_IRQS ; i++) {
 138                 action = irq_action[i];
 139                 if (!action) 
 140                         continue;
 141                 len += sprintf(buf+len, "%2d: %8d %c %s",
 142                         i, kstat.interrupts[i],
 143                         (action->flags & SA_INTERRUPT) ? '+' : ' ',
 144                         action->name);
 145                 for (action=action->next; action; action = action->next) {
 146                         len += sprintf(buf+len, ",%s %s",
 147                                 (action->flags & SA_INTERRUPT) ? " +" : "",
 148                                 action->name);
 149                 }
 150                 len += sprintf(buf+len, "\n");
 151         }
 152         return len;
 153 }
 154 
 155 static inline void ack_irq(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         if (irq < 16) {
 158                 /* ACK the interrupt making it the lowest priority */
 159                 /*  First the slave .. */
 160                 if (irq > 7) {
 161                         outb(0xE0 | (irq - 8), 0xa0);
 162                         irq = 2;
 163                 }
 164                 /* .. then the master */
 165                 outb(0xE0 | irq, 0x20);
 166         }
 167 }
 168 
 169 int request_irq(unsigned int irq, 
     /* [previous][next][first][last][top][bottom][index][help] */
 170                 void (*handler)(int, void *, struct pt_regs *),
 171                 unsigned long irqflags, 
 172                 const char * devname,
 173                 void *dev_id)
 174 {
 175         struct irqaction *action, *tmp = NULL;
 176         unsigned long flags;
 177 
 178         if (irq >= NR_IRQS)
 179                 return -EINVAL;
 180         /* don't accept requests for irq #0 */
 181         if (!irq)
 182                 return -EINVAL;
 183         if (!handler)
 184             return -EINVAL;
 185         action = irq_action[irq];
 186         if (action) {
 187             if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
 188                 for (tmp = action; tmp->next; tmp = tmp->next);
 189             } else {
 190                 return -EBUSY;
 191             }
 192             if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
 193               printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
 194               return -EBUSY;
 195             }   
 196         }
 197         save_flags(flags);
 198         cli();
 199         action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
 200         if (!action) { 
 201             restore_flags(flags);
 202             return -ENOMEM;
 203         }
 204         
 205         action->handler = handler;
 206         action->flags = irqflags;
 207         action->mask = 0;
 208         action->name = devname;
 209         action->next = NULL;
 210         action->dev_id = dev_id;
 211 
 212         if (tmp) {
 213             tmp->next = action;
 214         } else {
 215             irq_action[irq] = action;
 216             enable_irq(irq);
 217             if (irq >= 8 && irq < 16) {
 218                 enable_irq(2);  /* ensure cascade is enabled too */
 219             }
 220         }
 221 
 222         restore_flags(flags);
 223         return 0;
 224 }
 225 
 226 void free_irq(unsigned int irq, void *dev_id)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228         struct irqaction * action = irq_action[irq];
 229         struct irqaction * tmp = NULL;
 230         unsigned long flags;
 231 
 232         if (irq >= NR_IRQS) {
 233                 printk("Trying to free IRQ%d\n", irq);
 234                 return;
 235         }
 236         if (!action || !action->handler) {
 237                 printk("Trying to free free IRQ%d\n", irq);
 238                 return;
 239         }
 240         if (dev_id) {
 241             for (; action; action = action->next) {
 242                 if (action->dev_id == dev_id) break;
 243                 tmp = action;
 244             }
 245             if (!action) {
 246                 printk("Trying to free free shared IRQ%d\n",irq);
 247                 return;
 248             }
 249         } else if (action->flags & SA_SHIRQ) {
 250             printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
 251             return;
 252         }
 253         save_flags(flags);
 254         cli();
 255         if (action && tmp) {
 256             tmp->next = action->next;
 257         } else {
 258             irq_action[irq] = action->next;
 259         }
 260         kfree_s(action, sizeof(struct irqaction));
 261 
 262         if (!irq_action[irq]) {
 263             mask_irq(irq);
 264         }
 265 
 266         restore_flags(flags);
 267 }
 268 
 269 static inline void handle_nmi(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 270 {
 271         printk("Whee.. NMI received. Probable hardware error\n");
 272         printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
 273 }
 274 
 275 static void unexpected_irq(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         struct irqaction *action;
 278         int i;
 279 
 280         printk("IO device interrupt, irq = %d\n", irq);
 281         printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
 282         printk("Expecting: ");
 283         for (i = 0; i < 16; i++)
 284                 if ((action = irq_action[i]))
 285                         while (action->handler) {
 286                                 printk("[%s:%d] ", action->name, i);
 287                                 action = action->next;
 288                         }
 289         printk("\n");
 290 #if defined(CONFIG_ALPHA_JENSEN)
 291         printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
 292                 inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
 293         outb(0x0c, 0x3fc);
 294         outb(0x0c, 0x2fc);
 295         outb(0,0x61);
 296         outb(0,0x461);
 297 #endif
 298 }
 299 
 300 static inline void handle_irq(int irq, void *dev_id, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 301 {
 302         struct irqaction * action = irq_action[irq];
 303 
 304         kstat.interrupts[irq]++;
 305         if (!action) {
 306             unexpected_irq(irq, regs);
 307             return;
 308         }
 309         do {
 310             action->handler(irq, action->dev_id, regs);
 311             action = action->next;
 312         } while (action);
 313 }
 314 
 315 static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 316 {
 317         struct irqaction * action;
 318 
 319         if ((unsigned) irq > NR_IRQS) {
 320                 printk("device_interrupt: unexpected interrupt %d\n", irq);
 321                 return;
 322         }
 323 
 324         kstat.interrupts[irq]++;
 325         action = irq_action[irq];
 326         if (action) {
 327                 /* quick interrupts get executed with no extra overhead */
 328                 if (action->flags & SA_INTERRUPT) {
 329                         while (action) {
 330                                 action->handler(irq, action->dev_id, regs);
 331                                 action = action->next;
 332                         }
 333                         ack_irq(ack);
 334                         return;
 335                 }
 336         }
 337         /*
 338          * For normal interrupts, we mask it out, and then ACK it.
 339          * This way another (more timing-critical) interrupt can
 340          * come through while we're doing this one.
 341          *
 342          * Note! A irq without a handler gets masked and acked, but
 343          * never unmasked. The autoirq stuff depends on this (it looks
 344          * at the masks before and after doing the probing).
 345          */
 346         mask_irq(ack);
 347         ack_irq(ack);
 348         if (!action)
 349                 return;
 350         if (action->flags & SA_SAMPLE_RANDOM)
 351                 add_interrupt_randomness(irq);
 352         while (action) {
 353                 action->handler(irq, action->dev_id, regs);
 354                 action = action->next;
 355         }
 356         unmask_irq(ack);
 357 }
 358 
 359 /*
 360  * Handle ISA interrupt via the PICs.
 361  */
 362 static inline void isa_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 363                                         struct pt_regs * regs)
 364 {
 365 #if defined(CONFIG_ALPHA_APECS)
 366 #       define IACK_SC  APECS_IACK_SC
 367 #elif defined(CONFIG_ALPHA_LCA)
 368 #       define IACK_SC  LCA_IACK_SC
 369 #elif defined(CONFIG_ALPHA_ALCOR)
 370 #       define IACK_SC  ALCOR_IACK_SC
 371 #else
 372         /*
 373          * This is bogus but necessary to get it to compile
 374          * on all platforms.  If you try to use this on any
 375          * other than the intended platforms, you'll notice
 376          * real fast...
 377          */
 378 #       define IACK_SC  1L
 379 #endif
 380         int j;
 381 
 382 #if 1
 383         /*
 384          * Generate a PCI interrupt acknowledge cycle.  The PIC will
 385          * respond with the interrupt vector of the highest priority
 386          * interrupt that is pending.  The PALcode sets up the
 387          * interrupts vectors such that irq level L generates vector
 388          * L.
 389          */
 390         j = *(volatile int *) IACK_SC;
 391         j &= 0xff;
 392         if (j == 7) {
 393             if (!(inb(0x20) & 0x80)) {
 394                 /* it's only a passive release... */
 395                 return;
 396             }
 397         }
 398         device_interrupt(j, j, regs);
 399 #else
 400         unsigned long pic;
 401 
 402         /*
 403          * It seems to me that the probability of two or more *device*
 404          * interrupts occuring at almost exactly the same time is
 405          * pretty low.  So why pay the price of checking for
 406          * additional interrupts here if the common case can be
 407          * handled so much easier?
 408          */
 409         /* 
 410          *  The first read of gives you *all* interrupting lines.
 411          *  Therefore, read the mask register and and out those lines
 412          *  not enabled.  Note that some documentation has 21 and a1 
 413          *  write only.  This is not true.
 414          */
 415         pic = inb(0x20) | (inb(0xA0) << 8);     /* read isr */
 416         pic &= ~((cache_A1 << 8) | cache_21);   /* apply mask */
 417         pic &= 0xFFFB;                          /* mask out cascade */
 418 
 419         while (pic) {
 420                 j = ffz(~pic);
 421                 pic &= pic - 1;
 422                 device_interrupt(j, j, regs);
 423         }
 424 #endif
 425 }
 426 
 427 static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 428                                                         struct pt_regs * regs)
 429 {
 430         unsigned long pld;
 431         unsigned int i;
 432         unsigned long flags;
 433 
 434         save_flags(flags);
 435         cli();
 436 
 437         /* read the interrupt summary registers */
 438         pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
 439 
 440 #if 0
 441         printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8));
 442 #endif
 443 
 444         /*
 445          * Now for every possible bit set, work through them and call
 446          * the appropriate interrupt handler.
 447          */
 448         while (pld) {
 449                 i = ffz(~pld);
 450                 pld &= pld - 1; /* clear least bit set */
 451                 if (i == 4) {
 452                         isa_device_interrupt(vector, regs);
 453                 } else {
 454                         device_interrupt(16 + i, 16 + i, regs);
 455                 }
 456         }
 457         restore_flags(flags);
 458 }
 459 
 460 static inline void eb66_and_eb64p_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 461                                                    struct pt_regs * regs)
 462 {
 463         unsigned long pld;
 464         unsigned int i;
 465         unsigned long flags;
 466 
 467         save_flags(flags);
 468         cli();
 469 
 470         /* read the interrupt summary registers */
 471         pld = inb(0x26) | (inb(0x27) << 8);
 472         /*
 473          * Now, for every possible bit set, work through
 474          * them and call the appropriate interrupt handler.
 475          */
 476         while (pld) {
 477                 i = ffz(~pld);
 478                 pld &= pld - 1; /* clear least bit set */
 479 
 480                 if (i == 5) {
 481                         isa_device_interrupt(vector, regs);
 482                 } else {
 483                         device_interrupt(16 + i, 16 + i, regs);
 484                 }
 485         }
 486         restore_flags(flags);
 487 }
 488 
 489 /*
 490  * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
 491  * 0x9X0 for the local motherboard interrupts..
 492  *
 493  *      0x660 - NMI
 494  *
 495  *      0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
 496  *      0x810 - IRQ1  line printer (duh..)
 497  *      0x860 - IRQ6  floppy disk
 498  *      0x8E0 - IRQ14 SCSI controller
 499  *
 500  *      0x900 - COM1
 501  *      0x920 - COM2
 502  *      0x980 - keyboard
 503  *      0x990 - mouse
 504  *
 505  * PCI-based systems are more sane: they don't have the local
 506  * interrupts at all, and have only normal PCI interrupts from
 507  * devices.  Happily it's easy enough to do a sane mapping from the
 508  * Jensen..  Note that this means that we may have to do a hardware
 509  * "ack" to a different interrupt than we report to the rest of the
 510  * world.
 511  */
 512 static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 513 {
 514         int irq, ack;
 515         unsigned long flags;
 516 
 517         save_flags(flags);
 518         cli();
 519 
 520 
 521         ack = irq = (vector - 0x800) >> 4;
 522 
 523 #ifdef CONFIG_ALPHA_JENSEN
 524         switch (vector) {
 525               case 0x660: handle_nmi(regs); return;
 526                 /* local device interrupts: */
 527               case 0x900: handle_irq(4, regs); return;  /* com1 -> irq 4 */
 528               case 0x920: handle_irq(3, regs); return;  /* com2 -> irq 3 */
 529               case 0x980: handle_irq(1, regs); return;  /* kbd -> irq 1 */
 530               case 0x990: handle_irq(9, regs); return;  /* mouse -> irq 9 */
 531               default:
 532                 if (vector > 0x900) {
 533                         printk("Unknown local interrupt %lx\n", vector);
 534                 }
 535         }
 536         /* irq1 is supposed to be the keyboard, silly Jensen (is this really needed??) */
 537         if (irq == 1)
 538                 irq = 7;
 539 #endif /* CONFIG_ALPHA_JENSEN */
 540 
 541         device_interrupt(irq, ack, regs);
 542 
 543         restore_flags(flags) ;
 544 }
 545 
 546 #if NR_IRQS > 64
 547 #  error Number of irqs limited to 64 due to interrupt-probing.
 548 #endif
 549 
 550 /*
 551  * Start listening for interrupts..
 552  */
 553 unsigned long probe_irq_on(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 554 {
 555         struct irqaction * action;
 556         unsigned long irqs = 0, irqmask;
 557         unsigned long delay;
 558         unsigned int i;
 559 
 560         for (i = NR_IRQS - 1; i > 0; i--) {
 561                 action = irq_action[i];
 562                 if (!action) {
 563                         enable_irq(i);
 564                         irqs |= (1 << i);
 565                 }
 566         }
 567 
 568         /* wait for spurious interrupts to mask themselves out again */
 569         for (delay = jiffies + HZ/10; delay > jiffies; )
 570                 /* about 100 ms delay */;
 571         
 572         /* now filter out any obviously spurious interrupts */
 573         irqmask = (((unsigned long)cache_A1)<<8) | (unsigned long) cache_21;
 574 #if NR_IRQS == 33
 575         irqmask |= (unsigned long) cache_804 << 16;
 576 #elif NR_IRQS == 32
 577         irqmask |= ((((unsigned long)cache_26)<<16) |
 578                     (((unsigned long)cache_27)<<24));
 579 #endif
 580         irqs &= ~irqmask;
 581         return irqs;
 582 }
 583 
 584 /*
 585  * Get the result of the IRQ probe.. A negative result means that
 586  * we have several candidates (but we return the lowest-numbered
 587  * one).
 588  */
 589 int probe_irq_off(unsigned long irqs)
     /* [previous][next][first][last][top][bottom][index][help] */
 590 {
 591         unsigned long irqmask;
 592         int i;
 593         
 594         irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
 595 #if NR_IRQS == 33
 596         irqmask |= (unsigned long) cache_804 << 16;
 597 #elif NR_IRQS == 32
 598         irqmask |= ((((unsigned long)cache_26)<<16) |
 599                     (((unsigned long)cache_27)<<24));
 600 #endif
 601         irqs &= irqmask & ~1;   /* always mask out irq 0---it's the unused timer */
 602 #ifdef CONFIG_ALPHA_P2K
 603         irqs &= ~(1 << 8);      /* mask out irq 8 since that's the unused RTC input to PIC */
 604 #endif
 605         if (!irqs)
 606                 return 0;
 607         i = ffz(~irqs);
 608         if (irqs != (1UL << i))
 609                 i = -i;
 610         return i;
 611 }
 612 
 613 static void machine_check(unsigned long vector, unsigned long la, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 614 {
 615 #if defined(CONFIG_ALPHA_LCA)
 616         extern void lca_machine_check (unsigned long vector, unsigned long la,
 617                                        struct pt_regs *regs);
 618         lca_machine_check(vector, la, regs);
 619 #elif defined(CONFIG_ALPHA_APECS)
 620         extern void apecs_machine_check(unsigned long vector, unsigned long la,
 621                                         struct pt_regs * regs);
 622         apecs_machine_check(vector, la, regs);
 623 #elif defined(CONFIG_ALPHA_ALCOR)
 624         extern void alcor_machine_check(unsigned long vector, unsigned long la,
 625                                         struct pt_regs * regs);
 626         alcor_machine_check(vector, la, regs);
 627 #else
 628         printk("Machine check\n");
 629 #endif
 630 }
 631 
 632 asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
     /* [previous][next][first][last][top][bottom][index][help] */
 633         unsigned long a3, unsigned long a4, unsigned long a5,
 634         struct pt_regs regs)
 635 {
 636         switch (type) {
 637                 case 0:
 638                         printk("Interprocessor interrupt? You must be kidding\n");
 639                         break;
 640                 case 1:
 641                         timer_interrupt(&regs);
 642                         return;
 643                 case 2:
 644                         machine_check(vector, la_ptr, &regs);
 645                         return;
 646                 case 3:
 647 #if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_ALPHA_NONAME) || \
 648     defined(CONFIG_ALPHA_P2K) || defined(CONFIG_ALPHA_SRM)
 649                         srm_device_interrupt(vector, &regs);
 650 #elif NR_IRQS == 33
 651                         cabriolet_and_eb66p_device_interrupt(vector, &regs);
 652 #elif NR_IRQS == 32
 653                         eb66_and_eb64p_device_interrupt(vector, &regs);
 654 #elif NR_IRQS == 16
 655                         isa_device_interrupt(vector, &regs);
 656 #endif
 657                         return;
 658                 case 4:
 659                         printk("Performance counter interrupt\n");
 660                         break;;
 661                 default:
 662                         printk("Hardware intr %ld %lx? Huh?\n", type, vector);
 663         }
 664         printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps);
 665 }
 666 
 667 extern asmlinkage void entInt(void);
 668 
 669 void init_IRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 670 {
 671         wrent(entInt, 0);
 672         dma_outb(0, DMA1_RESET_REG);
 673         dma_outb(0, DMA2_RESET_REG);
 674         dma_outb(0, DMA1_CLR_MASK_REG);
 675         dma_outb(0, DMA2_CLR_MASK_REG);
 676 #if NR_IRQS == 33
 677         outl(cache_804, 0x804);
 678 #elif NR_IRQS == 32
 679         outb(cache_26, 0x26);
 680         outb(cache_27, 0x27);
 681 #endif
 682 }

/* [previous][next][first][last][top][bottom][index][help] */