0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/ioport.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/list.h>
0017 #include <linux/init.h>
0018 #include <linux/io.h>
0019 #include <linux/spinlock.h>
0020
0021 #include <asm/mach/irq.h>
0022
0023 #include <mach/hardware.h>
0024 #include <asm/hardware/dec21285.h>
0025 #include <asm/irq.h>
0026 #include <asm/mach-types.h>
0027
0028 #include "common.h"
0029
0030 static void isa_mask_pic_lo_irq(struct irq_data *d)
0031 {
0032 unsigned int mask = 1 << (d->irq & 7);
0033
0034 outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
0035 }
0036
0037 static void isa_ack_pic_lo_irq(struct irq_data *d)
0038 {
0039 unsigned int mask = 1 << (d->irq & 7);
0040
0041 outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
0042 outb(0x20, PIC_LO);
0043 }
0044
0045 static void isa_unmask_pic_lo_irq(struct irq_data *d)
0046 {
0047 unsigned int mask = 1 << (d->irq & 7);
0048
0049 outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
0050 }
0051
0052 static struct irq_chip isa_lo_chip = {
0053 .irq_ack = isa_ack_pic_lo_irq,
0054 .irq_mask = isa_mask_pic_lo_irq,
0055 .irq_unmask = isa_unmask_pic_lo_irq,
0056 };
0057
0058 static void isa_mask_pic_hi_irq(struct irq_data *d)
0059 {
0060 unsigned int mask = 1 << (d->irq & 7);
0061
0062 outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
0063 }
0064
0065 static void isa_ack_pic_hi_irq(struct irq_data *d)
0066 {
0067 unsigned int mask = 1 << (d->irq & 7);
0068
0069 outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
0070 outb(0x62, PIC_LO);
0071 outb(0x20, PIC_HI);
0072 }
0073
0074 static void isa_unmask_pic_hi_irq(struct irq_data *d)
0075 {
0076 unsigned int mask = 1 << (d->irq & 7);
0077
0078 outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
0079 }
0080
0081 static struct irq_chip isa_hi_chip = {
0082 .irq_ack = isa_ack_pic_hi_irq,
0083 .irq_mask = isa_mask_pic_hi_irq,
0084 .irq_unmask = isa_unmask_pic_hi_irq,
0085 };
0086
0087 static void isa_irq_handler(struct irq_desc *desc)
0088 {
0089 unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;
0090
0091 if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
0092 do_bad_IRQ(desc);
0093 return;
0094 }
0095
0096 generic_handle_irq(isa_irq);
0097 }
0098
0099 static struct resource pic1_resource = {
0100 .name = "pic1",
0101 .start = 0x20,
0102 .end = 0x3f,
0103 };
0104
0105 static struct resource pic2_resource = {
0106 .name = "pic2",
0107 .start = 0xa0,
0108 .end = 0xbf,
0109 };
0110
0111 void __init isa_init_irq(unsigned int host_irq)
0112 {
0113 unsigned int irq;
0114
0115
0116
0117
0118
0119
0120 outb(0x11, PIC_LO);
0121 outb(_ISA_IRQ(0), PIC_MASK_LO);
0122 outb(0x04, PIC_MASK_LO);
0123 outb(0x01, PIC_MASK_LO);
0124 outb(0xf5, PIC_MASK_LO);
0125
0126 outb(0x11, PIC_HI);
0127 outb(_ISA_IRQ(8), PIC_MASK_HI);
0128 outb(0x02, PIC_MASK_HI);
0129 outb(0x01, PIC_MASK_HI);
0130 outb(0xfa, PIC_MASK_HI);
0131
0132 outb(0x0b, PIC_LO);
0133 outb(0x0b, PIC_HI);
0134
0135 if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
0136 outb(0xff, PIC_MASK_LO);
0137 outb(0xff, PIC_MASK_HI);
0138 } else {
0139 printk(KERN_INFO "IRQ: ISA PIC not found\n");
0140 host_irq = (unsigned int)-1;
0141 }
0142
0143 if (host_irq != (unsigned int)-1) {
0144 for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
0145 irq_set_chip_and_handler(irq, &isa_lo_chip,
0146 handle_level_irq);
0147 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0148 }
0149
0150 for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
0151 irq_set_chip_and_handler(irq, &isa_hi_chip,
0152 handle_level_irq);
0153 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0154 }
0155
0156 request_resource(&ioport_resource, &pic1_resource);
0157 request_resource(&ioport_resource, &pic2_resource);
0158
0159 irq = IRQ_ISA_CASCADE;
0160 if (request_irq(irq, no_action, 0, "cascade", NULL))
0161 pr_err("Failed to request irq %u (cascade)\n", irq);
0162
0163 irq_set_chained_handler(host_irq, isa_irq_handler);
0164
0165
0166
0167
0168
0169
0170
0171 if (machine_is_netwinder())
0172 irq_modify_status(_ISA_IRQ(11),
0173 IRQ_NOREQUEST | IRQ_NOPROBE, IRQ_NOAUTOEN);
0174 }
0175 }
0176
0177