ints.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * ints.c - Generic interrupt controller support
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file COPYING in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright 1996 Roman Zippel
  9. * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
  10. */
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/irq.h>
  16. #include <asm/traps.h>
  17. #include <asm/io.h>
  18. #include <asm/machdep.h>
  19. #if defined(CONFIG_M68328)
  20. #include <asm/MC68328.h>
  21. #elif defined(CONFIG_M68EZ328)
  22. #include <asm/MC68EZ328.h>
  23. #elif defined(CONFIG_M68VZ328)
  24. #include <asm/MC68VZ328.h>
  25. #endif
  26. /* assembler routines */
  27. asmlinkage void system_call(void);
  28. asmlinkage void buserr(void);
  29. asmlinkage void trap(void);
  30. asmlinkage void trap3(void);
  31. asmlinkage void trap4(void);
  32. asmlinkage void trap5(void);
  33. asmlinkage void trap6(void);
  34. asmlinkage void trap7(void);
  35. asmlinkage void trap8(void);
  36. asmlinkage void trap9(void);
  37. asmlinkage void trap10(void);
  38. asmlinkage void trap11(void);
  39. asmlinkage void trap12(void);
  40. asmlinkage void trap13(void);
  41. asmlinkage void trap14(void);
  42. asmlinkage void trap15(void);
  43. asmlinkage void trap33(void);
  44. asmlinkage void trap34(void);
  45. asmlinkage void trap35(void);
  46. asmlinkage void trap36(void);
  47. asmlinkage void trap37(void);
  48. asmlinkage void trap38(void);
  49. asmlinkage void trap39(void);
  50. asmlinkage void trap40(void);
  51. asmlinkage void trap41(void);
  52. asmlinkage void trap42(void);
  53. asmlinkage void trap43(void);
  54. asmlinkage void trap44(void);
  55. asmlinkage void trap45(void);
  56. asmlinkage void trap46(void);
  57. asmlinkage void trap47(void);
  58. asmlinkage irqreturn_t bad_interrupt(int, void *);
  59. asmlinkage irqreturn_t inthandler(void);
  60. asmlinkage irqreturn_t inthandler1(void);
  61. asmlinkage irqreturn_t inthandler2(void);
  62. asmlinkage irqreturn_t inthandler3(void);
  63. asmlinkage irqreturn_t inthandler4(void);
  64. asmlinkage irqreturn_t inthandler5(void);
  65. asmlinkage irqreturn_t inthandler6(void);
  66. asmlinkage irqreturn_t inthandler7(void);
  67. /* The 68k family did not have a good way to determine the source
  68. * of interrupts until later in the family. The EC000 core does
  69. * not provide the vector number on the stack, we vector everything
  70. * into one vector and look in the blasted mask register...
  71. * This code is designed to be fast, almost constant time, not clean!
  72. */
  73. void process_int(int vec, struct pt_regs *fp)
  74. {
  75. int irq;
  76. int mask;
  77. unsigned long pend = ISR;
  78. while (pend) {
  79. if (pend & 0x0000ffff) {
  80. if (pend & 0x000000ff) {
  81. if (pend & 0x0000000f) {
  82. mask = 0x00000001;
  83. irq = 0;
  84. } else {
  85. mask = 0x00000010;
  86. irq = 4;
  87. }
  88. } else {
  89. if (pend & 0x00000f00) {
  90. mask = 0x00000100;
  91. irq = 8;
  92. } else {
  93. mask = 0x00001000;
  94. irq = 12;
  95. }
  96. }
  97. } else {
  98. if (pend & 0x00ff0000) {
  99. if (pend & 0x000f0000) {
  100. mask = 0x00010000;
  101. irq = 16;
  102. } else {
  103. mask = 0x00100000;
  104. irq = 20;
  105. }
  106. } else {
  107. if (pend & 0x0f000000) {
  108. mask = 0x01000000;
  109. irq = 24;
  110. } else {
  111. mask = 0x10000000;
  112. irq = 28;
  113. }
  114. }
  115. }
  116. while (! (mask & pend)) {
  117. mask <<=1;
  118. irq++;
  119. }
  120. do_IRQ(irq, fp);
  121. pend &= ~mask;
  122. }
  123. }
  124. static void intc_irq_unmask(struct irq_data *d)
  125. {
  126. IMR &= ~(1 << d->irq);
  127. }
  128. static void intc_irq_mask(struct irq_data *d)
  129. {
  130. IMR |= (1 << d->irq);
  131. }
  132. static struct irq_chip intc_irq_chip = {
  133. .name = "M68K-INTC",
  134. .irq_mask = intc_irq_mask,
  135. .irq_unmask = intc_irq_unmask,
  136. };
  137. /*
  138. * This function should be called during kernel startup to initialize
  139. * the machine vector table.
  140. */
  141. void __init trap_init(void)
  142. {
  143. int i;
  144. /* set up the vectors */
  145. for (i = 72; i < 256; ++i)
  146. _ramvec[i] = (e_vector) bad_interrupt;
  147. _ramvec[32] = system_call;
  148. _ramvec[65] = (e_vector) inthandler1;
  149. _ramvec[66] = (e_vector) inthandler2;
  150. _ramvec[67] = (e_vector) inthandler3;
  151. _ramvec[68] = (e_vector) inthandler4;
  152. _ramvec[69] = (e_vector) inthandler5;
  153. _ramvec[70] = (e_vector) inthandler6;
  154. _ramvec[71] = (e_vector) inthandler7;
  155. }
  156. void __init init_IRQ(void)
  157. {
  158. int i;
  159. IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
  160. /* turn off all interrupts */
  161. IMR = ~0;
  162. for (i = 0; (i < NR_IRQS); i++) {
  163. irq_set_chip(i, &intc_irq_chip);
  164. irq_set_handler(i, handle_level_irq);
  165. }
  166. }