Skip to content

Commit 02d4df7

Browse files
committed
Merge tag 'irq-core-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "Core: - Make affinity changes take effect immediately for interrupt threads. This reduces the impact on isolated CPUs as it pulls over the thread right away instead of doing it after the next hardware interrupt arrived. - Cleanup and improvements for the interrupt chip simulator - Deduplication of the interrupt descriptor initialization code so the sparse and non-sparse mode share more code. Drivers: - A set of conversions to platform_drivers::remove_new() which gets rid of the pointless return value. - A new driver for the Starfive JH8100 SoC - Support for Amlogic-T7 SoCs - Improvement for the interrupt handling and EOI management for the loongson interrupt controller. - The usual fixes and improvements all over the place" * tag 'irq-core-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (33 commits) irqchip/ts4800: Convert to platform_driver::remove_new() callback irqchip/stm32-exti: Convert to platform_driver::remove_new() callback irqchip/renesas-rza1: Convert to platform_driver::remove_new() callback irqchip/renesas-irqc: Convert to platform_driver::remove_new() callback irqchip/renesas-intc-irqpin: Convert to platform_driver::remove_new() callback irqchip/pruss-intc: Convert to platform_driver::remove_new() callback irqchip/mvebu-pic: Convert to platform_driver::remove_new() callback irqchip/madera: Convert to platform_driver::remove_new() callback irqchip/ls-scfg-msi: Convert to platform_driver::remove_new() callback irqchip/keystone: Convert to platform_driver::remove_new() callback irqchip/imx-irqsteer: Convert to platform_driver::remove_new() callback irqchip/imx-intmux: Convert to platform_driver::remove_new() callback irqchip/imgpdc: Convert to platform_driver::remove_new() callback irqchip: Add StarFive external interrupt controller dt-bindings: interrupt-controller: Add starfive,jh8100-intc arm64: dts: Add gpio_intc node for Amlogic-T7 SoCs irqchip/meson-gpio: Add support for Amlogic-T7 SoCs dt-bindings: interrupt-controller: Add support for Amlogic-T7 SoCs irqchip/vic: Fix a kernel-doc warning genirq: Wake interrupt threads immediately when changing affinity ...
2 parents 045395d + f7f56d5 commit 02d4df7

34 files changed

+537
-266
lines changed

Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ properties:
3636
- amlogic,meson-a1-gpio-intc
3737
- amlogic,meson-s4-gpio-intc
3838
- amlogic,c3-gpio-intc
39+
- amlogic,t7-gpio-intc
3940
- const: amlogic,meson-gpio-intc
4041

4142
reg:
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/interrupt-controller/starfive,jh8100-intc.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: StarFive External Interrupt Controller
8+
9+
description:
10+
StarFive SoC JH8100 contain a external interrupt controller. It can be used
11+
to handle high-level input interrupt signals. It also send the output
12+
interrupt signal to RISC-V PLIC.
13+
14+
maintainers:
15+
- Changhuang Liang <[email protected]>
16+
17+
properties:
18+
compatible:
19+
const: starfive,jh8100-intc
20+
21+
reg:
22+
maxItems: 1
23+
24+
clocks:
25+
description: APB clock for the interrupt controller
26+
maxItems: 1
27+
28+
resets:
29+
description: APB reset for the interrupt controller
30+
maxItems: 1
31+
32+
interrupts:
33+
maxItems: 1
34+
35+
interrupt-controller: true
36+
37+
"#interrupt-cells":
38+
const: 1
39+
40+
required:
41+
- compatible
42+
- reg
43+
- clocks
44+
- resets
45+
- interrupts
46+
- interrupt-controller
47+
- "#interrupt-cells"
48+
49+
additionalProperties: false
50+
51+
examples:
52+
- |
53+
interrupt-controller@12260000 {
54+
compatible = "starfive,jh8100-intc";
55+
reg = <0x12260000 0x10000>;
56+
clocks = <&syscrg_ne 76>;
57+
resets = <&syscrg_ne 13>;
58+
interrupts = <45>;
59+
interrupt-controller;
60+
#interrupt-cells = <1>;
61+
};

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20952,6 +20952,12 @@ F: Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
2095220952
F: drivers/phy/starfive/phy-jh7110-pcie.c
2095320953
F: drivers/phy/starfive/phy-jh7110-usb.c
2095420954

