Skip to content

Commit 60c1d94

Browse files
committed
Merge tag 'irq-core-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner: "Updates for the generic interrupt subsystem core code: - Address a long standing subtle problem in the CPU hotplug code for affinity-managed interrupts. Affinity-managed interrupts are shut down by the core code when the last CPU in the affinity set goes offline and started up again when the first CPU in the affinity set becomes online again. This unfortunately does not take into account whether an interrupt has been disabled before the last CPU goes offline and starts up the interrupt unconditionally when the first CPU becomes online again. That's obviously not what drivers expect. Address this by preserving the disabled state for affinity-managed interrupts accross these CPU hotplug operations. All non-managed interrupts are not affected by this because startup/shutdown is coupled to request/free_irq() which obviously has to reset state. - Support three-cell scheme interrupts to allow GPIO drivers to specify interrupts from an already existing scheme - Switch the interrupt subsystem core to lock guards. This gets rid of quite some copy & pasta boilerplate code all over the place. - The usual small cleanups and improvements all over the place" * tag 'irq-core-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (59 commits) genirq/irqdesc: Remove double locking in hwirq_show() genirq: Retain disable depth for managed interrupts across CPU hotplug genirq: Bump the size of the local variable for sprintf() genirq/manage: Use the correct lock guard in irq_set_irq_wake() genirq: Consistently use '%u' format specifier for unsigned int variables genirq: Ensure flags in lock guard is consistently initialized genirq: Fix inverted condition in handle_nested_irq() genirq/cpuhotplug: Fix up lock guards conversion brainf..t genirq: Use scoped_guard() to shut clang up genirq: Remove unused remove_percpu_irq() genirq: Remove irq_[get|put]_desc*() genirq/manage: Rework irq_set_irqchip_state() genirq/manage: Rework irq_get_irqchip_state() genirq/manage: Rework teardown_percpu_nmi() genirq/manage: Rework prepare_percpu_nmi() genirq/manage: Rework disable_percpu_irq() genirq/manage: Rework irq_percpu_is_enabled() genirq/manage: Rework enable_percpu_irq() genirq/manage: Rework irq_set_parent() genirq/manage: Rework can_request_irq() ...
2 parents 0c14940 + a510bb8 commit 60c1d94

File tree

15 files changed

+1026
-1380
lines changed

15 files changed

+1026
-1380
lines changed

include/linux/interrupt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ extern irqreturn_t no_action(int cpl, void *dev_id);
140140
/*
141141
* If a (PCI) device interrupt is not connected we set dev->irq to
142142
* IRQ_NOTCONNECTED. This causes request_irq() to fail with -ENOTCONN, so we
143-
* can distingiush that case from other error returns.
143+
* can distinguish that case from other error returns.
144144
*
145145
* 0x80000000 is guaranteed to be outside the available range of interrupts
146146
* and easy to distinguish from other possible incorrect values.

include/linux/irq.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,6 @@ enum {
597597

598598
struct irqaction;
599599
extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
600-
extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
601600

602601
#ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE
603602
extern void irq_cpu_online(void);
@@ -700,7 +699,7 @@ extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
700699
extern int noirqdebug_setup(char *str);
701700

702701
/* Checks whether the interrupt can be requested by request_irq(): */
703-
extern int can_request_irq(unsigned int irq, unsigned long irqflags);
702+
extern bool can_request_irq(unsigned int irq, unsigned long irqflags);
704703

705704
/* Dummy irq-chip implementations: */
706705
extern struct irq_chip no_irq_chip;

include/linux/irqdomain.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -571,16 +571,16 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
571571
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
572572
const u32 *intspec, unsigned int intsize,
573573
irq_hw_number_t *out_hwirq, unsigned int *out_type);
574-
575-
int irq_domain_translate_twocell(struct irq_domain *d,
576-
struct irq_fwspec *fwspec,
577-
unsigned long *out_hwirq,
578-
unsigned int *out_type);
579-
580-
int irq_domain_translate_onecell(struct irq_domain *d,
581-
struct irq_fwspec *fwspec,
582-
unsigned long *out_hwirq,
583-
unsigned int *out_type);
574+
int irq_domain_xlate_twothreecell(struct irq_domain *d, struct device_node *ctrlr,
575+
const u32 *intspec, unsigned int intsize,
576+
irq_hw_number_t *out_hwirq, unsigned int *out_type);
577+
578+
int irq_domain_translate_onecell(struct irq_domain *d, struct irq_fwspec *fwspec,
579+
unsigned long *out_hwirq, unsigned int *out_type);
580+
int irq_domain_translate_twocell(struct irq_domain *d, struct irq_fwspec *fwspec,
581+
unsigned long *out_hwirq, unsigned int *out_type);
582+
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec,
583+
unsigned long *out_hwirq, unsigned int *out_type);
584584

