ints.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c
  3. * Needed to drive the m68k emulating IRQ hardware on the PowerUp boards.
  4. */
  5. #include <linux/types.h>
  6. #include <linux/sched.h>
  7. #include <linux/kernel_stat.h>
  8. #include <linux/errno.h>
  9. #include <linux/init.h>
  10. #include <linux/seq_file.h>
  11. #include <asm/setup.h>
  12. #include <asm/system.h>
  13. #include <asm/irq.h>
  14. #include <asm/traps.h>
  15. #include <asm/page.h>
  16. #include <asm/machdep.h>
  17. /* table for system interrupt handlers */
  18. static irq_handler_t irq_list[SYS_IRQS];
  19. static const char *default_names[SYS_IRQS] = {
  20. "spurious int", "int1 handler", "int2 handler", "int3 handler",
  21. "int4 handler", "int5 handler", "int6 handler", "int7 handler"
  22. };
  23. /* The number of spurious interrupts */
  24. volatile unsigned int num_spurious;
  25. #define NUM_IRQ_NODES 100
  26. static irq_node_t nodes[NUM_IRQ_NODES];
  27. /*
  28. * void init_IRQ(void)
  29. *
  30. * Parameters: None
  31. *
  32. * Returns: Nothing
  33. *
  34. * This function should be called during kernel startup to initialize
  35. * the IRQ handling routines.
  36. */
  37. __init
  38. void m68k_init_IRQ(void)
  39. {
  40. int i;
  41. for (i = 0; i < SYS_IRQS; i++) {
  42. if (mach_default_handler)
  43. irq_list[i].handler = (*mach_default_handler)[i];
  44. irq_list[i].flags = 0;
  45. irq_list[i].dev_id = NULL;
  46. irq_list[i].devname = default_names[i];
  47. }
  48. for (i = 0; i < NUM_IRQ_NODES; i++)
  49. nodes[i].handler = NULL;
  50. mach_init_IRQ ();
  51. }
  52. irq_node_t *new_irq_node(void)
  53. {
  54. irq_node_t *node;
  55. short i;
  56. for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
  57. if (!node->handler)
  58. return node;
  59. printk ("new_irq_node: out of nodes\n");
  60. return NULL;
  61. }
  62. int sys_request_irq(unsigned int irq,
  63. void (*handler)(int, void *, struct pt_regs *),
  64. unsigned long flags, const char *devname, void *dev_id)
  65. {
  66. if (irq < IRQ1 || irq > IRQ7) {
  67. printk("%s: Incorrect IRQ %d from %s\n",
  68. __FUNCTION__, irq, devname);
  69. return -ENXIO;
  70. }
  71. #if 0
  72. if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
  73. if (irq_list[irq].flags & IRQ_FLG_LOCK) {
  74. printk("%s: IRQ %d from %s is not replaceable\n",
  75. __FUNCTION__, irq, irq_list[irq].devname);
  76. return -EBUSY;
  77. }
  78. if (!(flags & IRQ_FLG_REPLACE)) {
  79. printk("%s: %s can't replace IRQ %d from %s\n",
  80. __FUNCTION__, devname, irq, irq_list[irq].devname);
  81. return -EBUSY;
  82. }
  83. }
  84. #endif
  85. irq_list[irq].handler = handler;
  86. irq_list[irq].flags = flags;
  87. irq_list[irq].dev_id = dev_id;
  88. irq_list[irq].devname = devname;
  89. return 0;
  90. }
  91. void sys_free_irq(unsigned int irq, void *dev_id)
  92. {
  93. if (irq < IRQ1 || irq > IRQ7) {
  94. printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
  95. return;
  96. }
  97. if (irq_list[irq].dev_id != dev_id)
  98. printk("%s: Removing probably wrong IRQ %d from %s\n",
  99. __FUNCTION__, irq, irq_list[irq].devname);
  100. irq_list[irq].handler = (*mach_default_handler)[irq];
  101. irq_list[irq].flags = 0;
  102. irq_list[irq].dev_id = NULL;
  103. irq_list[irq].devname = default_names[irq];
  104. }
  105. asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
  106. {
  107. if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) {
  108. vec -= VEC_SPUR;
  109. kstat_cpu(0).irqs[vec]++;
  110. irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
  111. } else {
  112. if (mach_process_int)
  113. mach_process_int(vec, fp);
  114. else
  115. panic("Can't process interrupt vector %ld\n", vec);
  116. return;
  117. }
  118. }
  119. int m68k_get_irq_list(struct seq_file *p, void *v)
  120. {
  121. int i;
  122. /* autovector interrupts */
  123. if (mach_default_handler) {
  124. for (i = 0; i < SYS_IRQS; i++) {
  125. seq_printf(p, "auto %2d: %10u ", i,
  126. i ? kstat_cpu(0).irqs[i] : num_spurious);
  127. seq_puts(p, " ");
  128. seq_printf(p, "%s\n", irq_list[i].devname);
  129. }
  130. }
  131. mach_get_irq_list(p, v);
  132. return 0;
  133. }