Skip to content

Commit c0f182c

Browse files
committed
Merge tag 'irq-drivers-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq controller updates from Thomas Gleixner: "Update for interrupt chip drivers: - Convert the generic interrupt chip to lock guards to remove copy & pasta boilerplate code and gotos. - A new driver fot the interrupt controller in the EcoNet EN751221 MIPS SoC. - Extend the SG2042-MSI driver to support the new SG2044 SoC - Updates and cleanups for the (ancient) VT8500 driver - Improve the scalability of the ARM GICV4.1 ITS driver by utilizing node local copies a VM's interrupt translation table when possible. This results in a 12% reduction of VM IPI latency in certain workloads. - The usual cleanups and improvements all over the place" * tag 'irq-drivers-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits) irqchip/irq-pruss-intc: Simplify chained interrupt handler setup irqchip/gic-v4.1: Use local 4_1 ITS to generate VSGI irqchip/econet-en751221: Switch to of_fwnode_handle() irqchip/irq-vt8500: Switch to irq_domain_create_*() irqchip/econet-en751221: Switch to irq_domain_create_linear() irqchip/irq-vt8500: Use fewer global variables and add error handling irqchip/irq-vt8500: Use a dedicated chained handler function irqchip/irq-vt8500: Don't require 8 interrupts from a chained controller irqchip/irq-vt8500: Drop redundant copy of the device node pointer irqchip/irq-vt8500: Split up ack/mask functions irqchip/sg2042-msi: Fix wrong type cast in sg2044_msi_irq_ack() irqchip/sg2042-msi: Add the Sophgo SG2044 MSI interrupt controller irqchip/sg2042-msi: Introduce configurable chipinfo for SG2042 irqchip/sg2042-msi: Rename functions and data structures to be SG2042 agnostic dt-bindings: interrupt-controller: Add Sophgo SG2044 MSI controller genirq/generic-chip: Fix incorrect lock guard conversions genirq/generic-chip: Remove unused lock wrappers irqchip: Convert generic irqchip locking to guards gpio: mvebu: Convert generic irqchip locking to guard() ARM: orion/gpio:: Convert generic irqchip locking to guard() ...
2 parents 60c1d94 + 3e402ac commit c0f182c

28 files changed

+679
-312
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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/econet,en751221-intc.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: EcoNet EN751221 Interrupt Controller
8+
9+
maintainers:
10+
- Caleb James DeLisle <cjd@cjdns.fr>
11+
12+
description:
13+
The EcoNet EN751221 Interrupt Controller is a simple interrupt controller
14+
designed for the MIPS 34Kc MT SMP processor with 2 VPEs. Each interrupt can
15+
be routed to either VPE but not both, so to support per-CPU interrupts, a
16+
secondary IRQ number is allocated to control masking/unmasking on VPE#1. For
17+
lack of a better term we call these "shadow interrupts". The assignment of
18+
shadow interrupts is defined by the SoC integrator when wiring the interrupt
19+
lines, so they are configurable in the device tree.
20+
21+
allOf:
22+
- $ref: /schemas/interrupt-controller.yaml#
23+
24+
properties:
25+
compatible:
26+
const: econet,en751221-intc
27+
28+
reg:
29+
maxItems: 1
30+
31+
"#interrupt-cells":
32+
const: 1
33+
34+
interrupt-controller: true
35+
36+
interrupts:
37+
maxItems: 1
38+
description: Interrupt line connecting this controller to its parent.
39+
40+
econet,shadow-interrupts:
41+
$ref: /schemas/types.yaml#/definitions/uint32-matrix
42+
description:
43+
An array of interrupt number pairs where each pair represents a shadow
44+
interrupt relationship. The first number in each pair is the primary IRQ,
45+
and the second is its shadow IRQ used for VPE#1 control. For example,
46+
<8 3> means IRQ 8 is shadowed by IRQ 3, so IRQ 3 cannot be mapped, but
47+
when VPE#1 requests IRQ 8, it will manipulate the IRQ 3 mask bit.
48+
minItems: 1
49+
maxItems: 20
50+
items:
51+
items:
52+
- description: primary per-CPU IRQ
53+
- description: shadow IRQ number
54+
55+
required:
56+
- compatible
57+
- reg
58+
- interrupt-controller
59+
- "#interrupt-cells"
60+
- interrupts
61+
62+
additionalProperties: false
63+
64+
examples:
65+
- |
66+
interrupt-controller@1fb40000 {
67+
compatible = "econet,en751221-intc";
68+
reg = <0x1fb40000 0x100>;
69+
70+
interrupt-controller;
71+
#interrupt-cells = <1>;
72+
73+
interrupt-parent = <&cpuintc>;
74+
interrupts = <2>;
75+
76+
econet,shadow-interrupts = <7 2>, <8 3>, <13 12>, <30 29>;
77+
};
78+
...

Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ allOf:
1818

