Skip to content

Commit 55ad248

Browse files
KanjiMonsterMarc Zyngier
authored andcommitted
irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
The irq to block mapping is fixed, and interrupts from the first block will always be routed to the first parent IRQ. But the parent interrupts themselves can be routed to any available CPU. This is used by the bootloader to map the first parent interrupt to the boot CPU, regardless wether the boot CPU is the first one or the second one. When booting from the second CPU, the assumption that the first block's IRQ is mapped to the first CPU breaks, and the system hangs because interrupts do not get routed correctly. Fix this by passing the appropriate bcm6434_l1_cpu to the interrupt handler instead of the chip itself, so the handler always has the right block. Fixes: c7c42ec ("irqchips/bmips: Add bcm6345-l1 interrupt controller") Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230629072620.62527-1-jonas.gorski@gmail.com
1 parent a82f311 commit 55ad248

File tree

1 file changed

+5
-9
lines changed

1 file changed

+5
-9
lines changed

drivers/irqchip/irq-bcm6345-l1.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct bcm6345_l1_chip {
8282
};
8383

8484
struct bcm6345_l1_cpu {
85+
struct bcm6345_l1_chip *intc;
8586
void __iomem *map_base;
8687
unsigned int parent_irq;
8788
u32 enable_cache[];
@@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc,
115116

116117
static void bcm6345_l1_irq_handle(struct irq_desc *desc)
117118
{
118-
struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc);
119-
struct bcm6345_l1_cpu *cpu;
119+
struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc);
120+
struct bcm6345_l1_chip *intc = cpu->intc;
120121
struct irq_chip *chip = irq_desc_get_chip(desc);
121122
unsigned int idx;
122123

123-
#ifdef CONFIG_SMP
124-
cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
125-
#else
126-
cpu = intc->cpus[0];
127-
#endif
128-
129124
chained_irq_enter(chip, desc);
130125

131126
for (idx = 0; idx < intc->n_words; idx++) {
@@ -253,6 +248,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
253248
if (!cpu)
254249
return -ENOMEM;
255250

251+
cpu->intc = intc;
256252
cpu->map_base = ioremap(res.start, sz);
257253
if (!cpu->map_base)
258254
return -ENOMEM;
@@ -271,7 +267,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
271267
return -EINVAL;
272268
}
273269
irq_set_chained_handler_and_data(cpu->parent_irq,
274-
bcm6345_l1_irq_handle, intc);
270+
bcm6345_l1_irq_handle, cpu);
275271

276272
return 0;
277273
}

0 commit comments

Comments
 (0)