x86, suspend, acpi: correct and add comments about Big Real Mode
[pandora-kernel.git] / arch / x86 / kernel / i8259_32.c
1 #include <linux/errno.h>
2 #include <linux/signal.h>
3 #include <linux/sched.h>
4 #include <linux/ioport.h>
5 #include <linux/interrupt.h>
6 #include <linux/slab.h>
7 #include <linux/random.h>
8 #include <linux/init.h>
9 #include <linux/kernel_stat.h>
10 #include <linux/sysdev.h>
11 #include <linux/bitops.h>
12
13 #include <asm/atomic.h>
14 #include <asm/system.h>
15 #include <asm/io.h>
16 #include <asm/timer.h>
17 #include <asm/pgtable.h>
18 #include <asm/delay.h>
19 #include <asm/desc.h>
20 #include <asm/apic.h>
21 #include <asm/arch_hooks.h>
22 #include <asm/i8259.h>
23
24 /*
25  * This is the 'legacy' 8259A Programmable Interrupt Controller,
26  * present in the majority of PC/AT boxes.
27  * plus some generic x86 specific things if generic specifics makes
28  * any sense at all.
29  */
30
31 static int i8259A_auto_eoi;
32 DEFINE_SPINLOCK(i8259A_lock);
33 static void mask_and_ack_8259A(unsigned int);
34
35 static struct irq_chip i8259A_chip = {
36         .name           = "XT-PIC",
37         .mask           = disable_8259A_irq,
38         .disable        = disable_8259A_irq,
39         .unmask         = enable_8259A_irq,
40         .mask_ack       = mask_and_ack_8259A,
41 };
42
43 /*
44  * 8259A PIC functions to handle ISA devices:
45  */
46
47 /*
48  * This contains the irq mask for both 8259A irq controllers,
49  */
50 unsigned int cached_irq_mask = 0xffff;
51
52 /*
53  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
54  * boards the timer interrupt is not really connected to any IO-APIC pin,
55  * it's fed to the master 8259A's IR0 line only.
56  *
57  * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
58  * this 'mixed mode' IRQ handling costs nothing because it's only used
59  * at IRQ setup time.
60  */
61 unsigned long io_apic_irqs;
62
63 void disable_8259A_irq(unsigned int irq)
64 {
65         unsigned int mask = 1 << irq;
66         unsigned long flags;
67
68         spin_lock_irqsave(&i8259A_lock, flags);
69         cached_irq_mask |= mask;
70         if (irq & 8)
71                 outb(cached_slave_mask, PIC_SLAVE_IMR);
72         else
73                 outb(cached_master_mask, PIC_MASTER_IMR);
74         spin_unlock_irqrestore(&i8259A_lock, flags);
75 }
76
77 void enable_8259A_irq(unsigned int irq)
78 {
79         unsigned int mask = ~(1 << irq);
80         unsigned long flags;
81
82         spin_lock_irqsave(&i8259A_lock, flags);
83         cached_irq_mask &= mask;
84         if (irq & 8)
85                 outb(cached_slave_mask, PIC_SLAVE_IMR);
86         else
87                 outb(cached_master_mask, PIC_MASTER_IMR);
88         spin_unlock_irqrestore(&i8259A_lock, flags);
89 }
90
91 int i8259A_irq_pending(unsigned int irq)
92 {
93         unsigned int mask = 1<<irq;
94         unsigned long flags;
95         int ret;
96
97         spin_lock_irqsave(&i8259A_lock, flags);
98         if (irq < 8)
99                 ret = inb(PIC_MASTER_CMD) & mask;
100         else
101                 ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
102         spin_unlock_irqrestore(&i8259A_lock, flags);
103
104         return ret;
105 }
106
107 void make_8259A_irq(unsigned int irq)
108 {
109         disable_irq_nosync(irq);
110         io_apic_irqs &= ~(1<<irq);
111         set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
112                                       "XT");
113         enable_irq(irq);
114 }
115
116 /*
117  * This function assumes to be called rarely. Switching between
118  * 8259A registers is slow.
119  * This has to be protected by the irq controller spinlock
120  * before being called.
121  */
122 static inline int i8259A_irq_real(unsigned int irq)
123 {
124         int value;
125         int irqmask = 1<<irq;
126
127         if (irq < 8) {
128                 outb(0x0B,PIC_MASTER_CMD);      /* ISR register */
129                 value = inb(PIC_MASTER_CMD) & irqmask;
130                 outb(0x0A,PIC_MASTER_CMD);      /* back to the IRR register */
131                 return value;
132         }
133         outb(0x0B,PIC_SLAVE_CMD);       /* ISR register */
134         value = inb(PIC_SLAVE_CMD) & (irqmask >> 8);
135         outb(0x0A,PIC_SLAVE_CMD);       /* back to the IRR register */
136         return value;
137 }
138
139 /*
140  * Careful! The 8259A is a fragile beast, it pretty
141  * much _has_ to be done exactly like this (mask it
142  * first, _then_ send the EOI, and the order of EOI
143  * to the two 8259s is important!
144  */
145 static void mask_and_ack_8259A(unsigned int irq)
146 {
147         unsigned int irqmask = 1 << irq;
148         unsigned long flags;
149
150         spin_lock_irqsave(&i8259A_lock, flags);
151         /*
152          * Lightweight spurious IRQ detection. We do not want
153          * to overdo spurious IRQ handling - it's usually a sign
154          * of hardware problems, so we only do the checks we can
155          * do without slowing down good hardware unnecessarily.
156          *
157          * Note that IRQ7 and IRQ15 (the two spurious IRQs
158          * usually resulting from the 8259A-1|2 PICs) occur
159          * even if the IRQ is masked in the 8259A. Thus we
160          * can check spurious 8259A IRQs without doing the
161          * quite slow i8259A_irq_real() call for every IRQ.
162          * This does not cover 100% of spurious interrupts,
163          * but should be enough to warn the user that there
164          * is something bad going on ...
165          */
166         if (cached_irq_mask & irqmask)
167                 goto spurious_8259A_irq;
168         cached_irq_mask |= irqmask;
169
170 handle_real_irq:
171         if (irq & 8) {
172                 inb(PIC_SLAVE_IMR);     /* DUMMY - (do we need this?) */
173                 outb(cached_slave_mask, PIC_SLAVE_IMR);
174                 outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */
175                 outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */
176         } else {
177                 inb(PIC_MASTER_IMR);    /* DUMMY - (do we need this?) */
178                 outb(cached_master_mask, PIC_MASTER_IMR);
179                 outb(0x60+irq,PIC_MASTER_CMD);  /* 'Specific EOI to master */
180         }
181         spin_unlock_irqrestore(&i8259A_lock, flags);
182         return;
183
184 spurious_8259A_irq:
185         /*
186          * this is the slow path - should happen rarely.
187          */
188         if (i8259A_irq_real(irq))
189                 /*
190                  * oops, the IRQ _is_ in service according to the
191                  * 8259A - not spurious, go handle it.
192                  */
193                 goto handle_real_irq;
194
195         {
196                 static int spurious_irq_mask;
197                 /*
198                  * At this point we can be sure the IRQ is spurious,
199                  * lets ACK and report it. [once per IRQ]
200                  */
201                 if (!(spurious_irq_mask & irqmask)) {
202                         printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
203                         spurious_irq_mask |= irqmask;
204                 }
205                 atomic_inc(&irq_err_count);
206                 /*
207                  * Theoretically we do not have to handle this IRQ,
208                  * but in Linux this does not cause problems and is
209                  * simpler for us.
210                  */
211                 goto handle_real_irq;
212         }
213 }
214
215 static char irq_trigger[2];
216 /**
217  * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
218  */
219 static void restore_ELCR(char *trigger)
220 {
221         outb(trigger[0], 0x4d0);
222         outb(trigger[1], 0x4d1);
223 }
224
225 static void save_ELCR(char *trigger)
226 {
227         /* IRQ 0,1,2,8,13 are marked as reserved */
228         trigger[0] = inb(0x4d0) & 0xF8;
229         trigger[1] = inb(0x4d1) & 0xDE;
230 }
231
232 static int i8259A_resume(struct sys_device *dev)
233 {
234         init_8259A(i8259A_auto_eoi);
235         restore_ELCR(irq_trigger);
236         return 0;
237 }
238
239 static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
240 {
241         save_ELCR(irq_trigger);
242         return 0;
243 }
244
245 static int i8259A_shutdown(struct sys_device *dev)
246 {
247         /* Put the i8259A into a quiescent state that
248          * the kernel initialization code can get it
249          * out of.
250          */
251         outb(0xff, PIC_MASTER_IMR);     /* mask all of 8259A-1 */
252         outb(0xff, PIC_SLAVE_IMR);      /* mask all of 8259A-1 */
253         return 0;
254 }
255
256 static struct sysdev_class i8259_sysdev_class = {
257         .name = "i8259",
258         .suspend = i8259A_suspend,
259         .resume = i8259A_resume,
260         .shutdown = i8259A_shutdown,
261 };
262
263 static struct sys_device device_i8259A = {
264         .id     = 0,
265         .cls    = &i8259_sysdev_class,
266 };
267
268 static int __init i8259A_init_sysfs(void)
269 {
270         int error = sysdev_class_register(&i8259_sysdev_class);
271         if (!error)
272                 error = sysdev_register(&device_i8259A);
273         return error;
274 }
275
276 device_initcall(i8259A_init_sysfs);
277
278 void init_8259A(int auto_eoi)
279 {
280         unsigned long flags;
281
282         i8259A_auto_eoi = auto_eoi;
283
284         spin_lock_irqsave(&i8259A_lock, flags);
285
286         outb(0xff, PIC_MASTER_IMR);     /* mask all of 8259A-1 */
287         outb(0xff, PIC_SLAVE_IMR);      /* mask all of 8259A-2 */
288
289         /*
290          * outb_pic - this has to work on a wide range of PC hardware.
291          */
292         outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
293         outb_pic(0x20 + 0, PIC_MASTER_IMR);     /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
294         outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
295         if (auto_eoi)   /* master does Auto EOI */
296                 outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
297         else            /* master expects normal EOI */
298                 outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
299
300         outb_pic(0x11, PIC_SLAVE_CMD);  /* ICW1: select 8259A-2 init */
301         outb_pic(0x20 + 8, PIC_SLAVE_IMR);      /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
302         outb_pic(PIC_CASCADE_IR, PIC_SLAVE_IMR);        /* 8259A-2 is a slave on master's IR2 */
303         outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
304         if (auto_eoi)
305                 /*
306                  * In AEOI mode we just have to mask the interrupt
307                  * when acking.
308                  */
309                 i8259A_chip.mask_ack = disable_8259A_irq;
310         else
311                 i8259A_chip.mask_ack = mask_and_ack_8259A;
312
313         udelay(100);            /* wait for 8259A to initialize */
314
315         outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
316         outb(cached_slave_mask, PIC_SLAVE_IMR);   /* restore slave IRQ mask */
317
318         spin_unlock_irqrestore(&i8259A_lock, flags);
319 }
320
321 /*
322  * Note that on a 486, we don't want to do a SIGFPE on an irq13
323  * as the irq is unreliable, and exception 16 works correctly
324  * (ie as explained in the intel literature). On a 386, you
325  * can't use exception 16 due to bad IBM design, so we have to
326  * rely on the less exact irq13.
327  *
328  * Careful.. Not only is IRQ13 unreliable, but it is also
329  * leads to races. IBM designers who came up with it should
330  * be shot.
331  */
332  
333
334 static irqreturn_t math_error_irq(int cpl, void *dev_id)
335 {
336         extern void math_error(void __user *);
337         outb(0,0xF0);
338         if (ignore_fpu_irq || !boot_cpu_data.hard_math)
339                 return IRQ_NONE;
340         math_error((void __user *)get_irq_regs()->ip);
341         return IRQ_HANDLED;
342 }
343
344 /*
345  * New motherboards sometimes make IRQ 13 be a PCI interrupt,
346  * so allow interrupt sharing.
347  */
348 static struct irqaction fpu_irq = {
349         .handler = math_error_irq,
350         .mask = CPU_MASK_NONE,
351         .name = "fpu",
352 };
353
354 void __init init_ISA_irqs (void)
355 {
356         int i;
357
358 #ifdef CONFIG_X86_LOCAL_APIC
359         init_bsp_APIC();
360 #endif
361         init_8259A(0);
362
363         /*
364          * 16 old-style INTA-cycle interrupts:
365          */
366         for (i = 0; i < 16; i++) {
367                 set_irq_chip_and_handler_name(i, &i8259A_chip,
368                                               handle_level_irq, "XT");
369         }
370 }
371
372 /* Overridden in paravirt.c */
373 void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
374
375 void __init native_init_IRQ(void)
376 {
377         int i;
378
379         /* all the set up before the call gates are initialised */
380         pre_intr_init_hook();
381
382         /*
383          * Cover the whole vector space, no vector can escape
384          * us. (some of these will be overridden and become
385          * 'special' SMP interrupts)
386          */
387         for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
388                 int vector = FIRST_EXTERNAL_VECTOR + i;
389                 if (i >= NR_IRQS)
390                         break;
391                 /* SYSCALL_VECTOR was reserved in trap_init. */
392                 if (!test_bit(vector, used_vectors))
393                         set_intr_gate(vector, interrupt[i]);
394         }
395
396         /* setup after call gates are initialised (usually add in
397          * the architecture specific gates)
398          */
399         intr_init_hook();
400
401         /*
402          * External FPU? Set up irq13 if so, for
403          * original braindamaged IBM FERR coupling.
404          */
405         if (boot_cpu_data.hard_math && !cpu_has_fpu)
406                 setup_irq(FPU_IRQ, &fpu_irq);
407
408         irq_ctx_init(smp_processor_id());
409 }