ints.c 3.6 KB

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