585585
/* IPI functions */
586586
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);

kernel/irq/autoprobe.c

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ unsigned long probe_irq_on(void)
4343
* flush such a longstanding irq before considering it as spurious.
4444
*/
4545
for_each_irq_desc_reverse(i, desc) {
46-
raw_spin_lock_irq(&desc->lock);
46+
guard(raw_spinlock_irq)(&desc->lock);
4747
if (!desc->action && irq_settings_can_probe(desc)) {
4848
/*
4949
* Some chips need to know about probing in
5050
* progress:
5151
*/
5252
if (desc->irq_data.chip->irq_set_type)
53-
desc->irq_data.chip->irq_set_type(&desc->irq_data,
54-
IRQ_TYPE_PROBE);
53+
desc->irq_data.chip->irq_set_type(&desc->irq_data, IRQ_TYPE_PROBE);
5554
irq_activate_and_startup(desc, IRQ_NORESEND);
5655
}
57-
raw_spin_unlock_irq(&desc->lock);
5856
}
5957

6058
/* Wait for longstanding interrupts to trigger. */
@@ -66,13 +64,12 @@ unsigned long probe_irq_on(void)
6664
* happened in the previous stage, it may have masked itself)
6765
*/
6866
for_each_irq_desc_reverse(i, desc) {
69-
raw_spin_lock_irq(&desc->lock);
67+
guard(raw_spinlock_irq)(&desc->lock);
7068
if (!desc->action && irq_settings_can_probe(desc)) {
7169
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
7270
if (irq_activate_and_startup(desc, IRQ_NORESEND))
7371
desc->istate |= IRQS_PENDING;
7472
}
75-
raw_spin_unlock_irq(&desc->lock);
7673
}
7774

7875
/*
@@ -84,18 +81,16 @@ unsigned long probe_irq_on(void)
8481
* Now filter out any obviously spurious interrupts
8582
*/
8683
for_each_irq_desc(i, desc) {
87-
raw_spin_lock_irq(&desc->lock);
88-
84+
guard(raw_spinlock_irq)(&desc->lock);
8985
if (desc->istate & IRQS_AUTODETECT) {
9086
/* It triggered already - consider it spurious. */
9187
if (!(desc->istate & IRQS_WAITING)) {
9288
desc->istate &= ~IRQS_AUTODETECT;
9389
irq_shutdown_and_deactivate(desc);
94-
} else
95-
if (i < 32)
96-
mask |= 1 << i;
90+
} else if (i < 32) {
91+
mask |= 1 << i;
92+
}
9793
}
98-
raw_spin_unlock_irq(&desc->lock);
9994
}
10095

10196
return mask;
@@ -121,15 +116,14 @@ unsigned int probe_irq_mask(unsigned long val)
121116
int i;
122117

123118
for_each_irq_desc(i, desc) {
124-
raw_spin_lock_irq(&desc->lock);
119+
guard(raw_spinlock_irq)(&desc->lock);
125120
if (desc->istate & IRQS_AUTODETECT) {
126121
if (i < 16 && !(desc->istate & IRQS_WAITING))
127122
mask |= 1 << i;
128123

129124
desc->istate &= ~IRQS_AUTODETECT;
130125
irq_shutdown_and_deactivate(desc);
131126
}
132-
raw_spin_unlock_irq(&desc->lock);
133127
}
134128
mutex_unlock(&probing_active);
135129

@@ -160,8 +154,7 @@ int probe_irq_off(unsigned long val)
160154
struct irq_desc *desc;
161155

162156
for_each_irq_desc(i, desc) {
163-
raw_spin_lock_irq(&desc->lock);
164-
157+
guard(raw_spinlock_irq)(&desc->lock);
165158
if (desc->istate & IRQS_AUTODETECT) {
166159
if (!(desc->istate & IRQS_WAITING)) {
167160
if (!nr_of_irqs)
@@ -171,7 +164,6 @@ int probe_irq_off(unsigned long val)
171164
desc->istate &= ~IRQS_AUTODETECT;
172165
irq_shutdown_and_deactivate(desc);
173166
}
174-
raw_spin_unlock_irq(&desc->lock);
175167
}
176168
mutex_unlock(&probing_active);
177169

0 commit comments

Comments
 (0)