1 // SPDX-License-Identifier: GPL-2.0 1 2 #include <linux/init.h> 3 #include <linux/list.h> 4 #include <linux/io.h> 5 6 #include <asm/mach/irq.h> 7 #include <asm/hardware/iomd.h> 8 #include <asm/irq.h> 9 #include <asm/fiq.h> 10 11 // These are offsets from the stat register fo 12 #define STAT 0x00 13 #define REQ 0x04 14 #define CLR 0x04 15 #define MASK 0x08 16 17 static const u8 irq_prio_h[256] = { 18 0, 8, 9, 8,10,10,10,10,11,11,11,11,10 19 12, 8, 9, 8,10,10,10,10,11,11,11,11,10 20 13,13,13,13,10,10,10,10,11,11,11,11,10 21 13,13,13,13,10,10,10,10,11,11,11,11,10 22 14,14,14,14,10,10,10,10,11,11,11,11,10 23 14,14,14,14,10,10,10,10,11,11,11,11,10 24 13,13,13,13,10,10,10,10,11,11,11,11,10 25 13,13,13,13,10,10,10,10,11,11,11,11,10 26 15,15,15,15,10,10,10,10,11,11,11,11,10 27 15,15,15,15,10,10,10,10,11,11,11,11,10 28 13,13,13,13,10,10,10,10,11,11,11,11,10 29 13,13,13,13,10,10,10,10,11,11,11,11,10 30 15,15,15,15,10,10,10,10,11,11,11,11,10 31 15,15,15,15,10,10,10,10,11,11,11,11,10 32 13,13,13,13,10,10,10,10,11,11,11,11,10 33 13,13,13,13,10,10,10,10,11,11,11,11,10 34 }; 35 36 static const u8 irq_prio_d[256] = { 37 0,16,17,16,18,16,17,16,19,16,17,16,18 38 20,16,17,16,18,16,17,16,19,16,17,16,18 39 21,16,17,16,18,16,17,16,19,16,17,16,18 40 21,16,17,16,18,16,17,16,19,16,17,16,18 41 22,16,17,16,18,16,17,16,19,16,17,16,18 42 22,16,17,16,18,16,17,16,19,16,17,16,18 43 21,16,17,16,18,16,17,16,19,16,17,16,18 44 21,16,17,16,18,16,17,16,19,16,17,16,18 45 23,16,17,16,18,16,17,16,19,16,17,16,18 46 23,16,17,16,18,16,17,16,19,16,17,16,18 47 21,16,17,16,18,16,17,16,19,16,17,16,18 48 21,16,17,16,18,16,17,16,19,16,17,16,18 49 22,16,17,16,18,16,17,16,19,16,17,16,18 50 22,16,17,16,18,16,17,16,19,16,17,16,18 51 21,16,17,16,18,16,17,16,19,16,17,16,18 52 21,16,17,16,18,16,17,16,19,16,17,16,18 53 }; 54 55 static const u8 irq_prio_l[256] = { 56 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3 57 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3 58 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 59 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 60 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3 61 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3 62 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 63 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 64 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 65 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 66 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 67 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 68 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 69 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 70 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 71 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 72 }; 73 74 static int iomd_get_irq_nr(void) 75 { 76 int irq; 77 u8 reg; 78 79 /* get highest priority first */ 80 reg = readb(IOC_BASE + IOMD_IRQREQB); 81 irq = irq_prio_h[reg]; 82 if (irq) 83 return irq; 84 85 /* get DMA */ 86 reg = readb(IOC_BASE + IOMD_DMAREQ); 87 irq = irq_prio_d[reg]; 88 if (irq) 89 return irq; 90 91 /* get low priority */ 92 reg = readb(IOC_BASE + IOMD_IRQREQA); 93 irq = irq_prio_l[reg]; 94 if (irq) 95 return irq; 96 return 0; 97 } 98 99 static void iomd_handle_irq(struct pt_regs *re 100 { 101 int irq; 102 103 do { 104 irq = iomd_get_irq_nr(); 105 if (irq) 106 generic_handle_irq(irq 107 } while (irq); 108 } 109 110 static void __iomem *iomd_get_base(struct irq_ 111 { 112 void *cd = irq_data_get_irq_chip_data( 113 114 return (void __iomem *)(unsigned long) 115 } 116 117 static void iomd_set_base_mask(unsigned int ir 118 { 119 struct irq_data *d = irq_get_irq_data( 120 121 d->mask = mask; 122 irq_set_chip_data(irq, (void *)(unsign 123 } 124 125 static void iomd_irq_mask_ack(struct irq_data 126 { 127 void __iomem *base = iomd_get_base(d); 128 unsigned int val, mask = d->mask; 129 130 val = readb(base + MASK); 131 writeb(val & ~mask, base + MASK); 132 writeb(mask, base + CLR); 133 } 134 135 static void iomd_irq_mask(struct irq_data *d) 136 { 137 void __iomem *base = iomd_get_base(d); 138 unsigned int val, mask = d->mask; 139 140 val = readb(base + MASK); 141 writeb(val & ~mask, base + MASK); 142 } 143 144 static void iomd_irq_unmask(struct irq_data *d 145 { 146 void __iomem *base = iomd_get_base(d); 147 unsigned int val, mask = d->mask; 148 149 val = readb(base + MASK); 150 writeb(val | mask, base + MASK); 151 } 152 153 static struct irq_chip iomd_chip_clr = { 154 .irq_mask_ack = iomd_irq_mask_ack, 155 .irq_mask = iomd_irq_mask, 156 .irq_unmask = iomd_irq_unmask, 157 }; 158 159 static struct irq_chip iomd_chip_noclr = { 160 .irq_mask = iomd_irq_mask, 161 .irq_unmask = iomd_irq_unmask, 162 }; 163 164 extern unsigned char rpc_default_fiq_start, rp 165 166 void __init rpc_init_irq(void) 167 { 168 unsigned int irq, clr, set; 169 170 iomd_writeb(0, IOMD_IRQMASKA); 171 iomd_writeb(0, IOMD_IRQMASKB); 172 iomd_writeb(0, IOMD_FIQMASK); 173 iomd_writeb(0, IOMD_DMAMASK); 174 175 set_fiq_handler(&rpc_default_fiq_start 176 &rpc_default_fiq_end - &rpc_de 177 178 set_handle_irq(iomd_handle_irq); 179 180 for (irq = 0; irq < NR_IRQS; irq++) { 181 clr = IRQ_NOREQUEST; 182 set = 0; 183 184 if (irq <= 6 || (irq >= 9 && i 185 clr |= IRQ_NOPROBE; 186 187 if (irq == 21 || (irq >= 16 && 188 irq == IRQ_KEYBOARDTX) 189 set |= IRQ_NOAUTOEN; 190 191 switch (irq) { 192 case 0 ... 7: 193 irq_set_chip_and_handl 194 195 irq_modify_status(irq, 196 iomd_set_base_mask(irq 197 BIT 198 break; 199 200 case 8 ... 15: 201 irq_set_chip_and_handl 202 203 irq_modify_status(irq, 204 iomd_set_base_mask(irq 205 BIT 206 break; 207 208 case 16 ... 21: 209 irq_set_chip_and_handl 210 211 irq_modify_status(irq, 212 iomd_set_base_mask(irq 213 BIT 214 break; 215 216 case 64 ... 71: 217 irq_set_chip(irq, &iom 218 irq_modify_status(irq, 219 iomd_set_base_mask(irq 220 BIT 221 break; 222 } 223 } 224 225 init_FIQ(FIQ_START); 226 } 227
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.