20955+
STARFIVE JH8100 EXTERNAL INTERRUPT CONTROLLER DRIVER
20956+
M: Changhuang Liang <[email protected]>
20957+
S: Supported
20958+
F: Documentation/devicetree/bindings/interrupt-controller/starfive,jh8100-intc.yaml
20959+
F: drivers/irqchip/irq-starfive-jh8100-intc.c
20960+
2095520961
STATIC BRANCH/CALL
2095620962
M: Peter Zijlstra <[email protected]>
2095720963
M: Josh Poimboeuf <[email protected]>

arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@
171171
};
172172
};
173173

174+
gpio_intc: interrupt-controller@4080 {
175+
compatible = "amlogic,t7-gpio-intc",
176+
"amlogic,meson-gpio-intc";
177+
reg = <0x0 0x4080 0x0 0x20>;
178+
interrupt-controller;
179+
#interrupt-cells = <2>;
180+
amlogic,channel-interrupts =
181+
<10 11 12 13 14 15 16 17 18 19 20 21>;
182+
};
183+
174184
uart_a: serial@78000 {
175185
compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
176186
reg = <0x0 0x78000 0x0 0x18>;

drivers/irqchip/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,17 @@ config SIFIVE_PLIC
546546
select IRQ_DOMAIN_HIERARCHY
547547
select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
548548

549+
config STARFIVE_JH8100_INTC
550+
bool "StarFive JH8100 External Interrupt Controller"
551+
depends on ARCH_STARFIVE || COMPILE_TEST
552+
default ARCH_STARFIVE
553+
select IRQ_DOMAIN_HIERARCHY
554+
help
555+
This enables support for the INTC chip found in StarFive JH8100
556+
SoC.
557+
558+
If you don't know what to do here, say Y.
559+
549560
config EXYNOS_IRQ_COMBINER
550561
bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
551562
depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST

drivers/irqchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ obj-$(CONFIG_CSKY_MPINTC) += irq-csky-mpintc.o
9696
obj-$(CONFIG_CSKY_APB_INTC) += irq-csky-apb-intc.o
9797
obj-$(CONFIG_RISCV_INTC) += irq-riscv-intc.o
9898
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
99+
obj-$(CONFIG_STARFIVE_JH8100_INTC) += irq-starfive-jh8100-intc.o
99100
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
100101
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
101102
obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o

drivers/irqchip/irq-bcm6345-l1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
242242
else if (intc->n_words != n_words)
243243
return -EINVAL;
244244

245-
cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
245+
cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, enable_cache, n_words),
246246
GFP_KERNEL);
247247
if (!cpu)
248248
return -ENOMEM;

drivers/irqchip/irq-bcm7038-l1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
249249
return -EINVAL;
250250
}
251251

252-
cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
252+
cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, mask_cache, n_words),
253253
GFP_KERNEL);
254254
if (!cpu)
255255
return -ENOMEM;

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4436,12 +4436,12 @@ static const struct irq_domain_ops its_sgi_domain_ops = {
44364436

44374437
static int its_vpe_id_alloc(void)
44384438
{
4439-
return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
4439+
return ida_alloc_max(&its_vpeid_ida, ITS_MAX_VPEID - 1, GFP_KERNEL);
44404440
}
44414441

44424442
static void its_vpe_id_free(u16 id)
44434443
{
4444-
ida_simple_remove(&its_vpeid_ida, id);
4444+
ida_free(&its_vpeid_ida, id);
44454445
}
44464446

44474447
static int its_vpe_init(struct its_vpe *vpe)

drivers/irqchip/irq-gic-v3.c

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/percpu.h>
2020
#include <linux/refcount.h>
2121
#include <linux/slab.h>
22+
#include <linux/iopoll.h>
2223

2324
#include <linux/irqchip.h>
2425
#include <linux/irqchip/arm-gic-common.h>
@@ -180,11 +181,6 @@ static enum gic_intid_range get_intid_range(struct irq_data *d)
180181
return __get_intid_range(d->hwirq);
181182
}
182183

