This source file includes following definitions.
- do_IRQ
- do_fast_IRQ
- irqaction
- request_irq
- free_irq
- math_error_irq
- no_action
- init_IRQ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <linux/ptrace.h>
26 #include <linux/errno.h>
27 #include <linux/signal.h>
28 #include <linux/sched.h>
29
30 #include <asm/system.h>
31 #include <asm/io.h>
32 #include <asm/irq.h>
33
34 void irq13(void);
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 BUILD_IRQ(FIRST,0,0x01)
52 BUILD_IRQ(FIRST,1,0x02)
53 BUILD_IRQ(FIRST,2,0x04)
54 BUILD_IRQ(FIRST,3,0x08)
55 BUILD_IRQ(FIRST,4,0x10)
56 BUILD_IRQ(FIRST,5,0x20)
57 BUILD_IRQ(FIRST,6,0x40)
58 BUILD_IRQ(FIRST,7,0x80)
59 BUILD_IRQ(SECOND,8,0x01)
60 BUILD_IRQ(SECOND,9,0x02)
61 BUILD_IRQ(SECOND,10,0x04)
62 BUILD_IRQ(SECOND,11,0x08)
63 BUILD_IRQ(SECOND,12,0x10)
64 BUILD_IRQ(SECOND,13,0x20)
65 BUILD_IRQ(SECOND,14,0x40)
66 BUILD_IRQ(SECOND,15,0x80)
67
68
69
70
71
72 static void (*interrupt[16])(void) = {
73 IRQ0_interrupt, IRQ1_interrupt, IRQ2_interrupt, IRQ3_interrupt,
74 IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
75 IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
76 IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
77 };
78
79 static void (*fast_interrupt[16])(void) = {
80 fast_IRQ0_interrupt, fast_IRQ1_interrupt,
81 fast_IRQ2_interrupt, fast_IRQ3_interrupt,
82 fast_IRQ4_interrupt, fast_IRQ5_interrupt,
83 fast_IRQ6_interrupt, fast_IRQ7_interrupt,
84 fast_IRQ8_interrupt, fast_IRQ9_interrupt,
85 fast_IRQ10_interrupt, fast_IRQ11_interrupt,
86 fast_IRQ12_interrupt, fast_IRQ13_interrupt,
87 fast_IRQ14_interrupt, fast_IRQ15_interrupt
88 };
89
90 static void (*bad_interrupt[16])(void) = {
91 bad_IRQ0_interrupt, bad_IRQ1_interrupt,
92 bad_IRQ2_interrupt, bad_IRQ3_interrupt,
93 bad_IRQ4_interrupt, bad_IRQ5_interrupt,
94 bad_IRQ6_interrupt, bad_IRQ7_interrupt,
95 bad_IRQ8_interrupt, bad_IRQ9_interrupt,
96 bad_IRQ10_interrupt, bad_IRQ11_interrupt,
97 bad_IRQ12_interrupt, bad_IRQ13_interrupt,
98 bad_IRQ14_interrupt, bad_IRQ15_interrupt
99 };
100
101
102
103
104 static struct sigaction irq_sigaction[16] = {
105 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
106 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
107 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
108 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
109 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
110 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
111 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
112 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
113 };
114
115
116
117
118
119
120
121
122 int do_IRQ(int irq, struct pt_regs * regs)
123 {
124 struct sigaction * sa = irq + irq_sigaction;
125
126 sa->sa_handler((int) regs);
127 return 0;
128 }
129
130
131
132
133
134
135 int do_fast_IRQ(int irq)
136 {
137 struct sigaction * sa = irq + irq_sigaction;
138
139 sa->sa_handler(irq);
140 return 0;
141 }
142
143 int irqaction(unsigned int irq, struct sigaction * new)
144 {
145 struct sigaction * sa;
146 unsigned long flags;
147
148 if (irq > 15)
149 return -EINVAL;
150 sa = irq + irq_sigaction;
151 if (sa->sa_mask)
152 return -EBUSY;
153 if (!new->sa_handler)
154 return -EINVAL;
155 save_flags(flags);
156 cli();
157 *sa = *new;
158 sa->sa_mask = 1;
159 if (sa->sa_flags & SA_INTERRUPT)
160 set_intr_gate(0x20+irq,fast_interrupt[irq]);
161 else
162 set_intr_gate(0x20+irq,interrupt[irq]);
163 if (irq < 8)
164 outb(inb_p(0x21) & ~(1<<irq),0x21);
165 else {
166 outb(inb_p(0x21) & ~(1<<2),0x21);
167 outb(inb_p(0xA1) & ~(1<<(irq-8)),0xA1);
168 }
169 restore_flags(flags);
170 return 0;
171 }
172
173 int request_irq(unsigned int irq, void (*handler)(int))
174 {
175 struct sigaction sa;
176
177 sa.sa_handler = handler;
178 sa.sa_flags = 0;
179 sa.sa_mask = 0;
180 sa.sa_restorer = NULL;
181 return irqaction(irq,&sa);
182 }
183
184 void free_irq(unsigned int irq)
185 {
186 struct sigaction * sa = irq + irq_sigaction;
187 unsigned long flags;
188
189 if (irq > 15) {
190 printk("Trying to free IRQ%d\n",irq);
191 return;
192 }
193 if (!sa->sa_mask) {
194 printk("Trying to free free IRQ%d\n",irq);
195 return;
196 }
197 save_flags(flags);
198 cli();
199 if (irq < 8)
200 outb(inb_p(0x21) | (1<<irq),0x21);
201 else
202 outb(inb_p(0xA1) | (1<<(irq-8)),0xA1);
203 set_intr_gate(0x20+irq,bad_interrupt[irq]);
204 sa->sa_handler = NULL;
205 sa->sa_flags = 0;
206 sa->sa_mask = 0;
207 sa->sa_restorer = NULL;
208 restore_flags(flags);
209 }
210
211 extern void do_coprocessor_error(long,long);
212
213 static void math_error_irq(int cpl)
214 {
215 outb(0,0xF0);
216 do_coprocessor_error(0,0);
217 }
218
219 static void no_action(int cpl) { }
220
221 static struct sigaction ignore_IRQ = {
222 no_action,
223 0,
224 SA_INTERRUPT,
225 NULL
226 };
227
228 void init_IRQ(void)
229 {
230 int i;
231
232 for (i = 0; i < 16 ; i++)
233 set_intr_gate(0x20+i,bad_interrupt[i]);
234 if (irqaction(2,&ignore_IRQ))
235 printk("Unable to get IRQ2 for cascade\n");
236 if (request_irq(13,math_error_irq))
237 printk("Unable to get IRQ13 for math-error handler\n");
238 }