ints.c 4.3 KB

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