Skip to content

Commit 91351b5

Browse files
svanheuleMarc Zyngier
authored andcommitted
irqchip/realtek-rtl: Fix off-by-one in routing
There is an offset between routing values (1..6) and the connected MIPS CPU interrupts (2..7), but no distinction was made between these two values. This issue was previously hidden during testing, because an interrupt mapping was used where for each required interrupt another (unused) routing was configured, with an offset of +1. Offset the CPU IRQ numbers by -1 to retrieve the correct routing value. Fixes: 9f3a0f3 ("irqchip: Add support for Realtek RTL838x/RTL839x interrupt controller") Signed-off-by: Sander Vanheule <sander@svanheule.net> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/177b920aa8d8610615692d0e657e509f363c85ca.1641739718.git.sander@svanheule.net
1 parent 291e79c commit 91351b5

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

drivers/irqchip/irq-realtek-rtl.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
9595
* SoC interrupts are cascaded to MIPS CPU interrupts according to the
9696
* interrupt-map in the device tree. Each SoC interrupt gets 4 bits for
9797
* the CPU interrupt in an Interrupt Routing Register. Max 32 SoC interrupts
98-
* thus go into 4 IRRs.
98+
* thus go into 4 IRRs. A routing value of '0' means the interrupt is left
99+
* disconnected. Routing values {1..15} connect to output lines {0..14}.
99100
*/
100101
static int __init map_interrupts(struct device_node *node, struct irq_domain *domain)
101102
{
@@ -134,7 +135,7 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do
134135
of_node_put(cpu_ictl);
135136

136137
cpu_int = be32_to_cpup(imap + 2);
137-
if (cpu_int > 7)
138+
if (cpu_int > 7 || cpu_int < 2)
138139
return -EINVAL;
139140

140141
if (!(mips_irqs_set & BIT(cpu_int))) {
@@ -143,7 +144,8 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do
143144
mips_irqs_set |= BIT(cpu_int);
144145
}
145146

146-
regs[(soc_int * 4) / 32] |= cpu_int << (soc_int * 4) % 32;
147+
/* Use routing values (1..6) for CPU interrupts (2..7) */
148+
regs[(soc_int * 4) / 32] |= (cpu_int - 1) << (soc_int * 4) % 32;
147149
imap += 3;
148150
}
149151

0 commit comments

Comments
 (0)