Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'deps-irqchip-gic-3.17' of git://git.infradead.org/users/jcooper/linux.git

+1065 -56
+1
arch/arm64/Kconfig
··· 9 9 select ARM_AMBA 10 10 select ARM_ARCH_TIMER 11 11 select ARM_GIC 12 + select ARM_GIC_V3 12 13 select BUILDTIME_EXTABLE_SORT 13 14 select CLONE_BACKWARDS 14 15 select COMMON_CLK
+18
arch/arm64/kernel/head.S
··· 22 22 23 23 #include <linux/linkage.h> 24 24 #include <linux/init.h> 25 + #include <linux/irqchip/arm-gic-v3.h> 25 26 26 27 #include <asm/assembler.h> 27 28 #include <asm/ptrace.h> ··· 296 295 orr x0, x0, #3 // Enable EL1 physical timers 297 296 msr cnthctl_el2, x0 298 297 msr cntvoff_el2, xzr // Clear virtual offset 298 + 299 + #ifdef CONFIG_ARM_GIC_V3 300 + /* GICv3 system register access */ 301 + mrs x0, id_aa64pfr0_el1 302 + ubfx x0, x0, #24, #4 303 + cmp x0, #1 304 + b.ne 3f 305 + 306 + mrs x0, ICC_SRE_EL2 307 + orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 308 + orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 309 + msr ICC_SRE_EL2, x0 310 + isb // Make sure SRE is now set 311 + msr ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults 312 + 313 + 3: 314 + #endif 299 315 300 316 /* Populate ID registers. */ 301 317 mrs x0, midr_el1
+1
arch/arm64/kernel/hyp-stub.S
··· 19 19 20 20 #include <linux/init.h> 21 21 #include <linux/linkage.h> 22 + #include <linux/irqchip/arm-gic-v3.h> 22 23 23 24 #include <asm/assembler.h> 24 25 #include <asm/ptrace.h>
+5
drivers/irqchip/Kconfig
··· 10 10 config GIC_NON_BANKED 11 11 bool 12 12 13 + config ARM_GIC_V3 14 + bool 15 + select IRQ_DOMAIN 16 + select MULTI_IRQ_HANDLER 17 + 13 18 config ARM_NVIC 14 19 bool 15 20 select IRQ_DOMAIN
+2 -1
drivers/irqchip/Makefile
··· 15 15 obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o 16 16 obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o 17 17 obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o 18 - obj-$(CONFIG_ARM_GIC) += irq-gic.o 18 + obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o 19 + obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o 19 20 obj-$(CONFIG_ARM_NVIC) += irq-nvic.o 20 21 obj-$(CONFIG_ARM_VIC) += irq-vic.o 21 22 obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o
+115
drivers/irqchip/irq-gic-common.c
··· 1 + /* 2 + * Copyright (C) 2002 ARM Limited, All Rights Reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/interrupt.h> 18 + #include <linux/io.h> 19 + #include <linux/irq.h> 20 + #include <linux/irqchip/arm-gic.h> 21 + 22 + #include "irq-gic-common.h" 23 + 24 + void gic_configure_irq(unsigned int irq, unsigned int type, 25 + void __iomem *base, void (*sync_access)(void)) 26 + { 27 + u32 enablemask = 1 << (irq % 32); 28 + u32 enableoff = (irq / 32) * 4; 29 + u32 confmask = 0x2 << ((irq % 16) * 2); 30 + u32 confoff = (irq / 16) * 4; 31 + bool enabled = false; 32 + u32 val; 33 + 34 + /* 35 + * Read current configuration register, and insert the config 36 + * for "irq", depending on "type". 37 + */ 38 + val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); 39 + if (type == IRQ_TYPE_LEVEL_HIGH) 40 + val &= ~confmask; 41 + else if (type == IRQ_TYPE_EDGE_RISING) 42 + val |= confmask; 43 + 44 + /* 45 + * As recommended by the spec, disable the interrupt before changing 46 + * the configuration 47 + */ 48 + if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { 49 + writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); 50 + if (sync_access) 51 + sync_access(); 52 + enabled = true; 53 + } 54 + 55 + /* 56 + * Write back the new configuration, and possibly re-enable 57 + * the interrupt. 58 + */ 59 + writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); 60 + 61 + if (enabled) 62 + writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); 63 + 64 + if (sync_access) 65 + sync_access(); 66 + } 67 + 68 + void __init gic_dist_config(void __iomem *base, int gic_irqs, 69 + void (*sync_access)(void)) 70 + { 71 + unsigned int i; 72 + 73 + /* 74 + * Set all global interrupts to be level triggered, active low. 75 + */ 76 + for (i = 32; i < gic_irqs; i += 16) 77 + writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4); 78 + 79 + /* 80 + * Set priority on all global interrupts. 81 + */ 82 + for (i = 32; i < gic_irqs; i += 4) 83 + writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i); 84 + 85 + /* 86 + * Disable all interrupts. Leave the PPI and SGIs alone 87 + * as they are enabled by redistributor registers. 88 + */ 89 + for (i = 32; i < gic_irqs; i += 32) 90 + writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8); 91 + 92 + if (sync_access) 93 + sync_access(); 94 + } 95 + 96 + void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) 97 + { 98 + int i; 99 + 100 + /* 101 + * Deal with the banked PPI and SGI interrupts - disable all 102 + * PPI interrupts, ensure all SGI interrupts are enabled. 103 + */ 104 + writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR); 105 + writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET); 106 + 107 + /* 108 + * Set priority on PPI and SGI interrupts 109 + */ 110 + for (i = 0; i < 32; i += 4) 111 + writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); 112 + 113 + if (sync_access) 114 + sync_access(); 115 + }
+29
drivers/irqchip/irq-gic-common.h
··· 1 + /* 2 + * Copyright (C) 2002 ARM Limited, All Rights Reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #ifndef _IRQ_GIC_COMMON_H 18 + #define _IRQ_GIC_COMMON_H 19 + 20 + #include <linux/of.h> 21 + #include <linux/irqdomain.h> 22 + 23 + void gic_configure_irq(unsigned int irq, unsigned int type, 24 + void __iomem *base, void (*sync_access)(void)); 25 + void gic_dist_config(void __iomem *base, int gic_irqs, 26 + void (*sync_access)(void)); 27 + void gic_cpu_config(void __iomem *base, void (*sync_access)(void)); 28 + 29 + #endif /* _IRQ_GIC_COMMON_H */
+692
drivers/irqchip/irq-gic-v3.c
··· 1 + /* 2 + * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. 3 + * Author: Marc Zyngier <marc.zyngier@arm.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #include <linux/cpu.h> 19 + #include <linux/delay.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/of.h> 22 + #include <linux/of_address.h> 23 + #include <linux/of_irq.h> 24 + #include <linux/percpu.h> 25 + #include <linux/slab.h> 26 + 27 + #include <linux/irqchip/arm-gic-v3.h> 28 + 29 + #include <asm/cputype.h> 30 + #include <asm/exception.h> 31 + #include <asm/smp_plat.h> 32 + 33 + #include "irq-gic-common.h" 34 + #include "irqchip.h" 35 + 36 + struct gic_chip_data { 37 + void __iomem *dist_base; 38 + void __iomem **redist_base; 39 + void __percpu __iomem **rdist; 40 + struct irq_domain *domain; 41 + u64 redist_stride; 42 + u32 redist_regions; 43 + unsigned int irq_nr; 44 + }; 45 + 46 + static struct gic_chip_data gic_data __read_mostly; 47 + 48 + #define gic_data_rdist() (this_cpu_ptr(gic_data.rdist)) 49 + #define gic_data_rdist_rd_base() (*gic_data_rdist()) 50 + #define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K) 51 + 52 + /* Our default, arbitrary priority value. Linux only uses one anyway. */ 53 + #define DEFAULT_PMR_VALUE 0xf0 54 + 55 + static inline unsigned int gic_irq(struct irq_data *d) 56 + { 57 + return d->hwirq; 58 + } 59 + 60 + static inline int gic_irq_in_rdist(struct irq_data *d) 61 + { 62 + return gic_irq(d) < 32; 63 + } 64 + 65 + static inline void __iomem *gic_dist_base(struct irq_data *d) 66 + { 67 + if (gic_irq_in_rdist(d)) /* SGI+PPI -> SGI_base for this CPU */ 68 + return gic_data_rdist_sgi_base(); 69 + 70 + if (d->hwirq <= 1023) /* SPI -> dist_base */ 71 + return gic_data.dist_base; 72 + 73 + if (d->hwirq >= 8192) 74 + BUG(); /* LPI Detected!!! */ 75 + 76 + return NULL; 77 + } 78 + 79 + static void gic_do_wait_for_rwp(void __iomem *base) 80 + { 81 + u32 count = 1000000; /* 1s! */ 82 + 83 + while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { 84 + count--; 85 + if (!count) { 86 + pr_err_ratelimited("RWP timeout, gone fishing\n"); 87 + return; 88 + } 89 + cpu_relax(); 90 + udelay(1); 91 + }; 92 + } 93 + 94 + /* Wait for completion of a distributor change */ 95 + static void gic_dist_wait_for_rwp(void) 96 + { 97 + gic_do_wait_for_rwp(gic_data.dist_base); 98 + } 99 + 100 + /* Wait for completion of a redistributor change */ 101 + static void gic_redist_wait_for_rwp(void) 102 + { 103 + gic_do_wait_for_rwp(gic_data_rdist_rd_base()); 104 + } 105 + 106 + /* Low level accessors */ 107 + static u64 gic_read_iar(void) 108 + { 109 + u64 irqstat; 110 + 111 + asm volatile("mrs %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat)); 112 + return irqstat; 113 + } 114 + 115 + static void gic_write_pmr(u64 val) 116 + { 117 + asm volatile("msr " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); 118 + } 119 + 120 + static void gic_write_ctlr(u64 val) 121 + { 122 + asm volatile("msr " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); 123 + isb(); 124 + } 125 + 126 + static void gic_write_grpen1(u64 val) 127 + { 128 + asm volatile("msr " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); 129 + isb(); 130 + } 131 + 132 + static void gic_write_sgi1r(u64 val) 133 + { 134 + asm volatile("msr " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); 135 + } 136 + 137 + static void gic_enable_sre(void) 138 + { 139 + u64 val; 140 + 141 + asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); 142 + val |= ICC_SRE_EL1_SRE; 143 + asm volatile("msr " __stringify(ICC_SRE_EL1) ", %0" : : "r" (val)); 144 + isb(); 145 + 146 + /* 147 + * Need to check that the SRE bit has actually been set. If 148 + * not, it means that SRE is disabled at EL2. We're going to 149 + * die painfully, and there is nothing we can do about it. 150 + * 151 + * Kindly inform the luser. 152 + */ 153 + asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); 154 + if (!(val & ICC_SRE_EL1_SRE)) 155 + pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); 156 + } 157 + 158 + static void gic_enable_redist(void) 159 + { 160 + void __iomem *rbase; 161 + u32 count = 1000000; /* 1s! */ 162 + u32 val; 163 + 164 + rbase = gic_data_rdist_rd_base(); 165 + 166 + /* Wake up this CPU redistributor */ 167 + val = readl_relaxed(rbase + GICR_WAKER); 168 + val &= ~GICR_WAKER_ProcessorSleep; 169 + writel_relaxed(val, rbase + GICR_WAKER); 170 + 171 + while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) { 172 + count--; 173 + if (!count) { 174 + pr_err_ratelimited("redist didn't wake up...\n"); 175 + return; 176 + } 177 + cpu_relax(); 178 + udelay(1); 179 + }; 180 + } 181 + 182 + /* 183 + * Routines to disable, enable, EOI and route interrupts 184 + */ 185 + static void gic_poke_irq(struct irq_data *d, u32 offset) 186 + { 187 + u32 mask = 1 << (gic_irq(d) % 32); 188 + void (*rwp_wait)(void); 189 + void __iomem *base; 190 + 191 + if (gic_irq_in_rdist(d)) { 192 + base = gic_data_rdist_sgi_base(); 193 + rwp_wait = gic_redist_wait_for_rwp; 194 + } else { 195 + base = gic_data.dist_base; 196 + rwp_wait = gic_dist_wait_for_rwp; 197 + } 198 + 199 + writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4); 200 + rwp_wait(); 201 + } 202 + 203 + static int gic_peek_irq(struct irq_data *d, u32 offset) 204 + { 205 + u32 mask = 1 << (gic_irq(d) % 32); 206 + void __iomem *base; 207 + 208 + if (gic_irq_in_rdist(d)) 209 + base = gic_data_rdist_sgi_base(); 210 + else 211 + base = gic_data.dist_base; 212 + 213 + return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); 214 + } 215 + 216 + static void gic_mask_irq(struct irq_data *d) 217 + { 218 + gic_poke_irq(d, GICD_ICENABLER); 219 + } 220 + 221 + static void gic_unmask_irq(struct irq_data *d) 222 + { 223 + gic_poke_irq(d, GICD_ISENABLER); 224 + } 225 + 226 + static void gic_eoi_irq(struct irq_data *d) 227 + { 228 + gic_write_eoir(gic_irq(d)); 229 + } 230 + 231 + static int gic_set_type(struct irq_data *d, unsigned int type) 232 + { 233 + unsigned int irq = gic_irq(d); 234 + void (*rwp_wait)(void); 235 + void __iomem *base; 236 + 237 + /* Interrupt configuration for SGIs can't be changed */ 238 + if (irq < 16) 239 + return -EINVAL; 240 + 241 + if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) 242 + return -EINVAL; 243 + 244 + if (gic_irq_in_rdist(d)) { 245 + base = gic_data_rdist_sgi_base(); 246 + rwp_wait = gic_redist_wait_for_rwp; 247 + } else { 248 + base = gic_data.dist_base; 249 + rwp_wait = gic_dist_wait_for_rwp; 250 + } 251 + 252 + gic_configure_irq(irq, type, base, rwp_wait); 253 + 254 + return 0; 255 + } 256 + 257 + static u64 gic_mpidr_to_affinity(u64 mpidr) 258 + { 259 + u64 aff; 260 + 261 + aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 | 262 + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | 263 + MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | 264 + MPIDR_AFFINITY_LEVEL(mpidr, 0)); 265 + 266 + return aff; 267 + } 268 + 269 + static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 270 + { 271 + u64 irqnr; 272 + 273 + do { 274 + irqnr = gic_read_iar(); 275 + 276 + if (likely(irqnr > 15 && irqnr < 1020)) { 277 + u64 irq = irq_find_mapping(gic_data.domain, irqnr); 278 + if (likely(irq)) { 279 + handle_IRQ(irq, regs); 280 + continue; 281 + } 282 + 283 + WARN_ONCE(true, "Unexpected SPI received!\n"); 284 + gic_write_eoir(irqnr); 285 + } 286 + if (irqnr < 16) { 287 + gic_write_eoir(irqnr); 288 + #ifdef CONFIG_SMP 289 + handle_IPI(irqnr, regs); 290 + #else 291 + WARN_ONCE(true, "Unexpected SGI received!\n"); 292 + #endif 293 + continue; 294 + } 295 + } while (irqnr != ICC_IAR1_EL1_SPURIOUS); 296 + } 297 + 298 + static void __init gic_dist_init(void) 299 + { 300 + unsigned int i; 301 + u64 affinity; 302 + void __iomem *base = gic_data.dist_base; 303 + 304 + /* Disable the distributor */ 305 + writel_relaxed(0, base + GICD_CTLR); 306 + gic_dist_wait_for_rwp(); 307 + 308 + gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp); 309 + 310 + /* Enable distributor with ARE, Group1 */ 311 + writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, 312 + base + GICD_CTLR); 313 + 314 + /* 315 + * Set all global interrupts to the boot CPU only. ARE must be 316 + * enabled. 317 + */ 318 + affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); 319 + for (i = 32; i < gic_data.irq_nr; i++) 320 + writeq_relaxed(affinity, base + GICD_IROUTER + i * 8); 321 + } 322 + 323 + static int gic_populate_rdist(void) 324 + { 325 + u64 mpidr = cpu_logical_map(smp_processor_id()); 326 + u64 typer; 327 + u32 aff; 328 + int i; 329 + 330 + /* 331 + * Convert affinity to a 32bit value that can be matched to 332 + * GICR_TYPER bits [63:32]. 333 + */ 334 + aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 | 335 + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | 336 + MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | 337 + MPIDR_AFFINITY_LEVEL(mpidr, 0)); 338 + 339 + for (i = 0; i < gic_data.redist_regions; i++) { 340 + void __iomem *ptr = gic_data.redist_base[i]; 341 + u32 reg; 342 + 343 + reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK; 344 + if (reg != GIC_PIDR2_ARCH_GICv3 && 345 + reg != GIC_PIDR2_ARCH_GICv4) { /* We're in trouble... */ 346 + pr_warn("No redistributor present @%p\n", ptr); 347 + break; 348 + } 349 + 350 + do { 351 + typer = readq_relaxed(ptr + GICR_TYPER); 352 + if ((typer >> 32) == aff) { 353 + gic_data_rdist_rd_base() = ptr; 354 + pr_info("CPU%d: found redistributor %llx @%p\n", 355 + smp_processor_id(), 356 + (unsigned long long)mpidr, ptr); 357 + return 0; 358 + } 359 + 360 + if (gic_data.redist_stride) { 361 + ptr += gic_data.redist_stride; 362 + } else { 363 + ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */ 364 + if (typer & GICR_TYPER_VLPIS) 365 + ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */ 366 + } 367 + } while (!(typer & GICR_TYPER_LAST)); 368 + } 369 + 370 + /* We couldn't even deal with ourselves... */ 371 + WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n", 372 + smp_processor_id(), (unsigned long long)mpidr); 373 + return -ENODEV; 374 + } 375 + 376 + static void gic_cpu_init(void) 377 + { 378 + void __iomem *rbase; 379 + 380 + /* Register ourselves with the rest of the world */ 381 + if (gic_populate_rdist()) 382 + return; 383 + 384 + gic_enable_redist(); 385 + 386 + rbase = gic_data_rdist_sgi_base(); 387 + 388 + gic_cpu_config(rbase, gic_redist_wait_for_rwp); 389 + 390 + /* Enable system registers */ 391 + gic_enable_sre(); 392 + 393 + /* Set priority mask register */ 394 + gic_write_pmr(DEFAULT_PMR_VALUE); 395 + 396 + /* EOI deactivates interrupt too (mode 0) */ 397 + gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir); 398 + 399 + /* ... and let's hit the road... */ 400 + gic_write_grpen1(1); 401 + } 402 + 403 + #ifdef CONFIG_SMP 404 + static int gic_secondary_init(struct notifier_block *nfb, 405 + unsigned long action, void *hcpu) 406 + { 407 + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 408 + gic_cpu_init(); 409 + return NOTIFY_OK; 410 + } 411 + 412 + /* 413 + * Notifier for enabling the GIC CPU interface. Set an arbitrarily high 414 + * priority because the GIC needs to be up before the ARM generic timers. 415 + */ 416 + static struct notifier_block gic_cpu_notifier = { 417 + .notifier_call = gic_secondary_init, 418 + .priority = 100, 419 + }; 420 + 421 + static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, 422 + u64 cluster_id) 423 + { 424 + int cpu = *base_cpu; 425 + u64 mpidr = cpu_logical_map(cpu); 426 + u16 tlist = 0; 427 + 428 + while (cpu < nr_cpu_ids) { 429 + /* 430 + * If we ever get a cluster of more than 16 CPUs, just 431 + * scream and skip that CPU. 432 + */ 433 + if (WARN_ON((mpidr & 0xff) >= 16)) 434 + goto out; 435 + 436 + tlist |= 1 << (mpidr & 0xf); 437 + 438 + cpu = cpumask_next(cpu, mask); 439 + if (cpu == nr_cpu_ids) 440 + goto out; 441 + 442 + mpidr = cpu_logical_map(cpu); 443 + 444 + if (cluster_id != (mpidr & ~0xffUL)) { 445 + cpu--; 446 + goto out; 447 + } 448 + } 449 + out: 450 + *base_cpu = cpu; 451 + return tlist; 452 + } 453 + 454 + static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) 455 + { 456 + u64 val; 457 + 458 + val = (MPIDR_AFFINITY_LEVEL(cluster_id, 3) << 48 | 459 + MPIDR_AFFINITY_LEVEL(cluster_id, 2) << 32 | 460 + irq << 24 | 461 + MPIDR_AFFINITY_LEVEL(cluster_id, 1) << 16 | 462 + tlist); 463 + 464 + pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); 465 + gic_write_sgi1r(val); 466 + } 467 + 468 + static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 469 + { 470 + int cpu; 471 + 472 + if (WARN_ON(irq >= 16)) 473 + return; 474 + 475 + /* 476 + * Ensure that stores to Normal memory are visible to the 477 + * other CPUs before issuing the IPI. 478 + */ 479 + smp_wmb(); 480 + 481 + for_each_cpu_mask(cpu, *mask) { 482 + u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL; 483 + u16 tlist; 484 + 485 + tlist = gic_compute_target_list(&cpu, mask, cluster_id); 486 + gic_send_sgi(cluster_id, tlist, irq); 487 + } 488 + 489 + /* Force the above writes to ICC_SGI1R_EL1 to be executed */ 490 + isb(); 491 + } 492 + 493 + static void gic_smp_init(void) 494 + { 495 + set_smp_cross_call(gic_raise_softirq); 496 + register_cpu_notifier(&gic_cpu_notifier); 497 + } 498 + 499 + static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, 500 + bool force) 501 + { 502 + unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); 503 + void __iomem *reg; 504 + int enabled; 505 + u64 val; 506 + 507 + if (gic_irq_in_rdist(d)) 508 + return -EINVAL; 509 + 510 + /* If interrupt was enabled, disable it first */ 511 + enabled = gic_peek_irq(d, GICD_ISENABLER); 512 + if (enabled) 513 + gic_mask_irq(d); 514 + 515 + reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8); 516 + val = gic_mpidr_to_affinity(cpu_logical_map(cpu)); 517 + 518 + writeq_relaxed(val, reg); 519 + 520 + /* 521 + * If the interrupt was enabled, enabled it again. Otherwise, 522 + * just wait for the distributor to have digested our changes. 523 + */ 524 + if (enabled) 525 + gic_unmask_irq(d); 526 + else 527 + gic_dist_wait_for_rwp(); 528 + 529 + return IRQ_SET_MASK_OK; 530 + } 531 + #else 532 + #define gic_set_affinity NULL 533 + #define gic_smp_init() do { } while(0) 534 + #endif 535 + 536 + static struct irq_chip gic_chip = { 537 + .name = "GICv3", 538 + .irq_mask = gic_mask_irq, 539 + .irq_unmask = gic_unmask_irq, 540 + .irq_eoi = gic_eoi_irq, 541 + .irq_set_type = gic_set_type, 542 + .irq_set_affinity = gic_set_affinity, 543 + }; 544 + 545 + static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, 546 + irq_hw_number_t hw) 547 + { 548 + /* SGIs are private to the core kernel */ 549 + if (hw < 16) 550 + return -EPERM; 551 + /* PPIs */ 552 + if (hw < 32) { 553 + irq_set_percpu_devid(irq); 554 + irq_set_chip_and_handler(irq, &gic_chip, 555 + handle_percpu_devid_irq); 556 + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); 557 + } 558 + /* SPIs */ 559 + if (hw >= 32 && hw < gic_data.irq_nr) { 560 + irq_set_chip_and_handler(irq, &gic_chip, 561 + handle_fasteoi_irq); 562 + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 563 + } 564 + irq_set_chip_data(irq, d->host_data); 565 + return 0; 566 + } 567 + 568 + static int gic_irq_domain_xlate(struct irq_domain *d, 569 + struct device_node *controller, 570 + const u32 *intspec, unsigned int intsize, 571 + unsigned long *out_hwirq, unsigned int *out_type) 572 + { 573 + if (d->of_node != controller) 574 + return -EINVAL; 575 + if (intsize < 3) 576 + return -EINVAL; 577 + 578 + switch(intspec[0]) { 579 + case 0: /* SPI */ 580 + *out_hwirq = intspec[1] + 32; 581 + break; 582 + case 1: /* PPI */ 583 + *out_hwirq = intspec[1] + 16; 584 + break; 585 + default: 586 + return -EINVAL; 587 + } 588 + 589 + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 590 + return 0; 591 + } 592 + 593 + static const struct irq_domain_ops gic_irq_domain_ops = { 594 + .map = gic_irq_domain_map, 595 + .xlate = gic_irq_domain_xlate, 596 + }; 597 + 598 + static int __init gic_of_init(struct device_node *node, struct device_node *parent) 599 + { 600 + void __iomem *dist_base; 601 + void __iomem **redist_base; 602 + u64 redist_stride; 603 + u32 redist_regions; 604 + u32 reg; 605 + int gic_irqs; 606 + int err; 607 + int i; 608 + 609 + dist_base = of_iomap(node, 0); 610 + if (!dist_base) { 611 + pr_err("%s: unable to map gic dist registers\n", 612 + node->full_name); 613 + return -ENXIO; 614 + } 615 + 616 + reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; 617 + if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) { 618 + pr_err("%s: no distributor detected, giving up\n", 619 + node->full_name); 620 + err = -ENODEV; 621 + goto out_unmap_dist; 622 + } 623 + 624 + if (of_property_read_u32(node, "#redistributor-regions", &redist_regions)) 625 + redist_regions = 1; 626 + 627 + redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL); 628 + if (!redist_base) { 629 + err = -ENOMEM; 630 + goto out_unmap_dist; 631 + } 632 + 633 + for (i = 0; i < redist_regions; i++) { 634 + redist_base[i] = of_iomap(node, 1 + i); 635 + if (!redist_base[i]) { 636 + pr_err("%s: couldn't map region %d\n", 637 + node->full_name, i); 638 + err = -ENODEV; 639 + goto out_unmap_rdist; 640 + } 641 + } 642 + 643 + if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) 644 + redist_stride = 0; 645 + 646 + gic_data.dist_base = dist_base; 647 + gic_data.redist_base = redist_base; 648 + gic_data.redist_regions = redist_regions; 649 + gic_data.redist_stride = redist_stride; 650 + 651 + /* 652 + * Find out how many interrupts are supported. 653 + * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) 654 + */ 655 + gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f; 656 + gic_irqs = (gic_irqs + 1) * 32; 657 + if (gic_irqs > 1020) 658 + gic_irqs = 1020; 659 + gic_data.irq_nr = gic_irqs; 660 + 661 + gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, 662 + &gic_data); 663 + gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist)); 664 + 665 + if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) { 666 + err = -ENOMEM; 667 + goto out_free; 668 + } 669 + 670 + set_handle_irq(gic_handle_irq); 671 + 672 + gic_smp_init(); 673 + gic_dist_init(); 674 + gic_cpu_init(); 675 + 676 + return 0; 677 + 678 + out_free: 679 + if (gic_data.domain) 680 + irq_domain_remove(gic_data.domain); 681 + free_percpu(gic_data.rdist); 682 + out_unmap_rdist: 683 + for (i = 0; i < redist_regions; i++) 684 + if (redist_base[i]) 685 + iounmap(redist_base[i]); 686 + kfree(redist_base); 687 + out_unmap_dist: 688 + iounmap(dist_base); 689 + return err; 690 + } 691 + 692 + IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
+4 -55
drivers/irqchip/irq-gic.c
··· 46 46 #include <asm/exception.h> 47 47 #include <asm/smp_plat.h> 48 48 49 + #include "irq-gic-common.h" 49 50 #include "irqchip.h" 50 51 51 52 union gic_base { ··· 189 188 { 190 189 void __iomem *base = gic_dist_base(d); 191 190 unsigned int gicirq = gic_irq(d); 192 - u32 enablemask = 1 << (gicirq % 32); 193 - u32 enableoff = (gicirq / 32) * 4; 194 - u32 confmask = 0x2 << ((gicirq % 16) * 2); 195 - u32 confoff = (gicirq / 16) * 4; 196 - bool enabled = false; 197 - u32 val; 198 191 199 192 /* Interrupt configuration for SGIs can't be changed */ 200 193 if (gicirq < 16) ··· 202 207 if (gic_arch_extn.irq_set_type) 203 208 gic_arch_extn.irq_set_type(d, type); 204 209 205 - val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); 206 - if (type == IRQ_TYPE_LEVEL_HIGH) 207 - val &= ~confmask; 208 - else if (type == IRQ_TYPE_EDGE_RISING) 209 - val |= confmask; 210 - 211 - /* 212 - * As recommended by the spec, disable the interrupt before changing 213 - * the configuration 214 - */ 215 - if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { 216 - writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); 217 - enabled = true; 218 - } 219 - 220 - writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); 221 - 222 - if (enabled) 223 - writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); 210 + gic_configure_irq(gicirq, type, base, NULL); 224 211 225 212 raw_spin_unlock(&irq_controller_lock); 226 213 ··· 364 387 writel_relaxed(0, base + GIC_DIST_CTRL); 365 388 366 389 /* 367 - * Set all global interrupts to be level triggered, active low. 368 - */ 369 - for (i = 32; i < gic_irqs; i += 16) 370 - writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16); 371 - 372 - /* 373 390 * Set all global interrupts to this CPU only. 374 391 */ 375 392 cpumask = gic_get_cpumask(gic); ··· 372 401 for (i = 32; i < gic_irqs; i += 4) 373 402 writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); 374 403 375 - /* 376 - * Set priority on all global interrupts. 377 - */ 378 - for (i = 32; i < gic_irqs; i += 4) 379 - writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); 380 - 381 - /* 382 - * Disable all interrupts. Leave the PPI and SGIs alone 383 - * as these enables are banked registers. 384 - */ 385 - for (i = 32; i < gic_irqs; i += 32) 386 - writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); 404 + gic_dist_config(base, gic_irqs, NULL); 387 405 388 406 writel_relaxed(1, base + GIC_DIST_CTRL); 389 407 } ··· 399 439 if (i != cpu) 400 440 gic_cpu_map[i] &= ~cpu_mask; 401 441 402 - /* 403 - * Deal with the banked PPI and SGI interrupts - disable all 404 - * PPI interrupts, ensure all SGI interrupts are enabled. 405 - */ 406 - writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); 407 - writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); 408 - 409 - /* 410 - * Set priority on PPI and SGI interrupts 411 - */ 412 - for (i = 0; i < 32; i += 4) 413 - writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); 442 + gic_cpu_config(dist_base, NULL); 414 443 415 444 writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); 416 445 writel_relaxed(1, base + GIC_CPU_CTRL);
+198
include/linux/irqchip/arm-gic-v3.h
··· 1 + /* 2 + * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. 3 + * Author: Marc Zyngier <marc.zyngier@arm.com> 4 + * 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + #ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H 19 + #define __LINUX_IRQCHIP_ARM_GIC_V3_H 20 + 21 + /* 22 + * Distributor registers. We assume we're running non-secure, with ARE 23 + * being set. Secure-only and non-ARE registers are not described. 24 + */ 25 + #define GICD_CTLR 0x0000 26 + #define GICD_TYPER 0x0004 27 + #define GICD_IIDR 0x0008 28 + #define GICD_STATUSR 0x0010 29 + #define GICD_SETSPI_NSR 0x0040 30 + #define GICD_CLRSPI_NSR 0x0048 31 + #define GICD_SETSPI_SR 0x0050 32 + #define GICD_CLRSPI_SR 0x0058 33 + #define GICD_SEIR 0x0068 34 + #define GICD_ISENABLER 0x0100 35 + #define GICD_ICENABLER 0x0180 36 + #define GICD_ISPENDR 0x0200 37 + #define GICD_ICPENDR 0x0280 38 + #define GICD_ISACTIVER 0x0300 39 + #define GICD_ICACTIVER 0x0380 40 + #define GICD_IPRIORITYR 0x0400 41 + #define GICD_ICFGR 0x0C00 42 + #define GICD_IROUTER 0x6000 43 + #define GICD_PIDR2 0xFFE8 44 + 45 + #define GICD_CTLR_RWP (1U << 31) 46 + #define GICD_CTLR_ARE_NS (1U << 4) 47 + #define GICD_CTLR_ENABLE_G1A (1U << 1) 48 + #define GICD_CTLR_ENABLE_G1 (1U << 0) 49 + 50 + #define GICD_IROUTER_SPI_MODE_ONE (0U << 31) 51 + #define GICD_IROUTER_SPI_MODE_ANY (1U << 31) 52 + 53 + #define GIC_PIDR2_ARCH_MASK 0xf0 54 + #define GIC_PIDR2_ARCH_GICv3 0x30 55 + #define GIC_PIDR2_ARCH_GICv4 0x40 56 + 57 + /* 58 + * Re-Distributor registers, offsets from RD_base 59 + */ 60 + #define GICR_CTLR GICD_CTLR 61 + #define GICR_IIDR 0x0004 62 + #define GICR_TYPER 0x0008 63 + #define GICR_STATUSR GICD_STATUSR 64 + #define GICR_WAKER 0x0014 65 + #define GICR_SETLPIR 0x0040 66 + #define GICR_CLRLPIR 0x0048 67 + #define GICR_SEIR GICD_SEIR 68 + #define GICR_PROPBASER 0x0070 69 + #define GICR_PENDBASER 0x0078 70 + #define GICR_INVLPIR 0x00A0 71 + #define GICR_INVALLR 0x00B0 72 + #define GICR_SYNCR 0x00C0 73 + #define GICR_MOVLPIR 0x0100 74 + #define GICR_MOVALLR 0x0110 75 + #define GICR_PIDR2 GICD_PIDR2 76 + 77 + #define GICR_WAKER_ProcessorSleep (1U << 1) 78 + #define GICR_WAKER_ChildrenAsleep (1U << 2) 79 + 80 + /* 81 + * Re-Distributor registers, offsets from SGI_base 82 + */ 83 + #define GICR_ISENABLER0 GICD_ISENABLER 84 + #define GICR_ICENABLER0 GICD_ICENABLER 85 + #define GICR_ISPENDR0 GICD_ISPENDR 86 + #define GICR_ICPENDR0 GICD_ICPENDR 87 + #define GICR_ISACTIVER0 GICD_ISACTIVER 88 + #define GICR_ICACTIVER0 GICD_ICACTIVER 89 + #define GICR_IPRIORITYR0 GICD_IPRIORITYR 90 + #define GICR_ICFGR0 GICD_ICFGR 91 + 92 + #define GICR_TYPER_VLPIS (1U << 1) 93 + #define GICR_TYPER_LAST (1U << 4) 94 + 95 + /* 96 + * CPU interface registers 97 + */ 98 + #define ICC_CTLR_EL1_EOImode_drop_dir (0U << 1) 99 + #define ICC_CTLR_EL1_EOImode_drop (1U << 1) 100 + #define ICC_SRE_EL1_SRE (1U << 0) 101 + 102 + /* 103 + * Hypervisor interface registers (SRE only) 104 + */ 105 + #define ICH_LR_VIRTUAL_ID_MASK ((1UL << 32) - 1) 106 + 107 + #define ICH_LR_EOI (1UL << 41) 108 + #define ICH_LR_GROUP (1UL << 60) 109 + #define ICH_LR_STATE (3UL << 62) 110 + #define ICH_LR_PENDING_BIT (1UL << 62) 111 + #define ICH_LR_ACTIVE_BIT (1UL << 63) 112 + 113 + #define ICH_MISR_EOI (1 << 0) 114 + #define ICH_MISR_U (1 << 1) 115 + 116 + #define ICH_HCR_EN (1 << 0) 117 + #define ICH_HCR_UIE (1 << 1) 118 + 119 + #define ICH_VMCR_CTLR_SHIFT 0 120 + #define ICH_VMCR_CTLR_MASK (0x21f << ICH_VMCR_CTLR_SHIFT) 121 + #define ICH_VMCR_BPR1_SHIFT 18 122 + #define ICH_VMCR_BPR1_MASK (7 << ICH_VMCR_BPR1_SHIFT) 123 + #define ICH_VMCR_BPR0_SHIFT 21 124 + #define ICH_VMCR_BPR0_MASK (7 << ICH_VMCR_BPR0_SHIFT) 125 + #define ICH_VMCR_PMR_SHIFT 24 126 + #define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT) 127 + 128 + #define ICC_EOIR1_EL1 S3_0_C12_C12_1 129 + #define ICC_IAR1_EL1 S3_0_C12_C12_0 130 + #define ICC_SGI1R_EL1 S3_0_C12_C11_5 131 + #define ICC_PMR_EL1 S3_0_C4_C6_0 132 + #define ICC_CTLR_EL1 S3_0_C12_C12_4 133 + #define ICC_SRE_EL1 S3_0_C12_C12_5 134 + #define ICC_GRPEN1_EL1 S3_0_C12_C12_7 135 + 136 + #define ICC_IAR1_EL1_SPURIOUS 0x3ff 137 + 138 + #define ICC_SRE_EL2 S3_4_C12_C9_5 139 + 140 + #define ICC_SRE_EL2_SRE (1 << 0) 141 + #define ICC_SRE_EL2_ENABLE (1 << 3) 142 + 143 + /* 144 + * System register definitions 145 + */ 146 + #define ICH_VSEIR_EL2 S3_4_C12_C9_4 147 + #define ICH_HCR_EL2 S3_4_C12_C11_0 148 + #define ICH_VTR_EL2 S3_4_C12_C11_1 149 + #define ICH_MISR_EL2 S3_4_C12_C11_2 150 + #define ICH_EISR_EL2 S3_4_C12_C11_3 151 + #define ICH_ELSR_EL2 S3_4_C12_C11_5 152 + #define ICH_VMCR_EL2 S3_4_C12_C11_7 153 + 154 + #define __LR0_EL2(x) S3_4_C12_C12_ ## x 155 + #define __LR8_EL2(x) S3_4_C12_C13_ ## x 156 + 157 + #define ICH_LR0_EL2 __LR0_EL2(0) 158 + #define ICH_LR1_EL2 __LR0_EL2(1) 159 + #define ICH_LR2_EL2 __LR0_EL2(2) 160 + #define ICH_LR3_EL2 __LR0_EL2(3) 161 + #define ICH_LR4_EL2 __LR0_EL2(4) 162 + #define ICH_LR5_EL2 __LR0_EL2(5) 163 + #define ICH_LR6_EL2 __LR0_EL2(6) 164 + #define ICH_LR7_EL2 __LR0_EL2(7) 165 + #define ICH_LR8_EL2 __LR8_EL2(0) 166 + #define ICH_LR9_EL2 __LR8_EL2(1) 167 + #define ICH_LR10_EL2 __LR8_EL2(2) 168 + #define ICH_LR11_EL2 __LR8_EL2(3) 169 + #define ICH_LR12_EL2 __LR8_EL2(4) 170 + #define ICH_LR13_EL2 __LR8_EL2(5) 171 + #define ICH_LR14_EL2 __LR8_EL2(6) 172 + #define ICH_LR15_EL2 __LR8_EL2(7) 173 + 174 + #define __AP0Rx_EL2(x) S3_4_C12_C8_ ## x 175 + #define ICH_AP0R0_EL2 __AP0Rx_EL2(0) 176 + #define ICH_AP0R1_EL2 __AP0Rx_EL2(1) 177 + #define ICH_AP0R2_EL2 __AP0Rx_EL2(2) 178 + #define ICH_AP0R3_EL2 __AP0Rx_EL2(3) 179 + 180 + #define __AP1Rx_EL2(x) S3_4_C12_C9_ ## x 181 + #define ICH_AP1R0_EL2 __AP1Rx_EL2(0) 182 + #define ICH_AP1R1_EL2 __AP1Rx_EL2(1) 183 + #define ICH_AP1R2_EL2 __AP1Rx_EL2(2) 184 + #define ICH_AP1R3_EL2 __AP1Rx_EL2(3) 185 + 186 + #ifndef __ASSEMBLY__ 187 + 188 + #include <linux/stringify.h> 189 + 190 + static inline void gic_write_eoir(u64 irq) 191 + { 192 + asm volatile("msr " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq)); 193 + isb(); 194 + } 195 + 196 + #endif 197 + 198 + #endif