irq.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * arch/v850/kernel/irq.c -- High-level interrupt handling
  3. *
  4. * Copyright (C) 2001,02,03,04,05 NEC Electronics Corporation
  5. * Copyright (C) 2001,02,03,04,05 Miles Bader <miles@gnu.org>
  6. * Copyright (C) 1994-2000 Ralf Baechle
  7. * Copyright (C) 1992 Linus Torvalds
  8. *
  9. * This file is subject to the terms and conditions of the GNU General
  10. * Public License. See the file COPYING in the main directory of this
  11. * archive for more details.
  12. *
  13. * This file was was derived from the mips version, arch/mips/kernel/irq.c
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/irq.h>
  18. #include <linux/init.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/kernel_stat.h>
  21. #include <linux/slab.h>
  22. #include <linux/mm.h>
  23. #include <linux/random.h>
  24. #include <linux/seq_file.h>
  25. #include <asm/system.h>
  26. /*
  27. * 'what should we do if we get a hw irq event on an illegal vector'.
  28. * each architecture has to answer this themselves, it doesn't deserve
  29. * a generic callback i think.
  30. */
  31. void ack_bad_irq(unsigned int irq)
  32. {
  33. printk("received IRQ %d with unknown interrupt type\n", irq);
  34. }
  35. volatile unsigned long irq_err_count, spurious_count;
  36. /*
  37. * Generic, controller-independent functions:
  38. */
  39. int show_interrupts(struct seq_file *p, void *v)
  40. {
  41. int irq = *(loff_t *) v;
  42. if (irq == 0) {
  43. int cpu;
  44. seq_puts(p, " ");
  45. for (cpu=0; cpu < 1 /*smp_num_cpus*/; cpu++)
  46. seq_printf(p, "CPU%d ", cpu);
  47. seq_putc(p, '\n');
  48. }
  49. if (irq < NR_IRQS) {
  50. unsigned long flags;
  51. struct irqaction *action;
  52. spin_lock_irqsave(&irq_desc[irq].lock, flags);
  53. action = irq_desc[irq].action;
  54. if (action) {
  55. int j;
  56. int count = 0;
  57. int num = -1;
  58. const char *type_name = irq_desc[irq].handler->typename;
  59. for (j = 0; j < NR_IRQS; j++)
  60. if (irq_desc[j].handler->typename == type_name){
  61. if (irq == j)
  62. num = count;
  63. count++;
  64. }
  65. seq_printf(p, "%3d: ",irq);
  66. seq_printf(p, "%10u ", kstat_irqs(irq));
  67. if (count > 1) {
  68. int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
  69. seq_printf(p, " %*s%d", 14 - prec,
  70. type_name, num);
  71. } else
  72. seq_printf(p, " %14s", type_name);
  73. seq_printf(p, " %s", action->name);
  74. for (action=action->next; action; action = action->next)
  75. seq_printf(p, ", %s", action->name);
  76. seq_putc(p, '\n');
  77. }
  78. spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
  79. } else if (irq == NR_IRQS)
  80. seq_printf(p, "ERR: %10lu\n", irq_err_count);
  81. return 0;
  82. }
  83. /* Handle interrupt IRQ. REGS are the registers at the time of ther
  84. interrupt. */
  85. unsigned int handle_irq (int irq, struct pt_regs *regs)
  86. {
  87. irq_enter();
  88. __do_IRQ(irq, regs);
  89. irq_exit();
  90. return 1;
  91. }
  92. /* Initialize irq handling for IRQs.
  93. BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
  94. to IRQ_TYPE. An IRQ_TYPE of 0 means to use a generic interrupt type. */
  95. void __init
  96. init_irq_handlers (int base_irq, int num, int interval,
  97. struct hw_interrupt_type *irq_type)
  98. {
  99. while (num-- > 0) {
  100. irq_desc[base_irq].status = IRQ_DISABLED;
  101. irq_desc[base_irq].action = NULL;
  102. irq_desc[base_irq].depth = 1;
  103. irq_desc[base_irq].handler = irq_type;
  104. base_irq += interval;
  105. }
  106. }