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 12 #include <linux/types.h> 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/interrupt.h> 16 #include <linux/irq.h> 17 #include <asm/traps.h> 18 #include <asm/io.h> 19 #include <asm/machdep.h> 20 21 #if defined(CONFIG_M68328) 22 #include <asm/MC68328.h> 23 #elif defined(CONFIG_M68EZ328) 24 #include <asm/MC68EZ328.h> 25 #elif defined(CONFIG_M68VZ328) 26 #include <asm/MC68VZ328.h> 27 #endif 28 29 /* assembler routines */ 30 asmlinkage void system_call(void); 31 asmlinkage void buserr(void); 32 asmlinkage void trap(void); 33 asmlinkage void trap3(void); 34 asmlinkage void trap4(void); 35 asmlinkage void trap5(void); 36 asmlinkage void trap6(void); 37 asmlinkage void trap7(void); 38 asmlinkage void trap8(void); 39 asmlinkage void trap9(void); 40 asmlinkage void trap10(void); 41 asmlinkage void trap11(void); 42 asmlinkage void trap12(void); 43 asmlinkage void trap13(void); 44 asmlinkage void trap14(void); 45 asmlinkage void trap15(void); 46 asmlinkage void trap33(void); 47 asmlinkage void trap34(void); 48 asmlinkage void trap35(void); 49 asmlinkage void trap36(void); 50 asmlinkage void trap37(void); 51 asmlinkage void trap38(void); 52 asmlinkage void trap39(void); 53 asmlinkage void trap40(void); 54 asmlinkage void trap41(void); 55 asmlinkage void trap42(void); 56 asmlinkage void trap43(void); 57 asmlinkage void trap44(void); 58 asmlinkage void trap45(void); 59 asmlinkage void trap46(void); 60 asmlinkage void trap47(void); 61 asmlinkage irqreturn_t bad_interrupt(int, void *); 62 asmlinkage irqreturn_t inthandler(void); 63 asmlinkage irqreturn_t inthandler1(void); 64 asmlinkage irqreturn_t inthandler2(void); 65 asmlinkage irqreturn_t inthandler3(void); 66 asmlinkage irqreturn_t inthandler4(void); 67 asmlinkage irqreturn_t inthandler5(void); 68 asmlinkage irqreturn_t inthandler6(void); 69 asmlinkage irqreturn_t inthandler7(void); 70 71 extern e_vector *_ramvec; 72 73 /* The number of spurious interrupts */ 74 volatile unsigned int num_spurious; 75 76 /* 77 * This function should be called during kernel startup to initialize 78 * the machine vector table. 79 */ init_vectors(void)80void __init init_vectors(void) 81 { 82 int i; 83 84 /* set up the vectors */ 85 for (i = 72; i < 256; ++i) 86 _ramvec[i] = (e_vector) bad_interrupt; 87 88 _ramvec[32] = system_call; 89 90 _ramvec[65] = (e_vector) inthandler1; 91 _ramvec[66] = (e_vector) inthandler2; 92 _ramvec[67] = (e_vector) inthandler3; 93 _ramvec[68] = (e_vector) inthandler4; 94 _ramvec[69] = (e_vector) inthandler5; 95 _ramvec[70] = (e_vector) inthandler6; 96 _ramvec[71] = (e_vector) inthandler7; 97 98 IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ 99 100 /* turn off all interrupts */ 101 IMR = ~0; 102 } 103 104 /* The 68k family did not have a good way to determine the source 105 * of interrupts until later in the family. The EC000 core does 106 * not provide the vector number on the stack, we vector everything 107 * into one vector and look in the blasted mask register... 108 * This code is designed to be fast, almost constant time, not clean! 109 */ process_int(int vec,struct pt_regs * fp)110void process_int(int vec, struct pt_regs *fp) 111 { 112 int irq; 113 int mask; 114 115 unsigned long pend = ISR; 116 117 while (pend) { 118 if (pend & 0x0000ffff) { 119 if (pend & 0x000000ff) { 120 if (pend & 0x0000000f) { 121 mask = 0x00000001; 122 irq = 0; 123 } else { 124 mask = 0x00000010; 125 irq = 4; 126 } 127 } else { 128 if (pend & 0x00000f00) { 129 mask = 0x00000100; 130 irq = 8; 131 } else { 132 mask = 0x00001000; 133 irq = 12; 134 } 135 } 136 } else { 137 if (pend & 0x00ff0000) { 138 if (pend & 0x000f0000) { 139 mask = 0x00010000; 140 irq = 16; 141 } else { 142 mask = 0x00100000; 143 irq = 20; 144 } 145 } else { 146 if (pend & 0x0f000000) { 147 mask = 0x01000000; 148 irq = 24; 149 } else { 150 mask = 0x10000000; 151 irq = 28; 152 } 153 } 154 } 155 156 while (! (mask & pend)) { 157 mask <<=1; 158 irq++; 159 } 160 161 do_IRQ(irq, fp); 162 pend &= ~mask; 163 } 164 } 165 enable_vector(unsigned int irq)166void enable_vector(unsigned int irq) 167 { 168 IMR &= ~(1<<irq); 169 } 170 disable_vector(unsigned int irq)171void disable_vector(unsigned int irq) 172 { 173 IMR |= (1<<irq); 174 } 175 ack_vector(unsigned int irq)176void ack_vector(unsigned int irq) 177 { 178 /* Nothing needed */ 179 } 180 181