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