[tip: irq/drivers] irqchip/irq-realtek-rtl: Allow shuffled interrupt order
From: tip-bot2 for Markus Stockhausen
Date: Mon Jun 29 2026 - 11:29:50 EST
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 291e30ea93db78726c5d512afb620f9834c629d7
Gitweb: https://git.kernel.org/tip/291e30ea93db78726c5d512afb620f9834c629d7
Author: Markus Stockhausen <markus.stockhausen@xxxxxx>
AuthorDate: Fri, 05 Jun 2026 23:16:45 +02:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Mon, 29 Jun 2026 17:19:06 +02:00
irqchip/irq-realtek-rtl: Allow shuffled interrupt order
The driver silently assumes that the first given interrupt in
the device tree is nailed to "2". Any deviation from this will
break the driver. Fix this by storing the given interrupt
in the domain data structure and writing the proper value
to the routing register.
Signed-off-by: Markus Stockhausen <markus.stockhausen@xxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Link: https://patch.msgid.link/20260605211646.2101652-7-markus.stockhausen@xxxxxx
---
drivers/irqchip/irq-realtek-rtl.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index b256f98..96aae20 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -28,6 +28,8 @@
struct realtek_ictl_output {
struct fwnode_handle *fwnode;
struct irq_domain *domain;
+ unsigned int parent_irq;
+ unsigned int parent_hwirq;
unsigned int index;
u32 mask;
};
@@ -122,7 +124,7 @@ static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw_i
guard(raw_spinlock_irqsave)(&irq_lock);
output->mask |= BIT(hw_irq);
for_each_present_cpu(cpu)
- write_irr(cpu, hw_irq, 1);
+ write_irr(cpu, hw_irq, output->parent_hwirq - 1);
return 0;
}
@@ -175,6 +177,7 @@ static int __init realtek_setup_parents(struct device_node *node)
{
int err, parent_irq, num_parents = of_irq_count(node);
struct realtek_ictl_output *output;
+ struct irq_data *parent_data;
struct of_phandle_args oirq;
struct irq_domain *domain;
@@ -207,6 +210,12 @@ static int __init realtek_setup_parents(struct device_node *node)
goto err_out;
}
+ parent_data = irq_get_irq_data(parent_irq);
+ if (!parent_data) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
domain = irq_domain_create_linear(of_fwnode_handle(node), RTL_ICTL_NUM_INPUTS,
&irq_domain_ops, output);
if (!domain) {
@@ -217,6 +226,8 @@ static int __init realtek_setup_parents(struct device_node *node)
output->domain = domain;
output->fwnode = of_fwnode_handle(node);
output->index = 0;
+ output->parent_irq = parent_irq;
+ output->parent_hwirq = irqd_to_hwirq(parent_data);
irq_set_chained_handler_and_data(parent_irq, realtek_irq_dispatch, output);
return 0;