.. | .. |
---|
| 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 | * |
---|
.. | .. |
---|
50 | 47 | |
---|
51 | 48 | #include "irq-gic-common.h" |
---|
52 | 49 | |
---|
| 50 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 51 | +#include <soc/rockchip/rockchip_amp.h> |
---|
| 52 | +#endif |
---|
| 53 | + |
---|
53 | 54 | #ifdef CONFIG_ARM64 |
---|
54 | 55 | #include <asm/cpufeature.h> |
---|
55 | 56 | |
---|
.. | .. |
---|
86 | 87 | #endif |
---|
87 | 88 | struct irq_domain *domain; |
---|
88 | 89 | unsigned int gic_irqs; |
---|
89 | | -#ifdef CONFIG_GIC_NON_BANKED |
---|
90 | | - void __iomem *(*get_base)(union gic_base *); |
---|
91 | | -#endif |
---|
92 | 90 | }; |
---|
93 | 91 | |
---|
94 | 92 | #ifdef CONFIG_BL_SWITCHER |
---|
.. | .. |
---|
113 | 111 | |
---|
114 | 112 | #endif |
---|
115 | 113 | |
---|
| 114 | +static DEFINE_STATIC_KEY_FALSE(needs_rmw_access); |
---|
| 115 | + |
---|
116 | 116 | /* |
---|
117 | 117 | * The GIC mapping of CPU interfaces does not necessarily match |
---|
118 | 118 | * the logical CPU numbering. Let's use a mapping as returned |
---|
.. | .. |
---|
127 | 127 | |
---|
128 | 128 | static struct gic_kvm_info gic_v2_kvm_info; |
---|
129 | 129 | |
---|
| 130 | +static DEFINE_PER_CPU(u32, sgi_intid); |
---|
| 131 | + |
---|
130 | 132 | #ifdef CONFIG_GIC_NON_BANKED |
---|
131 | | -static void __iomem *gic_get_percpu_base(union gic_base *base) |
---|
| 133 | +static DEFINE_STATIC_KEY_FALSE(frankengic_key); |
---|
| 134 | + |
---|
| 135 | +static void enable_frankengic(void) |
---|
132 | 136 | { |
---|
133 | | - return raw_cpu_read(*base->percpu_base); |
---|
| 137 | + static_branch_enable(&frankengic_key); |
---|
134 | 138 | } |
---|
135 | 139 | |
---|
136 | | -static void __iomem *gic_get_common_base(union gic_base *base) |
---|
| 140 | +static inline void __iomem *__get_base(union gic_base *base) |
---|
137 | 141 | { |
---|
| 142 | + if (static_branch_unlikely(&frankengic_key)) |
---|
| 143 | + return raw_cpu_read(*base->percpu_base); |
---|
| 144 | + |
---|
138 | 145 | return base->common_base; |
---|
139 | 146 | } |
---|
140 | 147 | |
---|
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 | | -} |
---|
| 148 | +#define gic_data_dist_base(d) __get_base(&(d)->dist_base) |
---|
| 149 | +#define gic_data_cpu_base(d) __get_base(&(d)->cpu_base) |
---|
156 | 150 | #else |
---|
157 | 151 | #define gic_data_dist_base(d) ((d)->dist_base.common_base) |
---|
158 | 152 | #define gic_data_cpu_base(d) ((d)->cpu_base.common_base) |
---|
159 | | -#define gic_set_base_accessor(d, f) |
---|
| 153 | +#define enable_frankengic() do { } while(0) |
---|
160 | 154 | #endif |
---|
161 | 155 | |
---|
162 | 156 | static inline void __iomem *gic_dist_base(struct irq_data *d) |
---|
.. | .. |
---|
204 | 198 | |
---|
205 | 199 | static void gic_mask_irq(struct irq_data *d) |
---|
206 | 200 | { |
---|
| 201 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 202 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 203 | + return; |
---|
| 204 | +#endif |
---|
207 | 205 | gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); |
---|
208 | 206 | } |
---|
209 | 207 | |
---|
210 | 208 | static void gic_eoimode1_mask_irq(struct irq_data *d) |
---|
211 | 209 | { |
---|
| 210 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 211 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 212 | + return; |
---|
| 213 | +#endif |
---|
212 | 214 | gic_mask_irq(d); |
---|
213 | 215 | /* |
---|
214 | 216 | * When masking a forwarded interrupt, make sure it is |
---|
.. | .. |
---|
224 | 226 | |
---|
225 | 227 | static void gic_unmask_irq(struct irq_data *d) |
---|
226 | 228 | { |
---|
| 229 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 230 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 231 | + return; |
---|
| 232 | +#endif |
---|
227 | 233 | gic_poke_irq(d, GIC_DIST_ENABLE_SET); |
---|
228 | 234 | } |
---|
229 | 235 | |
---|
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 | 236 | static void gic_eoi_irq(struct irq_data *d) |
---|
240 | 237 | { |
---|
241 | | - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); |
---|
| 238 | + u32 hwirq = gic_irq(d); |
---|
| 239 | + |
---|
| 240 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 241 | + if (rockchip_amp_check_amp_irq(hwirq)) |
---|
| 242 | + return; |
---|
| 243 | +#endif |
---|
| 244 | + if (hwirq < 16) |
---|
| 245 | + hwirq = this_cpu_read(sgi_intid); |
---|
| 246 | + |
---|
| 247 | + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_EOI); |
---|
242 | 248 | } |
---|
243 | 249 | |
---|
244 | 250 | static void gic_eoimode1_eoi_irq(struct irq_data *d) |
---|
245 | 251 | { |
---|
| 252 | + u32 hwirq = gic_irq(d); |
---|
| 253 | + |
---|
| 254 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 255 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 256 | + return; |
---|
| 257 | +#endif |
---|
246 | 258 | /* Do not deactivate an IRQ forwarded to a vcpu. */ |
---|
247 | 259 | if (irqd_is_forwarded_to_vcpu(d)) |
---|
248 | 260 | return; |
---|
249 | 261 | |
---|
250 | | - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE); |
---|
| 262 | + if (hwirq < 16) |
---|
| 263 | + hwirq = this_cpu_read(sgi_intid); |
---|
| 264 | + |
---|
| 265 | + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_DEACTIVATE); |
---|
251 | 266 | } |
---|
252 | 267 | |
---|
253 | 268 | static int gic_irq_set_irqchip_state(struct irq_data *d, |
---|
.. | .. |
---|
255 | 270 | { |
---|
256 | 271 | u32 reg; |
---|
257 | 272 | |
---|
| 273 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 274 | + if (which != IRQCHIP_STATE_PENDING && |
---|
| 275 | + rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 276 | + return -EINVAL; |
---|
| 277 | +#endif |
---|
258 | 278 | switch (which) { |
---|
259 | 279 | case IRQCHIP_STATE_PENDING: |
---|
260 | 280 | reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR; |
---|
.. | .. |
---|
303 | 323 | { |
---|
304 | 324 | void __iomem *base = gic_dist_base(d); |
---|
305 | 325 | unsigned int gicirq = gic_irq(d); |
---|
| 326 | + int ret; |
---|
| 327 | + |
---|
| 328 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 329 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 330 | + return -EINVAL; |
---|
| 331 | +#endif |
---|
306 | 332 | |
---|
307 | 333 | /* Interrupt configuration for SGIs can't be changed */ |
---|
308 | 334 | if (gicirq < 16) |
---|
309 | | - return -EINVAL; |
---|
| 335 | + return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; |
---|
310 | 336 | |
---|
311 | 337 | /* SPIs have restrictions on the supported types */ |
---|
312 | 338 | if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && |
---|
313 | 339 | type != IRQ_TYPE_EDGE_RISING) |
---|
314 | 340 | return -EINVAL; |
---|
315 | 341 | |
---|
316 | | - return gic_configure_irq(gicirq, type, base, NULL); |
---|
| 342 | + ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL); |
---|
| 343 | + if (ret && gicirq < 32) { |
---|
| 344 | + /* Misconfigured PPIs are usually not fatal */ |
---|
| 345 | + pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16); |
---|
| 346 | + ret = 0; |
---|
| 347 | + } |
---|
| 348 | + |
---|
| 349 | + return ret; |
---|
317 | 350 | } |
---|
318 | 351 | |
---|
319 | 352 | static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) |
---|
320 | 353 | { |
---|
321 | 354 | /* Only interrupts on the primary GIC can be forwarded to a vcpu. */ |
---|
322 | | - if (cascading_gic_irq(d)) |
---|
| 355 | + if (cascading_gic_irq(d) || gic_irq(d) < 16) |
---|
323 | 356 | return -EINVAL; |
---|
324 | 357 | |
---|
325 | 358 | if (vcpu) |
---|
.. | .. |
---|
329 | 362 | return 0; |
---|
330 | 363 | } |
---|
331 | 364 | |
---|
332 | | -#ifdef CONFIG_SMP |
---|
333 | | -static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
---|
334 | | - bool force) |
---|
| 365 | +static int gic_retrigger(struct irq_data *data) |
---|
335 | 366 | { |
---|
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; |
---|
| 367 | + return !gic_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); |
---|
351 | 368 | } |
---|
352 | | -#endif |
---|
353 | 369 | |
---|
354 | 370 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) |
---|
355 | 371 | { |
---|
.. | .. |
---|
358 | 374 | void __iomem *cpu_base = gic_data_cpu_base(gic); |
---|
359 | 375 | |
---|
360 | 376 | do { |
---|
| 377 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 378 | + irqstat = readl_relaxed(cpu_base + GIC_CPU_ALIAS_INTACK); |
---|
| 379 | +#else |
---|
361 | 380 | irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); |
---|
| 381 | +#endif |
---|
362 | 382 | irqnr = irqstat & GICC_IAR_INT_ID_MASK; |
---|
363 | 383 | |
---|
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) { |
---|
| 384 | + if (unlikely(irqnr >= 1020)) |
---|
| 385 | + break; |
---|
| 386 | + |
---|
| 387 | + if (static_branch_likely(&supports_deactivate_key)) |
---|
372 | 388 | 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 | | - */ |
---|
| 389 | + isb(); |
---|
| 390 | + |
---|
| 391 | + /* |
---|
| 392 | + * Ensure any shared data written by the CPU sending the IPI |
---|
| 393 | + * is read after we've read the ACK register on the GIC. |
---|
| 394 | + * |
---|
| 395 | + * Pairs with the write barrier in gic_ipi_send_mask |
---|
| 396 | + */ |
---|
| 397 | + if (irqnr <= 15) { |
---|
383 | 398 | smp_rmb(); |
---|
384 | | - handle_IPI(irqnr, regs); |
---|
385 | | -#endif |
---|
386 | | - continue; |
---|
| 399 | + |
---|
| 400 | + /* |
---|
| 401 | + * The GIC encodes the source CPU in GICC_IAR, |
---|
| 402 | + * leading to the deactivation to fail if not |
---|
| 403 | + * written back as is to GICC_EOI. Stash the INTID |
---|
| 404 | + * away for gic_eoi_irq() to write back. This only |
---|
| 405 | + * works because we don't nest SGIs... |
---|
| 406 | + */ |
---|
| 407 | + this_cpu_write(sgi_intid, irqstat); |
---|
387 | 408 | } |
---|
388 | | - break; |
---|
| 409 | + |
---|
| 410 | + handle_domain_irq(gic->domain, irqnr, regs); |
---|
389 | 411 | } while (1); |
---|
390 | 412 | } |
---|
391 | 413 | |
---|
.. | .. |
---|
397 | 419 | unsigned long status; |
---|
398 | 420 | |
---|
399 | 421 | chained_irq_enter(chip, desc); |
---|
400 | | - |
---|
| 422 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 423 | + status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_ALIAS_INTACK); |
---|
| 424 | +#else |
---|
401 | 425 | status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); |
---|
402 | | - |
---|
| 426 | +#endif |
---|
403 | 427 | gic_irq = (status & GICC_IAR_INT_ID_MASK); |
---|
404 | 428 | if (gic_irq == GICC_INT_SPURIOUS) |
---|
405 | 429 | goto out; |
---|
.. | .. |
---|
421 | 445 | .irq_unmask = gic_unmask_irq, |
---|
422 | 446 | .irq_eoi = gic_eoi_irq, |
---|
423 | 447 | .irq_set_type = gic_set_type, |
---|
424 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
---|
425 | 448 | .irq_retrigger = gic_retrigger, |
---|
426 | | -#endif |
---|
427 | 449 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
---|
428 | 450 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
---|
429 | 451 | .flags = IRQCHIP_SET_TYPE_MASKED | |
---|
.. | .. |
---|
483 | 505 | bypass = readl(cpu_base + GIC_CPU_CTRL); |
---|
484 | 506 | bypass &= GICC_DIS_BYPASS_MASK; |
---|
485 | 507 | |
---|
| 508 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 509 | + writel_relaxed(0x0f, cpu_base + GIC_CPU_CTRL); |
---|
| 510 | +#else |
---|
486 | 511 | writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL); |
---|
| 512 | +#endif |
---|
487 | 513 | } |
---|
488 | 514 | |
---|
489 | 515 | |
---|
.. | .. |
---|
500 | 526 | * Set all global interrupts to this CPU only. |
---|
501 | 527 | */ |
---|
502 | 528 | cpumask = gic_get_cpumask(gic); |
---|
| 529 | + |
---|
| 530 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 531 | + for (i = 32; i < gic_irqs; i += 4) { |
---|
| 532 | + u32 maskval; |
---|
| 533 | + unsigned int j; |
---|
| 534 | + |
---|
| 535 | + maskval = 0; |
---|
| 536 | + for (j = 0; j < 4; j++) { |
---|
| 537 | + if (rockchip_amp_need_init_amp_irq(i + j)) { |
---|
| 538 | + maskval |= rockchip_amp_get_irq_cpumask(i + j) << |
---|
| 539 | + (j * 8); |
---|
| 540 | + } else { |
---|
| 541 | + maskval |= cpumask << (j * 8); |
---|
| 542 | + } |
---|
| 543 | + } |
---|
| 544 | + writel_relaxed(maskval, base + GIC_DIST_TARGET + i * 4 / 4); |
---|
| 545 | + } |
---|
| 546 | +#else |
---|
503 | 547 | cpumask |= cpumask << 8; |
---|
504 | 548 | cpumask |= cpumask << 16; |
---|
505 | 549 | for (i = 32; i < gic_irqs; i += 4) |
---|
506 | 550 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
---|
| 551 | +#endif |
---|
507 | 552 | |
---|
508 | 553 | gic_dist_config(base, gic_irqs, NULL); |
---|
509 | 554 | |
---|
| 555 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 556 | + /* set all the interrupt to non-secure state */ |
---|
| 557 | + for (i = 0; i < gic_irqs; i += 32) |
---|
| 558 | + writel_relaxed(0xffffffff, base + GIC_DIST_IGROUP + i * 4 / 32); |
---|
| 559 | + dsb(sy); |
---|
| 560 | + writel_relaxed(3, base + GIC_DIST_CTRL); |
---|
| 561 | +#else |
---|
510 | 562 | writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); |
---|
| 563 | +#endif |
---|
511 | 564 | } |
---|
512 | 565 | |
---|
513 | 566 | static int gic_cpu_init(struct gic_chip_data *gic) |
---|
.. | .. |
---|
542 | 595 | gic_cpu_map[i] &= ~cpu_mask; |
---|
543 | 596 | } |
---|
544 | 597 | |
---|
545 | | - gic_cpu_config(dist_base, NULL); |
---|
| 598 | + gic_cpu_config(dist_base, 32, NULL); |
---|
546 | 599 | |
---|
547 | 600 | writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); |
---|
548 | 601 | gic_cpu_if_up(gic); |
---|
.. | .. |
---|
608 | 661 | /* |
---|
609 | 662 | * Restores the GIC distributor registers during resume or when coming out of |
---|
610 | 663 | * 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 |
---|
| 664 | + * that occurred while the GIC was suspended is still present, it will be |
---|
| 665 | + * handled normally, but any edge interrupts that occurred will not be seen by |
---|
613 | 666 | * the GIC and need to be handled by the platform-specific wakeup source. |
---|
614 | 667 | */ |
---|
615 | 668 | void gic_dist_restore(struct gic_chip_data *gic) |
---|
.. | .. |
---|
655 | 708 | dist_base + GIC_DIST_ACTIVE_SET + i * 4); |
---|
656 | 709 | } |
---|
657 | 710 | |
---|
| 711 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 712 | + writel_relaxed(3, dist_base + GIC_DIST_CTRL); |
---|
| 713 | +#else |
---|
658 | 714 | writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); |
---|
| 715 | +#endif |
---|
659 | 716 | } |
---|
660 | 717 | |
---|
661 | 718 | void gic_cpu_save(struct gic_chip_data *gic) |
---|
.. | .. |
---|
735 | 792 | int i; |
---|
736 | 793 | |
---|
737 | 794 | 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 | 795 | switch (cmd) { |
---|
744 | 796 | case CPU_PM_ENTER: |
---|
745 | 797 | gic_cpu_save(&gic_data[i]); |
---|
.. | .. |
---|
801 | 853 | } |
---|
802 | 854 | #endif |
---|
803 | 855 | |
---|
| 856 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 857 | +/* |
---|
| 858 | + * ICDISR each bit 0 -- Secure 1--Non-Secure |
---|
| 859 | + */ |
---|
| 860 | +void gic_set_irq_secure(struct irq_data *d) |
---|
| 861 | +{ |
---|
| 862 | + u32 mask = 0; |
---|
| 863 | + void __iomem *base = gic_dist_base(d); |
---|
| 864 | + |
---|
| 865 | + base += GIC_DIST_IGROUP + ((gic_irq(d) / 32) * 4); |
---|
| 866 | + mask = readl_relaxed(base); |
---|
| 867 | + mask &= ~(1 << (gic_irq(d) % 32)); |
---|
| 868 | + writel_relaxed(mask, base); |
---|
| 869 | +} |
---|
| 870 | + |
---|
| 871 | +void gic_set_irq_priority(struct irq_data *d, u8 pri) |
---|
| 872 | +{ |
---|
| 873 | + writeb_relaxed(pri, gic_dist_base(d) + GIC_DIST_PRI + gic_irq(d)); |
---|
| 874 | +} |
---|
| 875 | +#endif |
---|
| 876 | + |
---|
804 | 877 | #ifdef CONFIG_SMP |
---|
805 | | -static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) |
---|
| 878 | +static void rmw_writeb(u8 bval, void __iomem *addr) |
---|
| 879 | +{ |
---|
| 880 | + static DEFINE_RAW_SPINLOCK(rmw_lock); |
---|
| 881 | + unsigned long offset = (unsigned long)addr & 3UL; |
---|
| 882 | + unsigned long shift = offset * 8; |
---|
| 883 | + unsigned long flags; |
---|
| 884 | + u32 val; |
---|
| 885 | + |
---|
| 886 | + raw_spin_lock_irqsave(&rmw_lock, flags); |
---|
| 887 | + |
---|
| 888 | + addr -= offset; |
---|
| 889 | + val = readl_relaxed(addr); |
---|
| 890 | + val &= ~GENMASK(shift + 7, shift); |
---|
| 891 | + val |= bval << shift; |
---|
| 892 | + writel_relaxed(val, addr); |
---|
| 893 | + |
---|
| 894 | + raw_spin_unlock_irqrestore(&rmw_lock, flags); |
---|
| 895 | +} |
---|
| 896 | + |
---|
| 897 | +static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, |
---|
| 898 | + bool force) |
---|
| 899 | +{ |
---|
| 900 | + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); |
---|
| 901 | + unsigned int cpu; |
---|
| 902 | + |
---|
| 903 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 904 | + if (rockchip_amp_check_amp_irq(gic_irq(d))) |
---|
| 905 | + return -EINVAL; |
---|
| 906 | +#endif |
---|
| 907 | + |
---|
| 908 | + if (!force) |
---|
| 909 | + cpu = cpumask_any_and(mask_val, cpu_online_mask); |
---|
| 910 | + else |
---|
| 911 | + cpu = cpumask_first(mask_val); |
---|
| 912 | + |
---|
| 913 | + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
---|
| 914 | + return -EINVAL; |
---|
| 915 | + |
---|
| 916 | + if (static_branch_unlikely(&needs_rmw_access)) |
---|
| 917 | + rmw_writeb(gic_cpu_map[cpu], reg); |
---|
| 918 | + else |
---|
| 919 | + writeb_relaxed(gic_cpu_map[cpu], reg); |
---|
| 920 | + irq_data_update_effective_affinity(d, cpumask_of(cpu)); |
---|
| 921 | + |
---|
| 922 | + return IRQ_SET_MASK_OK_DONE; |
---|
| 923 | +} |
---|
| 924 | + |
---|
| 925 | +static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) |
---|
806 | 926 | { |
---|
807 | 927 | int cpu; |
---|
808 | 928 | unsigned long flags, map = 0; |
---|
809 | 929 | |
---|
810 | 930 | if (unlikely(nr_cpu_ids == 1)) { |
---|
811 | 931 | /* Only one CPU? let's do a self-IPI... */ |
---|
812 | | - writel_relaxed(2 << 24 | irq, |
---|
| 932 | + writel_relaxed(2 << 24 | d->hwirq, |
---|
813 | 933 | gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
---|
814 | 934 | return; |
---|
815 | 935 | } |
---|
.. | .. |
---|
827 | 947 | dmb(ishst); |
---|
828 | 948 | |
---|
829 | 949 | /* this always happens on GIC0 */ |
---|
830 | | - writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
---|
831 | | - |
---|
| 950 | +#ifdef CONFIG_FIQ_GLUE |
---|
| 951 | + /* enable non-secure SGI for GIC with security extensions */ |
---|
| 952 | + writel_relaxed(map << 16 | d->hwirq | 0x8000, |
---|
| 953 | + gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
---|
| 954 | +#else |
---|
| 955 | + writel_relaxed(map << 16 | d->hwirq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
---|
| 956 | +#endif |
---|
832 | 957 | gic_unlock_irqrestore(flags); |
---|
833 | 958 | } |
---|
| 959 | + |
---|
| 960 | +static int gic_starting_cpu(unsigned int cpu) |
---|
| 961 | +{ |
---|
| 962 | + gic_cpu_init(&gic_data[0]); |
---|
| 963 | + if (IS_ENABLED(CONFIG_FIQ_GLUE)) { |
---|
| 964 | + /* set SGI to none secure state */ |
---|
| 965 | + writel_relaxed(0xffffffff, gic_data_dist_base(&gic_data[0]) + GIC_DIST_IGROUP); |
---|
| 966 | + writel_relaxed(0xf, gic_data_cpu_base(&gic_data[0]) + GIC_CPU_CTRL); |
---|
| 967 | + } |
---|
| 968 | + return 0; |
---|
| 969 | +} |
---|
| 970 | + |
---|
| 971 | +static __init void gic_smp_init(void) |
---|
| 972 | +{ |
---|
| 973 | + struct irq_fwspec sgi_fwspec = { |
---|
| 974 | + .fwnode = gic_data[0].domain->fwnode, |
---|
| 975 | + .param_count = 1, |
---|
| 976 | + }; |
---|
| 977 | + int base_sgi; |
---|
| 978 | + |
---|
| 979 | + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, |
---|
| 980 | + "irqchip/arm/gic:starting", |
---|
| 981 | + gic_starting_cpu, NULL); |
---|
| 982 | + |
---|
| 983 | + base_sgi = __irq_domain_alloc_irqs(gic_data[0].domain, -1, 8, |
---|
| 984 | + NUMA_NO_NODE, &sgi_fwspec, |
---|
| 985 | + false, NULL); |
---|
| 986 | + if (WARN_ON(base_sgi <= 0)) |
---|
| 987 | + return; |
---|
| 988 | + |
---|
| 989 | + set_smp_ipi_range(base_sgi, 8); |
---|
| 990 | +} |
---|
| 991 | +#else |
---|
| 992 | +#define gic_smp_init() do { } while(0) |
---|
| 993 | +#define gic_set_affinity NULL |
---|
| 994 | +#define gic_ipi_send_mask NULL |
---|
834 | 995 | #endif |
---|
835 | 996 | |
---|
836 | 997 | #ifdef CONFIG_BL_SWITCHER |
---|
.. | .. |
---|
903 | 1064 | gic_cpu_map[cpu] = 1 << new_cpu_id; |
---|
904 | 1065 | |
---|
905 | 1066 | /* |
---|
906 | | - * Find all the peripheral interrupts targetting the current |
---|
| 1067 | + * Find all the peripheral interrupts targeting the current |
---|
907 | 1068 | * CPU interface and migrate them to the new CPU interface. |
---|
908 | 1069 | * We skip DIST_TARGET 0 to 7 as they are read-only. |
---|
909 | 1070 | */ |
---|
.. | .. |
---|
976 | 1137 | irq_hw_number_t hw) |
---|
977 | 1138 | { |
---|
978 | 1139 | struct gic_chip_data *gic = d->host_data; |
---|
| 1140 | + struct irq_data *irqd = irq_desc_get_irq_data(irq_to_desc(irq)); |
---|
979 | 1141 | |
---|
980 | | - if (hw < 32) { |
---|
| 1142 | + switch (hw) { |
---|
| 1143 | + case 0 ... 15: |
---|
| 1144 | + irq_set_percpu_devid(irq); |
---|
| 1145 | + irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
---|
| 1146 | + handle_percpu_devid_fasteoi_ipi, |
---|
| 1147 | + NULL, NULL); |
---|
| 1148 | + break; |
---|
| 1149 | + case 16 ... 31: |
---|
981 | 1150 | irq_set_percpu_devid(irq); |
---|
982 | 1151 | irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
---|
983 | 1152 | handle_percpu_devid_irq, NULL, NULL); |
---|
984 | | - irq_set_status_flags(irq, IRQ_NOAUTOEN); |
---|
985 | | - } else { |
---|
| 1153 | + break; |
---|
| 1154 | + default: |
---|
986 | 1155 | irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, |
---|
987 | 1156 | handle_fasteoi_irq, NULL, NULL); |
---|
988 | 1157 | irq_set_probe(irq); |
---|
989 | | - irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq))); |
---|
| 1158 | + irqd_set_single_target(irqd); |
---|
| 1159 | + break; |
---|
990 | 1160 | } |
---|
| 1161 | + |
---|
| 1162 | + /* Prevents SW retriggers which mess up the ACK/EOI ordering */ |
---|
| 1163 | + irqd_set_handle_enforce_irqctx(irqd); |
---|
991 | 1164 | return 0; |
---|
992 | 1165 | } |
---|
993 | 1166 | |
---|
.. | .. |
---|
1000 | 1173 | unsigned long *hwirq, |
---|
1001 | 1174 | unsigned int *type) |
---|
1002 | 1175 | { |
---|
| 1176 | + if (fwspec->param_count == 1 && fwspec->param[0] < 16) { |
---|
| 1177 | + *hwirq = fwspec->param[0]; |
---|
| 1178 | + *type = IRQ_TYPE_EDGE_RISING; |
---|
| 1179 | + return 0; |
---|
| 1180 | + } |
---|
| 1181 | + |
---|
1003 | 1182 | if (is_of_node(fwspec->fwnode)) { |
---|
1004 | 1183 | if (fwspec->param_count < 3) |
---|
1005 | 1184 | return -EINVAL; |
---|
1006 | 1185 | |
---|
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; |
---|
| 1186 | + switch (fwspec->param[0]) { |
---|
| 1187 | + case 0: /* SPI */ |
---|
| 1188 | + *hwirq = fwspec->param[1] + 32; |
---|
| 1189 | + break; |
---|
| 1190 | + case 1: /* PPI */ |
---|
| 1191 | + *hwirq = fwspec->param[1] + 16; |
---|
| 1192 | + break; |
---|
| 1193 | + default: |
---|
| 1194 | + return -EINVAL; |
---|
| 1195 | + } |
---|
1016 | 1196 | |
---|
1017 | 1197 | *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; |
---|
1018 | 1198 | |
---|
.. | .. |
---|
1025 | 1205 | if(fwspec->param_count != 2) |
---|
1026 | 1206 | return -EINVAL; |
---|
1027 | 1207 | |
---|
| 1208 | + if (fwspec->param[0] < 16) { |
---|
| 1209 | + pr_err(FW_BUG "Illegal GSI%d translation request\n", |
---|
| 1210 | + fwspec->param[0]); |
---|
| 1211 | + return -EINVAL; |
---|
| 1212 | + } |
---|
| 1213 | + |
---|
1028 | 1214 | *hwirq = fwspec->param[0]; |
---|
1029 | 1215 | *type = fwspec->param[1]; |
---|
1030 | 1216 | |
---|
.. | .. |
---|
1033 | 1219 | } |
---|
1034 | 1220 | |
---|
1035 | 1221 | 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 | 1222 | } |
---|
1043 | 1223 | |
---|
1044 | 1224 | static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
---|
.. | .. |
---|
1085 | 1265 | gic->chip.irq_mask = gic_eoimode1_mask_irq; |
---|
1086 | 1266 | gic->chip.irq_eoi = gic_eoimode1_eoi_irq; |
---|
1087 | 1267 | 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 | 1268 | } |
---|
1092 | 1269 | |
---|
1093 | | -#ifdef CONFIG_SMP |
---|
1094 | | - if (gic == &gic_data[0]) |
---|
| 1270 | + if (gic == &gic_data[0]) { |
---|
1095 | 1271 | gic->chip.irq_set_affinity = gic_set_affinity; |
---|
1096 | | -#endif |
---|
| 1272 | + gic->chip.ipi_send_mask = gic_ipi_send_mask; |
---|
| 1273 | + } |
---|
1097 | 1274 | } |
---|
1098 | 1275 | |
---|
1099 | | -static int gic_init_bases(struct gic_chip_data *gic, int irq_start, |
---|
| 1276 | +static int gic_init_bases(struct gic_chip_data *gic, |
---|
1100 | 1277 | struct fwnode_handle *handle) |
---|
1101 | 1278 | { |
---|
1102 | | - irq_hw_number_t hwirq_base; |
---|
1103 | | - int gic_irqs, irq_base, ret; |
---|
| 1279 | + int gic_irqs, ret; |
---|
1104 | 1280 | |
---|
1105 | 1281 | if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { |
---|
1106 | 1282 | /* Frankein-GIC without banked registers... */ |
---|
.. | .. |
---|
1124 | 1300 | gic->raw_cpu_base + offset; |
---|
1125 | 1301 | } |
---|
1126 | 1302 | |
---|
1127 | | - gic_set_base_accessor(gic, gic_get_percpu_base); |
---|
| 1303 | + enable_frankengic(); |
---|
1128 | 1304 | } else { |
---|
1129 | 1305 | /* Normal, sane GIC... */ |
---|
1130 | 1306 | WARN(gic->percpu_offset, |
---|
.. | .. |
---|
1132 | 1308 | gic->percpu_offset); |
---|
1133 | 1309 | gic->dist_base.common_base = gic->raw_dist_base; |
---|
1134 | 1310 | gic->cpu_base.common_base = gic->raw_cpu_base; |
---|
1135 | | - gic_set_base_accessor(gic, gic_get_common_base); |
---|
1136 | 1311 | } |
---|
1137 | 1312 | |
---|
1138 | 1313 | /* |
---|
.. | .. |
---|
1152 | 1327 | } else { /* Legacy support */ |
---|
1153 | 1328 | /* |
---|
1154 | 1329 | * For primary GICs, skip over SGIs. |
---|
1155 | | - * For secondary GICs, skip over PPIs, too. |
---|
| 1330 | + * No secondary GIC support whatsoever. |
---|
1156 | 1331 | */ |
---|
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 | | - } |
---|
| 1332 | + int irq_base; |
---|
1164 | 1333 | |
---|
1165 | | - gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ |
---|
| 1334 | + gic_irqs -= 16; /* calculate # of irqs to allocate */ |
---|
1166 | 1335 | |
---|
1167 | | - irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, |
---|
| 1336 | + irq_base = irq_alloc_descs(16, 16, gic_irqs, |
---|
1168 | 1337 | numa_node_id()); |
---|
1169 | 1338 | 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; |
---|
| 1339 | + WARN(1, "Cannot allocate irq_descs @ IRQ16, assuming pre-allocated\n"); |
---|
| 1340 | + irq_base = 16; |
---|
1173 | 1341 | } |
---|
1174 | 1342 | |
---|
1175 | 1343 | gic->domain = irq_domain_add_legacy(NULL, gic_irqs, irq_base, |
---|
1176 | | - hwirq_base, &gic_irq_domain_ops, gic); |
---|
| 1344 | + 16, &gic_irq_domain_ops, gic); |
---|
1177 | 1345 | } |
---|
1178 | 1346 | |
---|
1179 | 1347 | if (WARN_ON(!gic->domain)) { |
---|
.. | .. |
---|
1181 | 1349 | goto error; |
---|
1182 | 1350 | } |
---|
1183 | 1351 | |
---|
| 1352 | +#ifdef CONFIG_ROCKCHIP_AMP |
---|
| 1353 | + rockchip_amp_get_gic_info(gic->gic_irqs, GIC_V2); |
---|
| 1354 | +#endif |
---|
1184 | 1355 | gic_dist_init(gic); |
---|
1185 | 1356 | ret = gic_cpu_init(gic); |
---|
1186 | 1357 | if (ret) |
---|
.. | .. |
---|
1202 | 1373 | } |
---|
1203 | 1374 | |
---|
1204 | 1375 | static int __init __gic_init_bases(struct gic_chip_data *gic, |
---|
1205 | | - int irq_start, |
---|
1206 | 1376 | struct fwnode_handle *handle) |
---|
1207 | 1377 | { |
---|
1208 | 1378 | char *name; |
---|
.. | .. |
---|
1219 | 1389 | */ |
---|
1220 | 1390 | for (i = 0; i < NR_GIC_CPU_IF; i++) |
---|
1221 | 1391 | 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); |
---|
| 1392 | + |
---|
1228 | 1393 | set_handle_irq(gic_handle_irq); |
---|
1229 | 1394 | if (static_branch_likely(&supports_deactivate_key)) |
---|
1230 | 1395 | pr_info("GIC: Using split EOI/Deactivate mode\n"); |
---|
.. | .. |
---|
1238 | 1403 | gic_init_chip(gic, NULL, name, false); |
---|
1239 | 1404 | } |
---|
1240 | 1405 | |
---|
1241 | | - ret = gic_init_bases(gic, irq_start, handle); |
---|
| 1406 | + ret = gic_init_bases(gic, handle); |
---|
1242 | 1407 | if (ret) |
---|
1243 | 1408 | kfree(name); |
---|
| 1409 | + else if (gic == &gic_data[0]) |
---|
| 1410 | + gic_smp_init(); |
---|
1244 | 1411 | |
---|
1245 | 1412 | return ret; |
---|
1246 | 1413 | } |
---|
1247 | 1414 | |
---|
1248 | | -void __init gic_init(unsigned int gic_nr, int irq_start, |
---|
1249 | | - void __iomem *dist_base, void __iomem *cpu_base) |
---|
| 1415 | +void __init gic_init(void __iomem *dist_base, void __iomem *cpu_base) |
---|
1250 | 1416 | { |
---|
1251 | 1417 | struct gic_chip_data *gic; |
---|
1252 | | - |
---|
1253 | | - if (WARN_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR)) |
---|
1254 | | - return; |
---|
1255 | 1418 | |
---|
1256 | 1419 | /* |
---|
1257 | 1420 | * Non-DT/ACPI systems won't run a hypervisor, so let's not |
---|
.. | .. |
---|
1259 | 1422 | */ |
---|
1260 | 1423 | static_branch_disable(&supports_deactivate_key); |
---|
1261 | 1424 | |
---|
1262 | | - gic = &gic_data[gic_nr]; |
---|
| 1425 | + gic = &gic_data[0]; |
---|
1263 | 1426 | gic->raw_dist_base = dist_base; |
---|
1264 | 1427 | gic->raw_cpu_base = cpu_base; |
---|
1265 | 1428 | |
---|
1266 | | - __gic_init_bases(gic, irq_start, NULL); |
---|
| 1429 | + __gic_init_bases(gic, NULL); |
---|
1267 | 1430 | } |
---|
1268 | 1431 | |
---|
1269 | 1432 | static void gic_teardown(struct gic_chip_data *gic) |
---|
.. | .. |
---|
1365 | 1528 | return true; |
---|
1366 | 1529 | } |
---|
1367 | 1530 | |
---|
| 1531 | +static bool gic_enable_rmw_access(void *data) |
---|
| 1532 | +{ |
---|
| 1533 | + /* |
---|
| 1534 | + * The EMEV2 class of machines has a broken interconnect, and |
---|
| 1535 | + * locks up on accesses that are less than 32bit. So far, only |
---|
| 1536 | + * the affinity setting requires it. |
---|
| 1537 | + */ |
---|
| 1538 | + if (of_machine_is_compatible("renesas,emev2")) { |
---|
| 1539 | + static_branch_enable(&needs_rmw_access); |
---|
| 1540 | + return true; |
---|
| 1541 | + } |
---|
| 1542 | + |
---|
| 1543 | + return false; |
---|
| 1544 | +} |
---|
| 1545 | + |
---|
| 1546 | +static const struct gic_quirk gic_quirks[] = { |
---|
| 1547 | + { |
---|
| 1548 | + .desc = "broken byte access", |
---|
| 1549 | + .compatible = "arm,pl390", |
---|
| 1550 | + .init = gic_enable_rmw_access, |
---|
| 1551 | + }, |
---|
| 1552 | + { }, |
---|
| 1553 | +}; |
---|
| 1554 | + |
---|
1368 | 1555 | static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node) |
---|
1369 | 1556 | { |
---|
1370 | 1557 | if (!gic || !node) |
---|
.. | .. |
---|
1380 | 1567 | |
---|
1381 | 1568 | if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset)) |
---|
1382 | 1569 | gic->percpu_offset = 0; |
---|
| 1570 | + |
---|
| 1571 | + gic_enable_of_quirks(node, gic_quirks, gic); |
---|
1383 | 1572 | |
---|
1384 | 1573 | return 0; |
---|
1385 | 1574 | |
---|
.. | .. |
---|
1406 | 1595 | if (ret) |
---|
1407 | 1596 | return ret; |
---|
1408 | 1597 | |
---|
1409 | | - ret = gic_init_bases(*gic, -1, &dev->of_node->fwnode); |
---|
| 1598 | + ret = gic_init_bases(*gic, &dev->of_node->fwnode); |
---|
1410 | 1599 | if (ret) { |
---|
1411 | 1600 | gic_teardown(*gic); |
---|
1412 | 1601 | return ret; |
---|
.. | .. |
---|
1466 | 1655 | if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base)) |
---|
1467 | 1656 | static_branch_disable(&supports_deactivate_key); |
---|
1468 | 1657 | |
---|
1469 | | - ret = __gic_init_bases(gic, -1, &node->fwnode); |
---|
| 1658 | + ret = __gic_init_bases(gic, &node->fwnode); |
---|
1470 | 1659 | if (ret) { |
---|
1471 | 1660 | gic_teardown(gic); |
---|
1472 | 1661 | return ret; |
---|
.. | .. |
---|
1515 | 1704 | } acpi_data __initdata; |
---|
1516 | 1705 | |
---|
1517 | 1706 | static int __init |
---|
1518 | | -gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, |
---|
| 1707 | +gic_acpi_parse_madt_cpu(union acpi_subtable_headers *header, |
---|
1519 | 1708 | const unsigned long end) |
---|
1520 | 1709 | { |
---|
1521 | 1710 | struct acpi_madt_generic_interrupt *processor; |
---|
.. | .. |
---|
1547 | 1736 | } |
---|
1548 | 1737 | |
---|
1549 | 1738 | /* The things you have to do to just *count* something... */ |
---|
1550 | | -static int __init acpi_dummy_func(struct acpi_subtable_header *header, |
---|
| 1739 | +static int __init acpi_dummy_func(union acpi_subtable_headers *header, |
---|
1551 | 1740 | const unsigned long end) |
---|
1552 | 1741 | { |
---|
1553 | 1742 | return 0; |
---|
.. | .. |
---|
1608 | 1797 | gic_set_kvm_info(&gic_v2_kvm_info); |
---|
1609 | 1798 | } |
---|
1610 | 1799 | |
---|
1611 | | -static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, |
---|
| 1800 | +static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, |
---|
1612 | 1801 | const unsigned long end) |
---|
1613 | 1802 | { |
---|
1614 | 1803 | struct acpi_madt_generic_distributor *dist; |
---|
.. | .. |
---|
1650 | 1839 | /* |
---|
1651 | 1840 | * Initialize GIC instance zero (no multi-GIC support). |
---|
1652 | 1841 | */ |
---|
1653 | | - domain_handle = irq_domain_alloc_fwnode(gic->raw_dist_base); |
---|
| 1842 | + domain_handle = irq_domain_alloc_fwnode(&dist->base_address); |
---|
1654 | 1843 | if (!domain_handle) { |
---|
1655 | 1844 | pr_err("Unable to allocate domain handle\n"); |
---|
1656 | 1845 | gic_teardown(gic); |
---|
1657 | 1846 | return -ENOMEM; |
---|
1658 | 1847 | } |
---|
1659 | 1848 | |
---|
1660 | | - ret = __gic_init_bases(gic, -1, domain_handle); |
---|
| 1849 | + ret = __gic_init_bases(gic, domain_handle); |
---|
1661 | 1850 | if (ret) { |
---|
1662 | 1851 | pr_err("Failed to initialise GIC\n"); |
---|
1663 | 1852 | irq_domain_free_fwnode(domain_handle); |
---|