1919
properties:
2020
compatible:
21-
const: sophgo,sg2042-msi
21+
enum:
22+
- sophgo,sg2042-msi
23+
- sophgo,sg2044-msi
2224

2325
reg:
2426
items:

arch/arm/plat-orion/gpio.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,10 @@ static void orion_gpio_unmask_irq(struct irq_data *d)
496496
u32 reg_val;
497497
u32 mask = d->mask;
498498

499-
irq_gc_lock(gc);
499+
guard(raw_spinlock)(&gc->lock);
500500
reg_val = irq_reg_readl(gc, ct->regs.mask);
501501
reg_val |= mask;
502502
irq_reg_writel(gc, reg_val, ct->regs.mask);
503-
irq_gc_unlock(gc);
504503
}
505504

506505
static void orion_gpio_mask_irq(struct irq_data *d)
@@ -510,11 +509,10 @@ static void orion_gpio_mask_irq(struct irq_data *d)
510509
u32 mask = d->mask;
511510
u32 reg_val;
512511

513-
irq_gc_lock(gc);
512+
guard(raw_spinlock)(&gc->lock);
514513
reg_val = irq_reg_readl(gc, ct->regs.mask);
515514
reg_val &= ~mask;
516515
irq_reg_writel(gc, reg_val, ct->regs.mask);
517-
irq_gc_unlock(gc);
518516
}
519517

520518
void __init orion_gpio_init(int gpio_base, int ngpio,

drivers/gpio/gpio-mvebu.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,8 @@ static void mvebu_gpio_irq_ack(struct irq_data *d)
408408
struct mvebu_gpio_chip *mvchip = gc->private;
409409
u32 mask = d->mask;
410410

411-
irq_gc_lock(gc);
411+
guard(raw_spinlock)(&gc->lock);
412412
mvebu_gpio_write_edge_cause(mvchip, ~mask);
413-
irq_gc_unlock(gc);
414413
}
415414

416415
static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
@@ -420,10 +419,9 @@ static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
420419
struct irq_chip_type *ct = irq_data_get_chip_type(d);
421420
u32 mask = d->mask;
422421

423-
irq_gc_lock(gc);
422+
guard(raw_spinlock)(&gc->lock);
424423
ct->mask_cache_priv &= ~mask;
425424
mvebu_gpio_write_edge_mask(mvchip, ct->mask_cache_priv);
426-
irq_gc_unlock(gc);
427425
}
428426

429427
static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
@@ -433,11 +431,10 @@ static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
433431
struct irq_chip_type *ct = irq_data_get_chip_type(d);
434432
u32 mask = d->mask;
435433

436-
irq_gc_lock(gc);
434+
guard(raw_spinlock)(&gc->lock);
437435
mvebu_gpio_write_edge_cause(mvchip, ~mask);
438436
ct->mask_cache_priv |= mask;
439437
mvebu_gpio_write_edge_mask(mvchip, ct->mask_cache_priv);
440-
irq_gc_unlock(gc);
441438
}
442439

443440
static void mvebu_gpio_level_irq_mask(struct irq_data *d)
@@ -447,10 +444,9 @@ static void mvebu_gpio_level_irq_mask(struct irq_data *d)
447444
struct irq_chip_type *ct = irq_data_get_chip_type(d);
448445
u32 mask = d->mask;
449446

450-
irq_gc_lock(gc);
447+
guard(raw_spinlock)(&gc->lock);
451448
ct->mask_cache_priv &= ~mask;
452449
mvebu_gpio_write_level_mask(mvchip, ct->mask_cache_priv);
453-
irq_gc_unlock(gc);
454450
}
455451

456452
static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
@@ -460,10 +456,9 @@ static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
460456
struct irq_chip_type *ct = irq_data_get_chip_type(d);
461457
u32 mask = d->mask;
462458

463-
irq_gc_lock(gc);
459+
guard(raw_spinlock)(&gc->lock);
464460
ct->mask_cache_priv |= mask;
465461
mvebu_gpio_write_level_mask(mvchip, ct->mask_cache_priv);
466-
irq_gc_unlock(gc);
467462
}
468463

