ints.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * linux/arch/m68knommu/platform/68328/ints.c
  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. extern e_vector *_ramvec;
  68. /* The number of spurious interrupts */
  69. volatile unsigned int num_spurious;
  70. /*
  71. * This function should be called during kernel startup to initialize
  72. * the machine vector table.
  73. */
  74. void __init init_vectors(void)
  75. {
  76. int i;
  77. /* set up the vectors */
  78. for (i = 72; i < 256; ++i)
  79. _ramvec[i] = (e_vector) bad_interrupt;
  80. _ramvec[32] = system_call;
  81. _ramvec[65] = (e_vector) inthandler1;
  82. _ramvec[66] = (e_vector) inthandler2;
  83. _ramvec[67] = (e_vector) inthandler3;
  84. _ramvec[68] = (e_vector) inthandler4;
  85. _ramvec[69] = (e_vector) inthandler5;
  86. _ramvec[70] = (e_vector) inthandler6;
  87. _ramvec[71] = (e_vector) inthandler7;
  88. IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
  89. /* turn off all interrupts */
  90. IMR = ~0;
  91. }
  92. /* The 68k family did not have a good way to determine the source
  93. * of interrupts until later in the family. The EC000 core does
  94. * not provide the vector number on the stack, we vector everything
  95. * into one vector and look in the blasted mask register...
  96. * This code is designed to be fast, almost constant time, not clean!
  97. */
  98. void process_int(int vec, struct pt_regs *fp)
  99. {
  100. int irq;
  101. int mask;
  102. unsigned long pend = ISR;
  103. while (pend) {
  104. if (pend & 0x0000ffff) {
  105. if (pend & 0x000000ff) {
  106. if (pend & 0x0000000f) {
  107. mask = 0x00000001;
  108. irq = 0;
  109. } else {
  110. mask = 0x00000010;
  111. irq = 4;
  112. }
  113. } else {
  114. if (pend & 0x00000f00) {
  115. mask = 0x00000100;
  116. irq = 8;
  117. } else {
  118. mask = 0x00001000;
  119. irq = 12;
  120. }
  121. }
  122. } else {
  123. if (pend & 0x00ff0000) {
  124. if (pend & 0x000f0000) {
  125. mask = 0x00010000;
  126. irq = 16;
  127. } else {
  128. mask = 0x00100000;
  129. irq = 20;
  130. }
  131. } else {
  132. if (pend & 0x0f000000) {
  133. mask = 0x01000000;
  134. irq = 24;
  135. } else {
  136. mask = 0x10000000;
  137. irq = 28;
  138. }
  139. }
  140. }
  141. while (! (mask & pend)) {
  142. mask <<=1;
  143. irq++;
  144. }
  145. do_IRQ(irq, fp);
  146. pend &= ~mask;
  147. }
  148. }
  149. void enable_vector(unsigned int irq)
  150. {
  151. IMR &= ~(1<<irq);
  152. }
  153. void disable_vector(unsigned int irq)
  154. {
  155. IMR |= (1<<irq);
  156. }
  157. void ack_vector(unsigned int irq)
  158. {
  159. /* Nothing needed */
  160. }