Skip to content

Commit 92877b9

Browse files
author
Marc Zyngier
committed
Merge branch irq/plic-cleanups into irq/irqchip-next
* irq/plic-cleanups: : . : SiFive PLIC cleanups from Niklas Cassel: : : - Clarify some of the namings in the driver : : - Make sure S-mode interrupts are disabled when running in M-mode : . irqchip/sifive-plic: Disable S-mode IRQs if running in M-mode irqchip/sifive-plic: Improve naming scheme for per context offsets Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 0c8b522 + 098fdbc commit 92877b9

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

drivers/irqchip/irq-sifive-plic.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@
4444
* Each hart context has a vector of interrupt enable bits associated with it.
4545
* There's one bit for each interrupt source.
4646
*/
47-
#define ENABLE_BASE 0x2000
48-
#define ENABLE_PER_HART 0x80
47+
#define CONTEXT_ENABLE_BASE 0x2000
48+
#define CONTEXT_ENABLE_SIZE 0x80
4949

5050
/*
5151
* Each hart context has a set of control registers associated with it. Right
5252
* now there's only two: a source priority threshold over which the hart will
5353
* take an interrupt, and a register to claim interrupts.
5454
*/
5555
#define CONTEXT_BASE 0x200000
56-
#define CONTEXT_PER_HART 0x1000
56+
#define CONTEXT_SIZE 0x1000
5757
#define CONTEXT_THRESHOLD 0x00
5858
#define CONTEXT_CLAIM 0x04
5959

@@ -81,17 +81,21 @@ static int plic_parent_irq __ro_after_init;
8181
static bool plic_cpuhp_setup_done __ro_after_init;
8282
static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
8383

84-
static inline void plic_toggle(struct plic_handler *handler,
85-
int hwirq, int enable)
84+
static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
8685
{
87-
u32 __iomem *reg = handler->enable_base + (hwirq / 32) * sizeof(u32);
86+
u32 __iomem *reg = enable_base + (hwirq / 32) * sizeof(u32);
8887
u32 hwirq_mask = 1 << (hwirq % 32);
8988

90-
raw_spin_lock(&handler->enable_lock);
9189
if (enable)
9290
writel(readl(reg) | hwirq_mask, reg);
9391
else
9492
writel(readl(reg) & ~hwirq_mask, reg);
93+
}
94+
95+
static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
96+
{
97+
raw_spin_lock(&handler->enable_lock);
98+
__plic_toggle(handler->enable_base, hwirq, enable);
9599
raw_spin_unlock(&handler->enable_lock);
96100
}
97101

@@ -324,8 +328,18 @@ static int __init plic_init(struct device_node *node,
324328
* Skip contexts other than external interrupts for our
325329
* privilege level.
326330
*/
327-
if (parent.args[0] != RV_IRQ_EXT)
331+
if (parent.args[0] != RV_IRQ_EXT) {
332+
/* Disable S-mode enable bits if running in M-mode. */
333+
if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
334+
void __iomem *enable_base = priv->regs +
335+
CONTEXT_ENABLE_BASE +
336+
i * CONTEXT_ENABLE_SIZE;
337+
338+
for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
339+
__plic_toggle(enable_base, hwirq, 0);
340+
}
328341
continue;
342+
}
329343

330344
hartid = riscv_of_parent_hartid(parent.np);
331345
if (hartid < 0) {
@@ -361,11 +375,11 @@ static int __init plic_init(struct device_node *node,
361375

362376
cpumask_set_cpu(cpu, &priv->lmask);
363377
handler->present = true;
364-
handler->hart_base =
365-
priv->regs + CONTEXT_BASE + i * CONTEXT_PER_HART;
378+
handler->hart_base = priv->regs + CONTEXT_BASE +
379+
i * CONTEXT_SIZE;
366380
raw_spin_lock_init(&handler->enable_lock);
367-
handler->enable_base =
368-
priv->regs + ENABLE_BASE + i * ENABLE_PER_HART;
381+
handler->enable_base = priv->regs + CONTEXT_ENABLE_BASE +
382+
i * CONTEXT_ENABLE_SIZE;
369383
handler->priv = priv;
370384
done:
371385
for (hwirq = 1; hwirq <= nr_irqs; hwirq++)

0 commit comments

Comments
 (0)