469464
/*****************************************************************************

drivers/irqchip/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ config DW_APB_ICTL
166166
select GENERIC_IRQ_CHIP
167167
select IRQ_DOMAIN_HIERARCHY
168168

169+
config ECONET_EN751221_INTC
170+
bool
171+
select GENERIC_IRQ_CHIP
172+
select IRQ_DOMAIN
173+
169174
config FARADAY_FTINTC010
170175
bool
171176
select IRQ_DOMAIN

drivers/irqchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
1010
obj-$(CONFIG_ARCH_ACTIONS) += irq-owl-sirq.o
1111
obj-$(CONFIG_DAVINCI_CP_INTC) += irq-davinci-cp-intc.o
1212
obj-$(CONFIG_EXYNOS_IRQ_COMBINER) += exynos-combiner.o
13+
obj-$(CONFIG_ECONET_EN751221_INTC) += irq-econet-en751221.o
1314
obj-$(CONFIG_FARADAY_FTINTC010) += irq-ftintc010.o
1415
obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
1516
obj-$(CONFIG_ARCH_LPC32XX) += irq-lpc32xx.o

drivers/irqchip/irq-al-fic.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,13 @@ static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
6565
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
6666
struct al_fic *fic = gc->private;
6767
enum al_fic_state new_state;
68-
int ret = 0;
6968

70-
irq_gc_lock(gc);
69+
guard(raw_spinlock)(&gc->lock);
7170

7271
if (((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) &&
7372
((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_EDGE_RISING)) {
7473
pr_debug("fic doesn't support flow type %d\n", flow_type);
75-
ret = -EINVAL;
76-
goto err;
74+
return -EINVAL;
7775
}
7876

7977
new_state = (flow_type & IRQ_TYPE_LEVEL_HIGH) ?
@@ -91,16 +89,10 @@ static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
9189
if (fic->state == AL_FIC_UNCONFIGURED) {
9290
al_fic_set_trigger(fic, gc, new_state);
9391
} else if (fic->state != new_state) {
94-
pr_debug("fic %s state already configured to %d\n",
95-
fic->name, fic->state);
96-
ret = -EINVAL;
97-
goto err;
92+
pr_debug("fic %s state already configured to %d\n", fic->name, fic->state);
93+
return -EINVAL;
9894
}
99-
100-
err:
101-
irq_gc_unlock(gc);
102-
103-
return ret;
95+
return 0;
10496
}
10597

10698
static void al_fic_irq_handler(struct irq_desc *desc)

drivers/irqchip/irq-atmel-aic.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@ static int aic_retrigger(struct irq_data *d)
7878
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
7979

8080
/* Enable interrupt on AIC5 */
81-
irq_gc_lock(gc);
81+
guard(raw_spinlock)(&gc->lock);
8282
irq_reg_writel(gc, d->mask, AT91_AIC_ISCR);
83-
irq_gc_unlock(gc);
8483

8584
return 1;
8685
}
@@ -106,30 +105,27 @@ static void aic_suspend(struct irq_data *d)
106105
{
107106
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
108107

109-
irq_gc_lock(gc);
108+
guard(raw_spinlock)(&gc->lock);
110109
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IDCR);
111110
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IECR);
112-
irq_gc_unlock(gc);
113111
}
114112

115113
static void aic_resume(struct irq_data *d)
116114
{
117115
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
118116

119-
irq_gc_lock(gc);
117+
guard(raw_spinlock)(&gc->lock);
120118
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IDCR);
121119
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IECR);
122-
irq_gc_unlock(gc);
123120
}
124121

125122
static void aic_pm_shutdown(struct irq_data *d)
126123
{
127124
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
128125

129-
irq_gc_lock(gc);
126+
guard(raw_spinlock)(&gc->lock);
130127
irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
131128
irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
132-
irq_gc_unlock(gc);
133129
}
134130
#else
135131
#define aic_suspend NULL
@@ -175,10 +171,8 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
175171
{
176172
struct irq_domain_chip_generic *dgc = d->gc;
177173
struct irq_chip_generic *gc;
178-
unsigned long flags;
179174
unsigned smr;
180-
int idx;
181-
int ret;
175+
int idx, ret;
182176

183177
if (!dgc)
184178
return -EINVAL;
@@ -194,11 +188,10 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
194188

195189
gc = dgc->gc[idx];
196190

197-
irq_gc_lock_irqsave(gc, flags);
191+
guard(raw_spinlock_irq)(&gc->lock);
198192
smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
199193
aic_common_set_priority(intspec[2], &smr);
200194
irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
201-
irq_gc_unlock_irqrestore(gc, flags);
202195

203196
return ret;
204197
}

0 commit comments

Comments
 (0)