| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * 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 | 4 | * |
|---|
| 8 | 5 | * Interrupt architecture for the GIC: |
|---|
| 9 | 6 | * |
|---|
| .. | .. |
|---|
| 86 | 83 | #endif |
|---|
| 87 | 84 | struct irq_domain *domain; |
|---|
| 88 | 85 | unsigned int gic_irqs; |
|---|
| 89 | | -#ifdef CONFIG_GIC_NON_BANKED |
|---|
| 90 | | - void __iomem *(*get_base)(union gic_base *); |
|---|
| 91 | | -#endif |
|---|
| 92 | 86 | }; |
|---|
| 93 | 87 | |
|---|
| 94 | 88 | #ifdef CONFIG_BL_SWITCHER |
|---|
| .. | .. |
|---|
| 113 | 107 | |
|---|
| 114 | 108 | #endif |
|---|
| 115 | 109 | |
|---|
| 110 | +static DEFINE_STATIC_KEY_FALSE(needs_rmw_access); |
|---|
| 111 | + |
|---|
| 116 | 112 | /* |
|---|
| 117 | 113 | * The GIC mapping of CPU interfaces does not necessarily match |
|---|
| 118 | 114 | * the logical CPU numbering. Let's use a mapping as returned |
|---|
| .. | .. |
|---|
| 127 | 123 | |
|---|
| 128 | 124 | static struct gic_kvm_info gic_v2_kvm_info; |
|---|
| 129 | 125 | |
|---|
| 126 | +static DEFINE_PER_CPU(u32, sgi_intid); |
|---|
| 127 | + |
|---|
| 130 | 128 | #ifdef CONFIG_GIC_NON_BANKED |
|---|
| 131 | | -static void __iomem *gic_get_percpu_base(union gic_base *base) |
|---|
| 129 | +static DEFINE_STATIC_KEY_FALSE(frankengic_key); |
|---|
| 130 | + |
|---|
| 131 | +static void enable_frankengic(void) |
|---|
| 132 | 132 | { |
|---|
| 133 | | - return raw_cpu_read(*base->percpu_base); |
|---|
| 133 | + static_branch_enable(&frankengic_key); |
|---|
| 134 | 134 | } |
|---|
| 135 | 135 | |
|---|
| 136 | | -static void __iomem *gic_get_common_base(union gic_base *base) |
|---|
| 136 | +static inline void __iomem *__get_base(union gic_base *base) |
|---|
| 137 | 137 | { |
|---|
| 138 | + if (static_branch_unlikely(&frankengic_key)) |
|---|
| 139 | + return raw_cpu_read(*base->percpu_base); |
|---|
| 140 | + |
|---|
| 138 | 141 | return base->common_base; |
|---|
| 139 | 142 | } |
|---|
| 140 | 143 | |
|---|
| 141 | | -static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) |
|---|
| 142 | | -{ |
|---|
| 143 | | - return data->get_base(&data->dist_base); |
|---|
| 144 | | -} |
|---|
| 145 | | - |
|---|
| 146 | | -static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) |
|---|
| 147 | | -{ |
|---|
| 148 | | - return data->get_base(&data->cpu_base); |
|---|
| 149 | | -} |
|---|
| 150 | | - |
|---|
| 151 | | -static inline void gic_set_base_accessor(struct gic_chip_data *data, |
|---|
| 152 | | - void __iomem *(*f)(union gic_base *)) |
|---|
| 153 | | -{ |
|---|
| 154 | | - data->get_base = f; |
|---|
| 155 | | -} |
|---|
| 144 | +#define gic_data_dist_base(d) __get_base(&(d)->dist_base) |
|---|
| 145 | +#define gic_data_cpu_base(d) __get_base(&(d)->cpu_base) |
|---|
| 156 | 146 | #else |
|---|
| 157 | 147 | #define gic_data_dist_base(d) ((d)->dist_base.common_base) |
|---|
| 158 | 148 | #define gic_data_cpu_base(d) ((d)->cpu_base.common_base) |
|---|
| 159 | | -#define gic_set_base_accessor(d, f) |
|---|
| 149 | +#define enable_frankengic() do { } while(0) |
|---|
| 160 | 150 | #endif |
|---|
| 161 | 151 | |
|---|
| 162 | 152 | static inline void __iomem *gic_dist_base(struct irq_data *d) |
|---|
| .. | .. |
|---|
| 227 | 217 | gic_poke_irq(d, GIC_DIST_ENABLE_SET); |
|---|
| 228 | 218 | } |
|---|
| 229 | 219 | |
|---|
| 230 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 231 | | -static int gic_retrigger(struct irq_data *d) |
|---|
| 232 | | -{ |
|---|
| 233 | | - gic_poke_irq(d, GIC_DIST_PENDING_SET); |
|---|
| 234 | | - /* the genirq layer expects 0 if we can't retrigger in hardware */ |
|---|
| 235 | | - return 0; |
|---|
| 236 | | -} |
|---|
| 237 | | -#endif |
|---|
| 238 | | - |
|---|
| 239 | 220 | static void gic_eoi_irq(struct irq_data *d) |
|---|
| 240 | 221 | { |
|---|
| 241 | | - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); |
|---|
| 222 | + u32 hwirq = gic_irq(d); |
|---|
| 223 | + |
|---|
| 224 | + if (hwirq < 16) |
|---|
| 225 | + hwirq = this_cpu_read(sgi_intid); |
|---|
| 226 | + |
|---|
| 227 | + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_EOI); |
|---|
| 242 | 228 | } |
|---|
| 243 | 229 | |
|---|
| 244 | 230 | static void gic_eoimode1_eoi_irq(struct irq_data *d) |
|---|
| 245 | 231 | { |
|---|
| 232 | + u32 hwirq = gic_irq(d); |
|---|
| 233 | + |
|---|
| 246 | 234 | /* Do not deactivate an IRQ forwarded to a vcpu. */ |
|---|
| 247 | 235 | if (irqd_is_forwarded_to_vcpu(d)) |
|---|
| 248 | 236 | return; |
|---|
| 249 | 237 | |
|---|
| 250 | | - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE); |
|---|
| 238 | + if (hwirq < 16) |
|---|
| 239 | + hwirq = this_cpu_read(sgi_intid); |
|---|
| 240 | + |
|---|
| 241 | + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_DEACTIVATE); |
|---|
| 251 | 242 | } |
|---|
| 252 | 243 | |
|---|
| 253 | 244 | static int gic_irq_set_irqchip_state(struct irq_data *d, |
|---|
| .. | .. |
|---|
| 303 | 294 | { |
|---|
| 304 | 295 | void __iomem *base = gic_dist_base(d); |
|---|
| 305 | 296 | unsigned int gicirq = gic_irq(d); |
|---|
| 297 | + int ret; |
|---|
| 306 | 298 | |
|---|
| 307 | 299 | /* Interrupt configuration for SGIs can't be changed */ |
|---|
| 308 | 300 | if (gicirq < 16) |
|---|
| 309 | | - return -EINVAL; |
|---|
| 301 | + return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; |
|---|
| 310 | 302 | |
|---|
| 311 | 303 | /* SPIs have restrictions on the supported types */ |
|---|
| 312 | 304 | if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && |
|---|
| 313 | 305 | type != IRQ_TYPE_EDGE_RISING) |
|---|
| 314 | 306 | return -EINVAL; |
|---|
| 315 | 307 | |
|---|
| 316 | | - return gic_configure_irq(gicirq, type, base, NULL); |
|---|
| 308 | + ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL); |
|---|
| 309 | + if (ret && gicirq < 32) { |
|---|
| 310 | + /* Misconfigured PPIs are usually not fatal */ |
|---|
| 311 | + pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16); |
|---|
| 312 | + ret = 0; |
|---|
| 313 | + } |
|---|
| 314 | + |
|---|
| 315 | + return ret; |
|---|
| 317 | 316 | } |
|---|
| 318 | 317 | |
|---|
| 319 | 318 | static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) |
|---|
| 320 | 319 | { |
|---|
| 321 | 320 | /* Only interrupts on the primary GIC can be forwarded to a vcpu. */ |
|---|
| 322 | | - if (cascading_gic_irq(d)) |
|---|
| 321 | + if (cascading_gic_irq(d) || gic_irq(d) < 16) |
|---|
| 323 | 322 | return -EINVAL; |
|---|
| 324 | 323 | |
|---|
| 325 | 324 | if (vcpu) |
|---|
| .. | .. |
|---|
| 329 | 328 | return 0; |
|---|
| 330 | 329 | } |
|---|
| 331 | 330 | |
|---|
| 332 | | -#ifdef CONFIG_SMP |
|---|
| 333 | | -static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
|---|
| 334 | | - bool force) |
|---|
| 331 | +static int gic_retrigger(struct irq_data *data) |
|---|
| 335 | 332 | { |
|---|
| 336 | | - void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); |
|---|
| 337 | | - unsigned int cpu; |
|---|
| 338 | | - |
|---|
| 339 | | - if (!force) |
|---|
| 340 | | - cpu = cpumask_any_and(mask_val, cpu_online_mask); |
|---|
| 341 | | - else |
|---|
| 342 | | - cpu = cpumask_first(mask_val); |
|---|
| 343 | | - |
|---|
| 344 | | - if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
|---|
| 345 | | - return -EINVAL; |
|---|
| 346 | | - |
|---|
| 347 | | - writeb_relaxed(gic_cpu_map[cpu], reg); |
|---|
| 348 | | - irq_data_update_effective_affinity(d, cpumask_of(cpu)); |
|---|
| 349 | | - |
|---|
| 350 | | - return IRQ_SET_MASK_OK_DONE; |
|---|
| 333 | + return !gic_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); |
|---|
| 351 | 334 | } |
|---|
| 352 | | -#endif |
|---|
| 353 | 335 | |
|---|
| 354 | 336 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) |
|---|
| 355 | 337 | { |
|---|
| .. | .. |
|---|
| 358 | 340 | void __iomem *cpu_base = gic_data_cpu_base(gic); |
|---|
| 359 | 341 | |
|---|
| 360 | 342 | do { |
|---|
| 343 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 344 | + irqstat = readl_relaxed(cpu_base + GIC_CPU_ALIAS_INTACK); |
|---|
| 345 | +#else |
|---|
| 361 | 346 | irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); |
|---|
| 347 | +#endif |
|---|
| 362 | 348 | irqnr = irqstat & GICC_IAR_INT_ID_MASK; |
|---|
| 363 | 349 | |
|---|
| 364 | | - if (likely(irqnr > 15 && irqnr < 1020)) { |
|---|
| 365 | | - if (static_branch_likely(&supports_deactivate_key)) |
|---|
| 366 | | - writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); |
|---|
| 367 | | - isb(); |
|---|
| 368 | | - handle_domain_irq(gic->domain, irqnr, regs); |
|---|
| 369 | | - continue; |
|---|
| 370 | | - } |
|---|
| 371 | | - if (irqnr < 16) { |
|---|
| 350 | + if (unlikely(irqnr >= 1020)) |
|---|
| 351 | + break; |
|---|
| 352 | + |
|---|
| 353 | + if (static_branch_likely(&supports_deactivate_key)) |
|---|
| 372 | 354 | writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); |
|---|
| 373 | | - if (static_branch_likely(&supports_deactivate_key)) |
|---|
| 374 | | - writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE); |
|---|
| 375 | | -#ifdef CONFIG_SMP |
|---|
| 376 | | - /* |
|---|
| 377 | | - * Ensure any shared data written by the CPU sending |
|---|
| 378 | | - * the IPI is read after we've read the ACK register |
|---|
| 379 | | - * on the GIC. |
|---|
| 380 | | - * |
|---|
| 381 | | - * Pairs with the write barrier in gic_raise_softirq |
|---|
| 382 | | - */ |
|---|
| 355 | + isb(); |
|---|
| 356 | + |
|---|
| 357 | + /* |
|---|
| 358 | + * Ensure any shared data written by the CPU sending the IPI |
|---|
| 359 | + * is read after we've read the ACK register on the GIC. |
|---|
| 360 | + * |
|---|
| 361 | + * Pairs with the write barrier in gic_ipi_send_mask |
|---|
| 362 | + */ |
|---|
| 363 | + if (irqnr <= 15) { |
|---|
| 383 | 364 | smp_rmb(); |
|---|
| 384 | | - handle_IPI(irqnr, regs); |
|---|
| 385 | | -#endif |
|---|
| 386 | | - continue; |
|---|
| 365 | + |
|---|
| 366 | + /* |
|---|
| 367 | + * The GIC encodes the source CPU in GICC_IAR, |
|---|
| 368 | + * leading to the deactivation to fail if not |
|---|
| 369 | + * written back as is to GICC_EOI. Stash the INTID |
|---|
| 370 | + * away for gic_eoi_irq() to write back. This only |
|---|
| 371 | + * works because we don't nest SGIs... |
|---|
| 372 | + */ |
|---|
| 373 | + this_cpu_write(sgi_intid, irqstat); |
|---|
| 387 | 374 | } |
|---|
| 388 | | - break; |
|---|
| 375 | + |
|---|
| 376 | + handle_domain_irq(gic->domain, irqnr, regs); |
|---|
| 389 | 377 | } while (1); |
|---|
| 390 | 378 | } |
|---|
| 391 | 379 | |
|---|
| .. | .. |
|---|
| 397 | 385 | unsigned long status; |
|---|
| 398 | 386 | |
|---|
| 399 | 387 | chained_irq_enter(chip, desc); |
|---|
| 400 | | - |
|---|
| 388 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 389 | + status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_ALIAS_INTACK); |
|---|
| 390 | +#else |
|---|
| 401 | 391 | status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); |
|---|
| 402 | | - |
|---|
| 392 | +#endif |
|---|
| 403 | 393 | gic_irq = (status & GICC_IAR_INT_ID_MASK); |
|---|
| 404 | 394 | if (gic_irq == GICC_INT_SPURIOUS) |
|---|
| 405 | 395 | goto out; |
|---|
| .. | .. |
|---|
| 421 | 411 | .irq_unmask = gic_unmask_irq, |
|---|
| 422 | 412 | .irq_eoi = gic_eoi_irq, |
|---|
| 423 | 413 | .irq_set_type = gic_set_type, |
|---|
| 424 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 425 | 414 | .irq_retrigger = gic_retrigger, |
|---|
| 426 | | -#endif |
|---|
| 427 | 415 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
|---|
| 428 | 416 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
|---|
| 429 | 417 | .flags = IRQCHIP_SET_TYPE_MASKED | |
|---|
| .. | .. |
|---|
| 483 | 471 | bypass = readl(cpu_base + GIC_CPU_CTRL); |
|---|
| 484 | 472 | bypass &= GICC_DIS_BYPASS_MASK; |
|---|
| 485 | 473 | |
|---|
| 474 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 475 | + writel_relaxed(0x0f, cpu_base + GIC_CPU_CTRL); |
|---|
| 476 | +#else |
|---|
| 486 | 477 | writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL); |
|---|
| 478 | +#endif |
|---|
| 487 | 479 | } |
|---|
| 488 | 480 | |
|---|
| 489 | 481 | |
|---|
| .. | .. |
|---|
| 507 | 499 | |
|---|
| 508 | 500 | gic_dist_config(base, gic_irqs, NULL); |
|---|
| 509 | 501 | |
|---|
| 502 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 503 | + /* set all the interrupt to non-secure state */ |
|---|
| 504 | + for (i = 0; i < gic_irqs; i += 32) |
|---|
| 505 | + writel_relaxed(0xffffffff, base + GIC_DIST_IGROUP + i * 4 / 32); |
|---|
| 506 | + dsb(sy); |
|---|
| 507 | + writel_relaxed(3, base + GIC_DIST_CTRL); |
|---|
| 508 | +#else |
|---|
| 510 | 509 | writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); |
|---|
| 510 | +#endif |
|---|
| 511 | 511 | } |
|---|
| 512 | 512 | |
|---|
| 513 | 513 | static int gic_cpu_init(struct gic_chip_data *gic) |
|---|
| .. | .. |
|---|
| 542 | 542 | gic_cpu_map[i] &= ~cpu_mask; |
|---|
| 543 | 543 | } |
|---|
| 544 | 544 | |
|---|
| 545 | | - gic_cpu_config(dist_base, NULL); |
|---|
| 545 | + gic_cpu_config(dist_base, 32, NULL); |
|---|
| 546 | 546 | |
|---|
| 547 | 547 | writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); |
|---|
| 548 | 548 | gic_cpu_if_up(gic); |
|---|
| .. | .. |
|---|
| 608 | 608 | /* |
|---|
| 609 | 609 | * Restores the GIC distributor registers during resume or when coming out of |
|---|
| 610 | 610 | * idle. Must be called before enabling interrupts. If a level interrupt |
|---|
| 611 | | - * that occured while the GIC was suspended is still present, it will be |
|---|
| 612 | | - * handled normally, but any edge interrupts that occured will not be seen by |
|---|
| 611 | + * that occurred while the GIC was suspended is still present, it will be |
|---|
| 612 | + * handled normally, but any edge interrupts that occurred will not be seen by |
|---|
| 613 | 613 | * the GIC and need to be handled by the platform-specific wakeup source. |
|---|
| 614 | 614 | */ |
|---|
| 615 | 615 | void gic_dist_restore(struct gic_chip_data *gic) |
|---|
| .. | .. |
|---|
| 655 | 655 | dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
|---|
| 656 | 656 | } |
|---|
| 657 | 657 | |
|---|
| 658 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 659 | + writel_relaxed(3, dist_base + GIC_DIST_CTRL); |
|---|
| 660 | +#else |
|---|
| 658 | 661 | writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); |
|---|
| 662 | +#endif |
|---|
| 659 | 663 | } |
|---|
| 660 | 664 | |
|---|
| 661 | 665 | void gic_cpu_save(struct gic_chip_data *gic) |
|---|
| .. | .. |
|---|
| 735 | 739 | int i; |
|---|
| 736 | 740 | |
|---|
| 737 | 741 | for (i = 0; i < CONFIG_ARM_GIC_MAX_NR; i++) { |
|---|
| 738 | | -#ifdef CONFIG_GIC_NON_BANKED |
|---|
| 739 | | - /* Skip over unused GICs */ |
|---|
| 740 | | - if (!gic_data[i].get_base) |
|---|
| 741 | | - continue; |
|---|
| 742 | | -#endif |
|---|
| 743 | 742 | switch (cmd) { |
|---|
| 744 | 743 | case CPU_PM_ENTER: |
|---|
| 745 | 744 | gic_cpu_save(&gic_data[i]); |
|---|
| .. | .. |
|---|
| 801 | 800 | } |
|---|
| 802 | 801 | #endif |
|---|
| 803 | 802 | |
|---|
| 803 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 804 | +/* |
|---|
| 805 | + * ICDISR each bit 0 -- Secure 1--Non-Secure |
|---|
| 806 | + */ |
|---|
| 807 | +void gic_set_irq_secure(struct irq_data *d) |
|---|
| 808 | +{ |
|---|
| 809 | + u32 mask = 0; |
|---|
| 810 | + void __iomem *base = gic_dist_base(d); |
|---|
| 811 | + |
|---|
| 812 | + base += GIC_DIST_IGROUP + ((gic_irq(d) / 32) * 4); |
|---|
| 813 | + mask = readl_relaxed(base); |
|---|
| 814 | + mask &= ~(1 << (gic_irq(d) % 32)); |
|---|
| 815 | + writel_relaxed(mask, base); |
|---|
| 816 | +} |
|---|
| 817 | + |
|---|
| 818 | +void gic_set_irq_priority(struct irq_data *d, u8 pri) |
|---|
| 819 | +{ |
|---|
| 820 | + writeb_relaxed(pri, gic_dist_base(d) + GIC_DIST_PRI + gic_irq(d)); |
|---|
| 821 | +} |
|---|
| 822 | +#endif |
|---|
| 823 | + |
|---|
| 804 | 824 | #ifdef CONFIG_SMP |
|---|
| 805 | | -static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) |
|---|
| 825 | +static void rmw_writeb(u8 bval, void __iomem *addr) |
|---|
| 826 | +{ |
|---|
| 827 | + static DEFINE_RAW_SPINLOCK(rmw_lock); |
|---|
| 828 | + unsigned long offset = (unsigned long)addr & 3UL; |
|---|
| 829 | + unsigned long shift = offset * 8; |
|---|
| 830 | + unsigned long flags; |
|---|
| 831 | + u32 val; |
|---|
| 832 | + |
|---|
| 833 | + raw_spin_lock_irqsave(&rmw_lock, flags); |
|---|
| 834 | + |
|---|
| 835 | + addr -= offset; |
|---|
| 836 | + val = readl_relaxed(addr); |
|---|
| 837 | + val &= ~GENMASK(shift + 7, shift); |
|---|
| 838 | + val |= bval << shift; |
|---|
| 839 | + writel_relaxed(val, addr); |
|---|
| 840 | + |
|---|
| 841 | + raw_spin_unlock_irqrestore(&rmw_lock, flags); |
|---|
| 842 | +} |
|---|
| 843 | + |
|---|
| 844 | +static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
|---|
| 845 | + bool force) |
|---|
| 846 | +{ |
|---|
| 847 | + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); |
|---|
| 848 | + unsigned int cpu; |
|---|
| 849 | + |
|---|
| 850 | + if (!force) |
|---|
| 851 | + cpu = cpumask_any_and(mask_val, cpu_online_mask); |
|---|
| 852 | + else |
|---|
| 853 | + cpu = cpumask_first(mask_val); |
|---|
| 854 | + |
|---|
| 855 | + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
|---|
| 856 | + return -EINVAL; |
|---|
| 857 | + |
|---|
| 858 | + if (static_branch_unlikely(&needs_rmw_access)) |
|---|
| 859 | + rmw_writeb(gic_cpu_map[cpu], reg); |
|---|
| 860 | + else |
|---|
| 861 | + writeb_relaxed(gic_cpu_map[cpu], reg); |
|---|
| 862 | + irq_data_update_effective_affinity(d, cpumask_of(cpu)); |
|---|
| 863 | + |
|---|
| 864 | + return IRQ_SET_MASK_OK_DONE; |
|---|
| 865 | +} |
|---|
| 866 | + |
|---|
| 867 | +static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) |
|---|
| 806 | 868 | { |
|---|
| 807 | 869 | int cpu; |
|---|
| 808 | 870 | unsigned long flags, map = 0; |
|---|
| 809 | 871 | |
|---|
| 810 | 872 | if (unlikely(nr_cpu_ids == 1)) { |
|---|
| 811 | 873 | /* Only one CPU? let's do a self-IPI... */ |
|---|
| 812 | | - writel_relaxed(2 << 24 | irq, |
|---|
| 874 | + writel_relaxed(2 << 24 | d->hwirq, |
|---|
| 813 | 875 | gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
|---|
| 814 | 876 | return; |
|---|
| 815 | 877 | } |
|---|
| .. | .. |
|---|
| 827 | 889 | dmb(ishst); |
|---|
| 828 | 890 | |
|---|
| 829 | 891 | /* this always happens on GIC0 */ |
|---|
| 830 | | - writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
|---|
| 831 | | - |
|---|
| 892 | +#ifdef CONFIG_FIQ_GLUE |
|---|
| 893 | + /* enable non-secure SGI for GIC with security extensions */ |
|---|
| 894 | + writel_relaxed(map << 16 | d->hwirq | 0x8000, |
|---|
| 895 | + gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
|---|
| 896 | +#else |
|---|
| 897 | + writel_relaxed(map << 16 | d->hwirq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
|---|
| 898 | +#endif |
|---|
| 832 | 899 | gic_unlock_irqrestore(flags); |
|---|
| 833 | 900 | } |
|---|
| 901 | + |
|---|
| 902 | +static int gic_starting_cpu(unsigned int cpu) |
|---|
| 903 | +{ |
|---|
| 904 | + gic_cpu_init(&gic_data[0]); |
|---|
| 905 | + if (IS_ENABLED(CONFIG_FIQ_GLUE)) { |
|---|
| 906 | + /* set SGI to none secure state */ |
|---|
| 907 | + writel_relaxed(0xffffffff, gic_data_dist_base(&gic_data[0]) + GIC_DIST_IGROUP); |
|---|
| 908 | + writel_relaxed(0xf, gic_data_cpu_base(&gic_data[0]) + GIC_CPU_CTRL); |
|---|
| 909 | + } |
|---|
| 910 | + return 0; |
|---|
| 911 | +} |
|---|
| 912 | + |
|---|
| 913 | +static __init void gic_smp_init(void) |
|---|
| 914 | +{ |
|---|
| 915 | + struct irq_fwspec sgi_fwspec = { |
|---|
| 916 | + .fwnode = gic_data[0].domain->fwnode, |
|---|
| 917 | + .param_count = 1, |
|---|
| 918 | + }; |
|---|
| 919 | + int base_sgi; |
|---|
| 920 | + |
|---|
| 921 | + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, |
|---|
| 922 | + "irqchip/arm/gic:starting", |
|---|
| 923 | + gic_starting_cpu, NULL); |
|---|
| 924 | + |
|---|
| 925 | + base_sgi = __irq_domain_alloc_irqs(gic_data[0].domain, -1, 8, |
|---|
| 926 | + NUMA_NO_NODE, &sgi_fwspec, |
|---|
| 927 | + false, NULL); |
|---|
| 928 | + if (WARN_ON(base_sgi <= 0)) |
|---|
| 929 | + return; |
|---|
| 930 | + |
|---|
| 931 | + set_smp_ipi_range(base_sgi, 8); |
|---|
| 932 | +} |
|---|
| 933 | +#else |
|---|
| 934 | +#define gic_smp_init() do { } while(0) |
|---|
| 935 | +#define gic_set_affinity NULL |
|---|
| 936 | +#define gic_ipi_send_mask NULL |
|---|
| 834 | 937 | #endif |
|---|
| 835 | 938 | |
|---|
| 836 | 939 | #ifdef CONFIG_BL_SWITCHER |
|---|
| .. | .. |
|---|
| 903 | 1006 | gic_cpu_map[cpu] = 1 << new_cpu_id; |
|---|
| 904 | 1007 | |
|---|
| 905 | 1008 | /* |
|---|
| 906 | | - * Find all the peripheral interrupts targetting the current |
|---|
| 1009 | + * Find all the peripheral interrupts targeting the current |
|---|
| 907 | 1010 | * CPU interface and migrate them to the new CPU interface. |
|---|
| 908 | 1011 | * We skip DIST_TARGET 0 to 7 as they are read-only. |
|---|
| 909 | 1012 | */ |
|---|
| .. | .. |
|---|
| 976 | 1079 | irq_hw_number_t hw) |
|---|
| 977 | 1080 | { |
|---|
| 978 | 1081 | struct gic_chip_data *gic = d->host_data; |
|---|
| 1082 | + struct irq_data *irqd = irq_desc_get_irq_data(irq_to_desc(irq)); |
|---|
| 979 | 1083 | |
|---|
| 980 | | - if (hw < 32) { |
|---|
| 1084 | + switch (hw) { |
|---|
| 1085 | + case 0 ... 15: |
|---|
| 1086 | + irq_set_percpu_devid(irq); |
|---|
| 1087 | + irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
|---|
| 1088 | + handle_percpu_devid_fasteoi_ipi, |
|---|
| 1089 | + NULL, NULL); |
|---|
| 1090 | + break; |
|---|
| 1091 | + case 16 ... 31: |
|---|
| 981 | 1092 | irq_set_percpu_devid(irq); |
|---|
| 982 | 1093 | irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
|---|
| 983 | 1094 | handle_percpu_devid_irq, NULL, NULL); |
|---|
| 984 | | - irq_set_status_flags(irq, IRQ_NOAUTOEN); |
|---|
| 985 | | - } else { |
|---|
| 1095 | + break; |
|---|
| 1096 | + default: |
|---|
| 986 | 1097 | irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
|---|
| 987 | 1098 | handle_fasteoi_irq, NULL, NULL); |
|---|
| 988 | 1099 | irq_set_probe(irq); |
|---|
| 989 | | - irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq))); |
|---|
| 1100 | + irqd_set_single_target(irqd); |
|---|
| 1101 | + break; |
|---|
| 990 | 1102 | } |
|---|
| 1103 | + |
|---|
| 1104 | + /* Prevents SW retriggers which mess up the ACK/EOI ordering */ |
|---|
| 1105 | + irqd_set_handle_enforce_irqctx(irqd); |
|---|
| 991 | 1106 | return 0; |
|---|
| 992 | 1107 | } |
|---|
| 993 | 1108 | |
|---|
| .. | .. |
|---|
| 1000 | 1115 | unsigned long *hwirq, |
|---|
| 1001 | 1116 | unsigned int *type) |
|---|
| 1002 | 1117 | { |
|---|
| 1118 | + if (fwspec->param_count == 1 && fwspec->param[0] < 16) { |
|---|
| 1119 | + *hwirq = fwspec->param[0]; |
|---|
| 1120 | + *type = IRQ_TYPE_EDGE_RISING; |
|---|
| 1121 | + return 0; |
|---|
| 1122 | + } |
|---|
| 1123 | + |
|---|
| 1003 | 1124 | if (is_of_node(fwspec->fwnode)) { |
|---|
| 1004 | 1125 | if (fwspec->param_count < 3) |
|---|
| 1005 | 1126 | return -EINVAL; |
|---|
| 1006 | 1127 | |
|---|
| 1007 | | - /* Get the interrupt number and add 16 to skip over SGIs */ |
|---|
| 1008 | | - *hwirq = fwspec->param[1] + 16; |
|---|
| 1009 | | - |
|---|
| 1010 | | - /* |
|---|
| 1011 | | - * For SPIs, we need to add 16 more to get the GIC irq |
|---|
| 1012 | | - * ID number |
|---|
| 1013 | | - */ |
|---|
| 1014 | | - if (!fwspec->param[0]) |
|---|
| 1015 | | - *hwirq += 16; |
|---|
| 1128 | + switch (fwspec->param[0]) { |
|---|
| 1129 | + case 0: /* SPI */ |
|---|
| 1130 | + *hwirq = fwspec->param[1] + 32; |
|---|
| 1131 | + break; |
|---|
| 1132 | + case 1: /* PPI */ |
|---|
| 1133 | + *hwirq = fwspec->param[1] + 16; |
|---|
| 1134 | + break; |
|---|
| 1135 | + default: |
|---|
| 1136 | + return -EINVAL; |
|---|
| 1137 | + } |
|---|
| 1016 | 1138 | |
|---|
| 1017 | 1139 | *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; |
|---|
| 1018 | 1140 | |
|---|
| .. | .. |
|---|
| 1025 | 1147 | if(fwspec->param_count != 2) |
|---|
| 1026 | 1148 | return -EINVAL; |
|---|
| 1027 | 1149 | |
|---|
| 1150 | + if (fwspec->param[0] < 16) { |
|---|
| 1151 | + pr_err(FW_BUG "Illegal GSI%d translation request\n", |
|---|
| 1152 | + fwspec->param[0]); |
|---|
| 1153 | + return -EINVAL; |
|---|
| 1154 | + } |
|---|
| 1155 | + |
|---|
| 1028 | 1156 | *hwirq = fwspec->param[0]; |
|---|
| 1029 | 1157 | *type = fwspec->param[1]; |
|---|
| 1030 | 1158 | |
|---|
| .. | .. |
|---|
| 1033 | 1161 | } |
|---|
| 1034 | 1162 | |
|---|
| 1035 | 1163 | return -EINVAL; |
|---|
| 1036 | | -} |
|---|
| 1037 | | - |
|---|
| 1038 | | -static int gic_starting_cpu(unsigned int cpu) |
|---|
| 1039 | | -{ |
|---|
| 1040 | | - gic_cpu_init(&gic_data[0]); |
|---|
| 1041 | | - return 0; |
|---|
| 1042 | 1164 | } |
|---|
| 1043 | 1165 | |
|---|
| 1044 | 1166 | static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
|---|
| .. | .. |
|---|
| 1085 | 1207 | gic->chip.irq_mask = gic_eoimode1_mask_irq; |
|---|
| 1086 | 1208 | gic->chip.irq_eoi = gic_eoimode1_eoi_irq; |
|---|
| 1087 | 1209 | gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity; |
|---|
| 1088 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 1089 | | - gic->chip.irq_retrigger = gic_retrigger; |
|---|
| 1090 | | -#endif |
|---|
| 1091 | 1210 | } |
|---|
| 1092 | 1211 | |
|---|
| 1093 | | -#ifdef CONFIG_SMP |
|---|
| 1094 | | - if (gic == &gic_data[0]) |
|---|
| 1212 | + if (gic == &gic_data[0]) { |
|---|
| 1095 | 1213 | gic->chip.irq_set_affinity = gic_set_affinity; |
|---|
| 1096 | | -#endif |
|---|
| 1214 | + gic->chip.ipi_send_mask = gic_ipi_send_mask; |
|---|
| 1215 | + } |
|---|
| 1097 | 1216 | } |
|---|
| 1098 | 1217 | |
|---|
| 1099 | | -static int gic_init_bases(struct gic_chip_data *gic, int irq_start, |
|---|
| 1218 | +static int gic_init_bases(struct gic_chip_data *gic, |
|---|
| 1100 | 1219 | struct fwnode_handle *handle) |
|---|
| 1101 | 1220 | { |
|---|
| 1102 | | - irq_hw_number_t hwirq_base; |
|---|
| 1103 | | - int gic_irqs, irq_base, ret; |
|---|
| 1221 | + int gic_irqs, ret; |
|---|
| 1104 | 1222 | |
|---|
| 1105 | 1223 | if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { |
|---|
| 1106 | 1224 | /* Frankein-GIC without banked registers... */ |
|---|
| .. | .. |
|---|
| 1124 | 1242 | gic->raw_cpu_base + offset; |
|---|
| 1125 | 1243 | } |
|---|
| 1126 | 1244 | |
|---|
| 1127 | | - gic_set_base_accessor(gic, gic_get_percpu_base); |
|---|
| 1245 | + enable_frankengic(); |
|---|
| 1128 | 1246 | } else { |
|---|
| 1129 | 1247 | /* Normal, sane GIC... */ |
|---|
| 1130 | 1248 | WARN(gic->percpu_offset, |
|---|
| .. | .. |
|---|
| 1132 | 1250 | gic->percpu_offset); |
|---|
| 1133 | 1251 | gic->dist_base.common_base = gic->raw_dist_base; |
|---|
| 1134 | 1252 | gic->cpu_base.common_base = gic->raw_cpu_base; |
|---|
| 1135 | | - gic_set_base_accessor(gic, gic_get_common_base); |
|---|
| 1136 | 1253 | } |
|---|
| 1137 | 1254 | |
|---|
| 1138 | 1255 | /* |
|---|
| .. | .. |
|---|
| 1152 | 1269 | } else { /* Legacy support */ |
|---|
| 1153 | 1270 | /* |
|---|
| 1154 | 1271 | * For primary GICs, skip over SGIs. |
|---|
| 1155 | | - * For secondary GICs, skip over PPIs, too. |
|---|
| 1272 | + * No secondary GIC support whatsoever. |
|---|
| 1156 | 1273 | */ |
|---|
| 1157 | | - if (gic == &gic_data[0] && (irq_start & 31) > 0) { |
|---|
| 1158 | | - hwirq_base = 16; |
|---|
| 1159 | | - if (irq_start != -1) |
|---|
| 1160 | | - irq_start = (irq_start & ~31) + 16; |
|---|
| 1161 | | - } else { |
|---|
| 1162 | | - hwirq_base = 32; |
|---|
| 1163 | | - } |
|---|
| 1274 | + int irq_base; |
|---|
| 1164 | 1275 | |
|---|
| 1165 | | - gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ |
|---|
| 1276 | + gic_irqs -= 16; /* calculate # of irqs to allocate */ |
|---|
| 1166 | 1277 | |
|---|
| 1167 | | - irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, |
|---|
| 1278 | + irq_base = irq_alloc_descs(16, 16, gic_irqs, |
|---|
| 1168 | 1279 | numa_node_id()); |
|---|
| 1169 | 1280 | if (irq_base < 0) { |
|---|
| 1170 | | - WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", |
|---|
| 1171 | | - irq_start); |
|---|
| 1172 | | - irq_base = irq_start; |
|---|
| 1281 | + WARN(1, "Cannot allocate irq_descs @ IRQ16, assuming pre-allocated\n"); |
|---|
| 1282 | + irq_base = 16; |
|---|
| 1173 | 1283 | } |
|---|
| 1174 | 1284 | |
|---|
| 1175 | 1285 | gic->domain = irq_domain_add_legacy(NULL, gic_irqs, irq_base, |
|---|
| 1176 | | - hwirq_base, &gic_irq_domain_ops, gic); |
|---|
| 1286 | + 16, &gic_irq_domain_ops, gic); |
|---|
| 1177 | 1287 | } |
|---|
| 1178 | 1288 | |
|---|
| 1179 | 1289 | if (WARN_ON(!gic->domain)) { |
|---|
| .. | .. |
|---|
| 1202 | 1312 | } |
|---|
| 1203 | 1313 | |
|---|
| 1204 | 1314 | static int __init __gic_init_bases(struct gic_chip_data *gic, |
|---|
| 1205 | | - int irq_start, |
|---|
| 1206 | 1315 | struct fwnode_handle *handle) |
|---|
| 1207 | 1316 | { |
|---|
| 1208 | 1317 | char *name; |
|---|
| .. | .. |
|---|
| 1219 | 1328 | */ |
|---|
| 1220 | 1329 | for (i = 0; i < NR_GIC_CPU_IF; i++) |
|---|
| 1221 | 1330 | gic_cpu_map[i] = 0xff; |
|---|
| 1222 | | -#ifdef CONFIG_SMP |
|---|
| 1223 | | - set_smp_cross_call(gic_raise_softirq); |
|---|
| 1224 | | -#endif |
|---|
| 1225 | | - cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, |
|---|
| 1226 | | - "irqchip/arm/gic:starting", |
|---|
| 1227 | | - gic_starting_cpu, NULL); |
|---|
| 1331 | + |
|---|
| 1228 | 1332 | set_handle_irq(gic_handle_irq); |
|---|
| 1229 | 1333 | if (static_branch_likely(&supports_deactivate_key)) |
|---|
| 1230 | 1334 | pr_info("GIC: Using split EOI/Deactivate mode\n"); |
|---|
| .. | .. |
|---|
| 1238 | 1342 | gic_init_chip(gic, NULL, name, false); |
|---|
| 1239 | 1343 | } |
|---|
| 1240 | 1344 | |
|---|
| 1241 | | - ret = gic_init_bases(gic, irq_start, handle); |
|---|
| 1345 | + ret = gic_init_bases(gic, handle); |
|---|
| 1242 | 1346 | if (ret) |
|---|
| 1243 | 1347 | kfree(name); |
|---|
| 1348 | + else if (gic == &gic_data[0]) |
|---|
| 1349 | + gic_smp_init(); |
|---|
| 1244 | 1350 | |
|---|
| 1245 | 1351 | return ret; |
|---|
| 1246 | 1352 | } |
|---|
| 1247 | 1353 | |
|---|
| 1248 | | -void __init gic_init(unsigned int gic_nr, int irq_start, |
|---|
| 1249 | | - void __iomem *dist_base, void __iomem *cpu_base) |
|---|
| 1354 | +void __init gic_init(void __iomem *dist_base, void __iomem *cpu_base) |
|---|
| 1250 | 1355 | { |
|---|
| 1251 | 1356 | struct gic_chip_data *gic; |
|---|
| 1252 | | - |
|---|
| 1253 | | - if (WARN_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR)) |
|---|
| 1254 | | - return; |
|---|
| 1255 | 1357 | |
|---|
| 1256 | 1358 | /* |
|---|
| 1257 | 1359 | * Non-DT/ACPI systems won't run a hypervisor, so let's not |
|---|
| .. | .. |
|---|
| 1259 | 1361 | */ |
|---|
| 1260 | 1362 | static_branch_disable(&supports_deactivate_key); |
|---|
| 1261 | 1363 | |
|---|
| 1262 | | - gic = &gic_data[gic_nr]; |
|---|
| 1364 | + gic = &gic_data[0]; |
|---|
| 1263 | 1365 | gic->raw_dist_base = dist_base; |
|---|
| 1264 | 1366 | gic->raw_cpu_base = cpu_base; |
|---|
| 1265 | 1367 | |
|---|
| 1266 | | - __gic_init_bases(gic, irq_start, NULL); |
|---|
| 1368 | + __gic_init_bases(gic, NULL); |
|---|
| 1267 | 1369 | } |
|---|
| 1268 | 1370 | |
|---|
| 1269 | 1371 | static void gic_teardown(struct gic_chip_data *gic) |
|---|
| .. | .. |
|---|
| 1365 | 1467 | return true; |
|---|
| 1366 | 1468 | } |
|---|
| 1367 | 1469 | |
|---|
| 1470 | +static bool gic_enable_rmw_access(void *data) |
|---|
| 1471 | +{ |
|---|
| 1472 | + /* |
|---|
| 1473 | + * The EMEV2 class of machines has a broken interconnect, and |
|---|
| 1474 | + * locks up on accesses that are less than 32bit. So far, only |
|---|
| 1475 | + * the affinity setting requires it. |
|---|
| 1476 | + */ |
|---|
| 1477 | + if (of_machine_is_compatible("renesas,emev2")) { |
|---|
| 1478 | + static_branch_enable(&needs_rmw_access); |
|---|
| 1479 | + return true; |
|---|
| 1480 | + } |
|---|
| 1481 | + |
|---|
| 1482 | + return false; |
|---|
| 1483 | +} |
|---|
| 1484 | + |
|---|
| 1485 | +static const struct gic_quirk gic_quirks[] = { |
|---|
| 1486 | + { |
|---|
| 1487 | + .desc = "broken byte access", |
|---|
| 1488 | + .compatible = "arm,pl390", |
|---|
| 1489 | + .init = gic_enable_rmw_access, |
|---|
| 1490 | + }, |
|---|
| 1491 | + { }, |
|---|
| 1492 | +}; |
|---|
| 1493 | + |
|---|
| 1368 | 1494 | static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node) |
|---|
| 1369 | 1495 | { |
|---|
| 1370 | 1496 | if (!gic || !node) |
|---|
| .. | .. |
|---|
| 1380 | 1506 | |
|---|
| 1381 | 1507 | if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset)) |
|---|
| 1382 | 1508 | gic->percpu_offset = 0; |
|---|
| 1509 | + |
|---|
| 1510 | + gic_enable_of_quirks(node, gic_quirks, gic); |
|---|
| 1383 | 1511 | |
|---|
| 1384 | 1512 | return 0; |
|---|
| 1385 | 1513 | |
|---|
| .. | .. |
|---|
| 1406 | 1534 | if (ret) |
|---|
| 1407 | 1535 | return ret; |
|---|
| 1408 | 1536 | |
|---|
| 1409 | | - ret = gic_init_bases(*gic, -1, &dev->of_node->fwnode); |
|---|
| 1537 | + ret = gic_init_bases(*gic, &dev->of_node->fwnode); |
|---|
| 1410 | 1538 | if (ret) { |
|---|
| 1411 | 1539 | gic_teardown(*gic); |
|---|
| 1412 | 1540 | return ret; |
|---|
| .. | .. |
|---|
| 1466 | 1594 | if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base)) |
|---|
| 1467 | 1595 | static_branch_disable(&supports_deactivate_key); |
|---|
| 1468 | 1596 | |
|---|
| 1469 | | - ret = __gic_init_bases(gic, -1, &node->fwnode); |
|---|
| 1597 | + ret = __gic_init_bases(gic, &node->fwnode); |
|---|
| 1470 | 1598 | if (ret) { |
|---|
| 1471 | 1599 | gic_teardown(gic); |
|---|
| 1472 | 1600 | return ret; |
|---|
| .. | .. |
|---|
| 1515 | 1643 | } acpi_data __initdata; |
|---|
| 1516 | 1644 | |
|---|
| 1517 | 1645 | static int __init |
|---|
| 1518 | | -gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, |
|---|
| 1646 | +gic_acpi_parse_madt_cpu(union acpi_subtable_headers *header, |
|---|
| 1519 | 1647 | const unsigned long end) |
|---|
| 1520 | 1648 | { |
|---|
| 1521 | 1649 | struct acpi_madt_generic_interrupt *processor; |
|---|
| .. | .. |
|---|
| 1547 | 1675 | } |
|---|
| 1548 | 1676 | |
|---|
| 1549 | 1677 | /* The things you have to do to just *count* something... */ |
|---|
| 1550 | | -static int __init acpi_dummy_func(struct acpi_subtable_header *header, |
|---|
| 1678 | +static int __init acpi_dummy_func(union acpi_subtable_headers *header, |
|---|
| 1551 | 1679 | const unsigned long end) |
|---|
| 1552 | 1680 | { |
|---|
| 1553 | 1681 | return 0; |
|---|
| .. | .. |
|---|
| 1608 | 1736 | gic_set_kvm_info(&gic_v2_kvm_info); |
|---|
| 1609 | 1737 | } |
|---|
| 1610 | 1738 | |
|---|
| 1611 | | -static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, |
|---|
| 1739 | +static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, |
|---|
| 1612 | 1740 | const unsigned long end) |
|---|
| 1613 | 1741 | { |
|---|
| 1614 | 1742 | struct acpi_madt_generic_distributor *dist; |
|---|
| .. | .. |
|---|
| 1650 | 1778 | /* |
|---|
| 1651 | 1779 | * Initialize GIC instance zero (no multi-GIC support). |
|---|
| 1652 | 1780 | */ |
|---|
| 1653 | | - domain_handle = irq_domain_alloc_fwnode(gic->raw_dist_base); |
|---|
| 1781 | + domain_handle = irq_domain_alloc_fwnode(&dist->base_address); |
|---|
| 1654 | 1782 | if (!domain_handle) { |
|---|
| 1655 | 1783 | pr_err("Unable to allocate domain handle\n"); |
|---|
| 1656 | 1784 | gic_teardown(gic); |
|---|
| 1657 | 1785 | return -ENOMEM; |
|---|
| 1658 | 1786 | } |
|---|
| 1659 | 1787 | |
|---|
| 1660 | | - ret = __gic_init_bases(gic, -1, domain_handle); |
|---|
| 1788 | + ret = __gic_init_bases(gic, domain_handle); |
|---|
| 1661 | 1789 | if (ret) { |
|---|
| 1662 | 1790 | pr_err("Failed to initialise GIC\n"); |
|---|
| 1663 | 1791 | irq_domain_free_fwnode(domain_handle); |
|---|