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 }
128
129
130
131
132
133
134 int do_fast_IRQ(int irq)
135 {
136 struct sigaction * sa = irq + irq_sigaction;
137
138 sa->sa_handler(irq);
139 }
140
141 int irqaction(unsigned int irq, struct sigaction * new)
142 {
143 struct sigaction * sa;
144 unsigned long flags;
145
146 if (irq > 15)
147 return -EINVAL;
148 sa = irq + irq_sigaction;
149 if (sa->sa_mask)
150 return -EBUSY;
151 if (!new->sa_handler)
152 return -EINVAL;
153 save_flags(flags);
154 cli();
155 *sa = *new;
156 sa->sa_mask = 1;
157 if (sa->sa_flags & SA_INTERRUPT)
158 set_intr_gate(0x20+irq,fast_interrupt[irq]);
159 else
160 set_intr_gate(0x20+irq,interrupt[irq]);
161 if (irq < 8)
162 outb(inb_p(0x21) & ~(1<<irq),0x21);
163 else {
164 outb(inb_p(0x21) & ~(1<<2),0x21);
165 outb(inb_p(0xA1) & ~(1<<(irq-8)),0xA1);
166 }
167 restore_flags(flags);
168 return 0;
169 }
170
171 int request_irq(unsigned int irq, void (*handler)(int))
172 {
173 struct sigaction sa;
174
175 sa.sa_handler = handler;
176 sa.sa_flags = 0;
177 sa.sa_mask = 0;
178 sa.sa_restorer = NULL;
179 return irqaction(irq,&sa);
180 }
181
182 void free_irq(unsigned int irq)
183 {
184 struct sigaction * sa = irq + irq_sigaction;
185 unsigned long flags;
186
187 if (irq > 15) {
188 printk("Trying to free IRQ%d\n",irq);
189 return;
190 }
191 if (!sa->sa_mask) {
192 printk("Trying to free free IRQ%d\n",irq);
193 return;
194 }
195 save_flags(flags);
196 cli();
197 if (irq < 8)
198 outb(inb_p(0x21) | (1<<irq),0x21);
199 else
200 outb(inb_p(0xA1) | (1<<(irq-8)),0xA1);
201 set_intr_gate(0x20+irq,bad_interrupt[irq]);
202 sa->sa_handler = NULL;
203 sa->sa_flags = 0;
204 sa->sa_mask = 0;
205 sa->sa_restorer = NULL;
206 restore_flags(flags);
207 }
208
209 extern void do_coprocessor_error(long,long);
210
211 static void math_error_irq(int cpl)
212 {
213 outb(0,0xF0);
214 do_coprocessor_error(0,0);
215 }
216
217 static void no_action(int cpl) { }
218
219 static struct sigaction ignore_IRQ = {
220 no_action,
221 0,
222 SA_INTERRUPT,
223 NULL
224 };
225
226 void init_IRQ(void)
227 {
228 int i;
229
230 for (i = 0; i < 16 ; i++)
231 set_intr_gate(0x20+i,bad_interrupt[i]);
232 if (irqaction(2,&ignore_IRQ))
233 printk("Unable to get IRQ2 for cascade\n");
234 if (request_irq(13,math_error_irq))
235 printk("Unable to get IRQ13 for math-error handler\n");
236 }