0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _ASM_I8259_H
0011 #define _ASM_I8259_H
0012
0013 #include <linux/compiler.h>
0014 #include <linux/spinlock.h>
0015
0016 #include <asm/io.h>
0017 #include <irq.h>
0018
0019
0020 #define PIC_MASTER_CMD 0x20
0021 #define PIC_MASTER_IMR 0x21
0022 #define PIC_MASTER_ISR PIC_MASTER_CMD
0023 #define PIC_MASTER_POLL PIC_MASTER_ISR
0024 #define PIC_MASTER_OCW3 PIC_MASTER_ISR
0025 #define PIC_SLAVE_CMD 0xa0
0026 #define PIC_SLAVE_IMR 0xa1
0027
0028
0029 #define PIC_CASCADE_IR 2
0030 #define MASTER_ICW4_DEFAULT 0x01
0031 #define SLAVE_ICW4_DEFAULT 0x01
0032 #define PIC_ICW4_AEOI 2
0033
0034 extern raw_spinlock_t i8259A_lock;
0035
0036 extern void make_8259A_irq(unsigned int irq);
0037
0038 extern void init_i8259_irqs(void);
0039 extern struct irq_domain *__init_i8259_irqs(struct device_node *node);
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 extern void i8259_set_poll(int (*poll)(void));
0051
0052
0053
0054
0055
0056
0057 static inline int i8259_irq(void)
0058 {
0059 int irq;
0060
0061 raw_spin_lock(&i8259A_lock);
0062
0063
0064 outb(0x0C, PIC_MASTER_CMD);
0065 irq = inb(PIC_MASTER_CMD) & 7;
0066 if (irq == PIC_CASCADE_IR) {
0067
0068
0069
0070
0071 outb(0x0C, PIC_SLAVE_CMD);
0072 irq = (inb(PIC_SLAVE_CMD) & 7) + 8;
0073 }
0074
0075 if (unlikely(irq == 7)) {
0076
0077
0078
0079
0080
0081
0082
0083 outb(0x0B, PIC_MASTER_ISR);
0084 if(~inb(PIC_MASTER_ISR) & 0x80)
0085 irq = -1;
0086 }
0087
0088 raw_spin_unlock(&i8259A_lock);
0089
0090 return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq;
0091 }
0092
0093 #endif