1 #include <linux/init.h> 2 #include <linux/list.h> 3 #include <linux/io.h> 4 5 #include <asm/mach/irq.h> 6 #include <asm/hardware/iomd.h> 7 #include <asm/irq.h> 8 #include <asm/fiq.h> 9 10 static void iomd_ack_irq_a(struct irq_data *d) 11 { 12 unsigned int val, mask; 13 14 mask = 1 << d->irq; 15 val = iomd_readb(IOMD_IRQMASKA); 16 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 17 iomd_writeb(mask, IOMD_IRQCLRA); 18 } 19 20 static void iomd_mask_irq_a(struct irq_data *d) 21 { 22 unsigned int val, mask; 23 24 mask = 1 << d->irq; 25 val = iomd_readb(IOMD_IRQMASKA); 26 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 27 } 28 29 static void iomd_unmask_irq_a(struct irq_data *d) 30 { 31 unsigned int val, mask; 32 33 mask = 1 << d->irq; 34 val = iomd_readb(IOMD_IRQMASKA); 35 iomd_writeb(val | mask, IOMD_IRQMASKA); 36 } 37 38 static struct irq_chip iomd_a_chip = { 39 .irq_ack = iomd_ack_irq_a, 40 .irq_mask = iomd_mask_irq_a, 41 .irq_unmask = iomd_unmask_irq_a, 42 }; 43 44 static void iomd_mask_irq_b(struct irq_data *d) 45 { 46 unsigned int val, mask; 47 48 mask = 1 << (d->irq & 7); 49 val = iomd_readb(IOMD_IRQMASKB); 50 iomd_writeb(val & ~mask, IOMD_IRQMASKB); 51 } 52 53 static void iomd_unmask_irq_b(struct irq_data *d) 54 { 55 unsigned int val, mask; 56 57 mask = 1 << (d->irq & 7); 58 val = iomd_readb(IOMD_IRQMASKB); 59 iomd_writeb(val | mask, IOMD_IRQMASKB); 60 } 61 62 static struct irq_chip iomd_b_chip = { 63 .irq_ack = iomd_mask_irq_b, 64 .irq_mask = iomd_mask_irq_b, 65 .irq_unmask = iomd_unmask_irq_b, 66 }; 67 68 static void iomd_mask_irq_dma(struct irq_data *d) 69 { 70 unsigned int val, mask; 71 72 mask = 1 << (d->irq & 7); 73 val = iomd_readb(IOMD_DMAMASK); 74 iomd_writeb(val & ~mask, IOMD_DMAMASK); 75 } 76 77 static void iomd_unmask_irq_dma(struct irq_data *d) 78 { 79 unsigned int val, mask; 80 81 mask = 1 << (d->irq & 7); 82 val = iomd_readb(IOMD_DMAMASK); 83 iomd_writeb(val | mask, IOMD_DMAMASK); 84 } 85 86 static struct irq_chip iomd_dma_chip = { 87 .irq_ack = iomd_mask_irq_dma, 88 .irq_mask = iomd_mask_irq_dma, 89 .irq_unmask = iomd_unmask_irq_dma, 90 }; 91 92 static void iomd_mask_irq_fiq(struct irq_data *d) 93 { 94 unsigned int val, mask; 95 96 mask = 1 << (d->irq & 7); 97 val = iomd_readb(IOMD_FIQMASK); 98 iomd_writeb(val & ~mask, IOMD_FIQMASK); 99 } 100 101 static void iomd_unmask_irq_fiq(struct irq_data *d) 102 { 103 unsigned int val, mask; 104 105 mask = 1 << (d->irq & 7); 106 val = iomd_readb(IOMD_FIQMASK); 107 iomd_writeb(val | mask, IOMD_FIQMASK); 108 } 109 110 static struct irq_chip iomd_fiq_chip = { 111 .irq_ack = iomd_mask_irq_fiq, 112 .irq_mask = iomd_mask_irq_fiq, 113 .irq_unmask = iomd_unmask_irq_fiq, 114 }; 115 116 extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; 117 118 void __init rpc_init_irq(void) 119 { 120 unsigned int irq, flags; 121 122 iomd_writeb(0, IOMD_IRQMASKA); 123 iomd_writeb(0, IOMD_IRQMASKB); 124 iomd_writeb(0, IOMD_FIQMASK); 125 iomd_writeb(0, IOMD_DMAMASK); 126 127 set_fiq_handler(&rpc_default_fiq_start, 128 &rpc_default_fiq_end - &rpc_default_fiq_start); 129 130 for (irq = 0; irq < NR_IRQS; irq++) { 131 flags = IRQF_VALID; 132 133 if (irq <= 6 || (irq >= 9 && irq <= 15)) 134 flags |= IRQF_PROBE; 135 136 if (irq == 21 || (irq >= 16 && irq <= 19) || 137 irq == IRQ_KEYBOARDTX) 138 flags |= IRQF_NOAUTOEN; 139 140 switch (irq) { 141 case 0 ... 7: 142 irq_set_chip_and_handler(irq, &iomd_a_chip, 143 handle_level_irq); 144 set_irq_flags(irq, flags); 145 break; 146 147 case 8 ... 15: 148 irq_set_chip_and_handler(irq, &iomd_b_chip, 149 handle_level_irq); 150 set_irq_flags(irq, flags); 151 break; 152 153 case 16 ... 21: 154 irq_set_chip_and_handler(irq, &iomd_dma_chip, 155 handle_level_irq); 156 set_irq_flags(irq, flags); 157 break; 158 159 case 64 ... 71: 160 irq_set_chip(irq, &iomd_fiq_chip); 161 set_irq_flags(irq, IRQF_VALID); 162 break; 163 } 164 } 165 166 init_FIQ(FIQ_START); 167 } 168 169