183-
static inline unsigned int gic_irq(struct irq_data *d)
184-
{
185-
return d->hwirq;
186-
}
187-
188184
static inline bool gic_irq_in_rdist(struct irq_data *d)
189185
{
190186
switch (get_intid_range(d)) {
@@ -251,17 +247,13 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
251247

252248
static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
253249
{
254-
u32 count = 1000000; /* 1s! */
250+
u32 val;
251+
int ret;
255252

256-
while (readl_relaxed(base + GICD_CTLR) & bit) {
257-
count--;
258-
if (!count) {
259-
pr_err_ratelimited("RWP timeout, gone fishing\n");
260-
return;
261-
}
262-
cpu_relax();
263-
udelay(1);
264-
}
253+
ret = readl_relaxed_poll_timeout_atomic(base + GICD_CTLR, val, !(val & bit),
254+
1, USEC_PER_SEC);
255+
if (ret == -ETIMEDOUT)
256+
pr_err_ratelimited("RWP timeout, gone fishing\n");
265257
}
266258

267259
/* Wait for completion of a distributor change */
@@ -279,8 +271,8 @@ static void gic_redist_wait_for_rwp(void)
279271
static void gic_enable_redist(bool enable)
280272
{
281273
void __iomem *rbase;
282-
u32 count = 1000000; /* 1s! */
283274
u32 val;
275+
int ret;
284276

285277
if (gic_data.flags & FLAGS_WORKAROUND_GICR_WAKER_MSM8996)
286278
return;
@@ -301,16 +293,13 @@ static void gic_enable_redist(bool enable)
301293
return; /* No PM support in this redistributor */
302294
}
303295

304-
while (--count) {
305-
val = readl_relaxed(rbase + GICR_WAKER);
306-
if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
307-
break;
308-
cpu_relax();
309-
udelay(1);
310-
}
311-
if (!count)
296+
ret = readl_relaxed_poll_timeout_atomic(rbase + GICR_WAKER, val,
297+
enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep),
298+
1, USEC_PER_SEC);
299+
if (ret == -ETIMEDOUT) {
312300
pr_err_ratelimited("redistributor failed to %s...\n",
313301
enable ? "wakeup" : "sleep");
302+
}
314303
}
315304

316305
/*
@@ -548,7 +537,7 @@ static int gic_irq_nmi_setup(struct irq_data *d)
548537
* A secondary irq_chip should be in charge of LPI request,
549538
* it should not be possible to get there
550539
*/
551-
if (WARN_ON(gic_irq(d) >= 8192))
540+
if (WARN_ON(irqd_to_hwirq(d) >= 8192))
552541
return -EINVAL;
553542

554543
/* desc lock should already be held */
@@ -588,7 +577,7 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
588577
* A secondary irq_chip should be in charge of LPI request,
589578
* it should not be possible to get there
590579
*/
591-
if (WARN_ON(gic_irq(d) >= 8192))
580+
if (WARN_ON(irqd_to_hwirq(d) >= 8192))
592581
return;
593582

594583
/* desc lock should already be held */
@@ -626,7 +615,7 @@ static bool gic_arm64_erratum_2941627_needed(struct irq_data *d)
626615

627616
static void gic_eoi_irq(struct irq_data *d)
628617
{
629-
write_gicreg(gic_irq(d), ICC_EOIR1_EL1);
618+
write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);
630619
isb();
631620

632621
if (gic_arm64_erratum_2941627_needed(d)) {
@@ -646,19 +635,19 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d)
646635
* No need to deactivate an LPI, or an interrupt that
647636
* is is getting forwarded to a vcpu.
648637
*/
649-
if (gic_irq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d))
638+
if (irqd_to_hwirq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d))
650639
return;
651640

652641
if (!gic_arm64_erratum_2941627_needed(d))
653-
gic_write_dir(gic_irq(d));
642+
gic_write_dir(irqd_to_hwirq(d));
654643
else
655644
gic_poke_irq(d, GICD_ICACTIVER);
656645
}
657646

