1 From c10f2dab0f055acbb1e163d207859a47f600f811 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Thu, 29 Oct 2020 10:37:38 +0800
4 Subject: irqchip/sifive-plic: Fix chip_data access within a hierarchy
6 From: Greentime Hu <greentime.hu@sifive.com>
8 [ Upstream commit f9ac7bbd6e4540dcc6df621b9c9b6eb2e26ded1d ]
10 The plic driver crashes in plic_irq_unmask() when the interrupt is within a
11 hierarchy, as it picks the top-level chip_data instead of its local one.
13 Using irq_data_get_irq_chip_data() instead of irq_get_chip_data() solves
16 Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
17 Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
18 [maz: rewrote commit message]
19 Signed-off-by: Marc Zyngier <maz@kernel.org>
20 Reviewed-by: Anup Patel <anup@brainfault.org>
21 Reviewed-by: Atish Patra <atish.patra@wdc.com>
22 Link: https://lore.kernel.org/r/20201029023738.127472-1-greentime.hu@sifive.com
23 Signed-off-by: Sasha Levin <sashal@kernel.org>
25 drivers/irqchip/irq-sifive-plic.c | 8 ++++----
26 1 file changed, 4 insertions(+), 4 deletions(-)
28 diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
29 index 4048657ece0ac..6f432d2a5cebd 100644
30 --- a/drivers/irqchip/irq-sifive-plic.c
31 +++ b/drivers/irqchip/irq-sifive-plic.c
32 @@ -99,7 +99,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
33 struct irq_data *d, int enable)
36 - struct plic_priv *priv = irq_get_chip_data(d->irq);
37 + struct plic_priv *priv = irq_data_get_irq_chip_data(d);
39 writel(enable, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
40 for_each_cpu(cpu, mask) {
41 @@ -115,7 +115,7 @@ static void plic_irq_unmask(struct irq_data *d)
45 - struct plic_priv *priv = irq_get_chip_data(d->irq);
46 + struct plic_priv *priv = irq_data_get_irq_chip_data(d);
48 cpumask_and(&amask, &priv->lmask, cpu_online_mask);
49 cpu = cpumask_any_and(irq_data_get_affinity_mask(d),
50 @@ -127,7 +127,7 @@ static void plic_irq_unmask(struct irq_data *d)
52 static void plic_irq_mask(struct irq_data *d)
54 - struct plic_priv *priv = irq_get_chip_data(d->irq);
55 + struct plic_priv *priv = irq_data_get_irq_chip_data(d);
57 plic_irq_toggle(&priv->lmask, d, 0);
59 @@ -138,7 +138,7 @@ static int plic_set_affinity(struct irq_data *d,
63 - struct plic_priv *priv = irq_get_chip_data(d->irq);
64 + struct plic_priv *priv = irq_data_get_irq_chip_data(d);
66 cpumask_and(&amask, &priv->lmask, mask_val);