658647
static int gic_set_type(struct irq_data *d, unsigned int type)
659648
{
649+
irq_hw_number_t irq = irqd_to_hwirq(d);
660650
enum gic_intid_range range;
661-
unsigned int irq = gic_irq(d);
662651
void __iomem *base;
663652
u32 offset, index;
664653
int ret;
@@ -684,7 +673,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
684673
ret = gic_configure_irq(index, type, base + offset, NULL);
685674
if (ret && (range == PPI_RANGE || range == EPPI_RANGE)) {
686675
/* Misconfigured PPIs are usually not fatal */
687-
pr_warn("GIC: PPI INTID%d is secure or misconfigured\n", irq);
676+
pr_warn("GIC: PPI INTID%ld is secure or misconfigured\n", irq);
688677
ret = 0;
689678
}
690679

drivers/irqchip/irq-gic.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,6 @@ static inline void __iomem *gic_cpu_base(struct irq_data *d)
162162
return gic_data_cpu_base(gic_data);
163163
}
164164

165-
static inline unsigned int gic_irq(struct irq_data *d)
166-
{
167-
return d->hwirq;
168-
}
169-
170165
static inline bool cascading_gic_irq(struct irq_data *d)
171166
{
172167
void *data = irq_data_get_irq_handler_data(d);
@@ -183,14 +178,16 @@ static inline bool cascading_gic_irq(struct irq_data *d)
183178
*/
184179
static void gic_poke_irq(struct irq_data *d, u32 offset)
185180
{
186-
u32 mask = 1 << (gic_irq(d) % 32);
187-
writel_relaxed(mask, gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4);
181+
u32 mask = 1 << (irqd_to_hwirq(d) % 32);
182+
183+
writel_relaxed(mask, gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4);
188184
}
189185

190186
static int gic_peek_irq(struct irq_data *d, u32 offset)
191187
{
192-
u32 mask = 1 << (gic_irq(d) % 32);
193-
return !!(readl_relaxed(gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4) & mask);
188+
u32 mask = 1 << (irqd_to_hwirq(d) % 32);
189+
190+
return !!(readl_relaxed(gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4) & mask);
194191
}
195192

196193
static void gic_mask_irq(struct irq_data *d)
@@ -220,7 +217,7 @@ static void gic_unmask_irq(struct irq_data *d)
220217

221218
static void gic_eoi_irq(struct irq_data *d)
222219
{
223-
u32 hwirq = gic_irq(d);
220+
irq_hw_number_t hwirq = irqd_to_hwirq(d);
224221

225222
if (hwirq < 16)
226223
hwirq = this_cpu_read(sgi_intid);
@@ -230,7 +227,7 @@ static void gic_eoi_irq(struct irq_data *d)
230227

231228
static void gic_eoimode1_eoi_irq(struct irq_data *d)
232229
{
233-
u32 hwirq = gic_irq(d);
230+
irq_hw_number_t hwirq = irqd_to_hwirq(d);
234231

235232
/* Do not deactivate an IRQ forwarded to a vcpu. */
236233
if (irqd_is_forwarded_to_vcpu(d))
@@ -293,8 +290,8 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
293290

294291
static int gic_set_type(struct irq_data *d, unsigned int type)
295292
{
293+
irq_hw_number_t gicirq = irqd_to_hwirq(d);
296294
void __iomem *base = gic_dist_base(d);
297-
unsigned int gicirq = gic_irq(d);
298295
int ret;
299296

300297
/* Interrupt configuration for SGIs can't be changed */
@@ -309,7 +306,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
309306
ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
310307
if (ret && gicirq < 32) {
311308
/* Misconfigured PPIs are usually not fatal */
312-
pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
309+
pr_warn("GIC: PPI%ld is secure or misconfigured\n", gicirq - 16);
313310
ret = 0;
314311
}
315312

@@ -319,7 +316,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
319316
static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
320317
{
321318
/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
322-
if (cascading_gic_irq(d) || gic_irq(d) < 16)
319+
if (cascading_gic_irq(d) || irqd_to_hwirq(d) < 16)
323320
return -EINVAL;
324321

325322
if (vcpu)
@@ -796,7 +793,7 @@ static void rmw_writeb(u8 bval, void __iomem *addr)
796793
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
797794
bool force)
798795
{
799-
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
796+
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + irqd_to_hwirq(d);
800797
struct gic_chip_data *gic = irq_data_get_irq_chip_data(d);
801798
unsigned int cpu;
802799

0 commit comments

Comments
 (0)