Commit 9ce06497 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Paul Walmsley

irqchip/sifive-plic: set max threshold for ignored handlers

When running in M-mode, the S-mode plic handlers are still listed in the
device tree.  Ignore them by setting the maximum threshold.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarPaul Walmsley <paul.walmsley@sifive.com>
parent 95594cb4
...@@ -244,6 +244,7 @@ static int __init plic_init(struct device_node *node, ...@@ -244,6 +244,7 @@ static int __init plic_init(struct device_node *node,
struct plic_handler *handler; struct plic_handler *handler;
irq_hw_number_t hwirq; irq_hw_number_t hwirq;
int cpu, hartid; int cpu, hartid;
u32 threshold = 0;
if (of_irq_parse_one(node, i, &parent)) { if (of_irq_parse_one(node, i, &parent)) {
pr_err("failed to parse parent for context %d.\n", i); pr_err("failed to parse parent for context %d.\n", i);
...@@ -266,10 +267,16 @@ static int __init plic_init(struct device_node *node, ...@@ -266,10 +267,16 @@ static int __init plic_init(struct device_node *node,
continue; continue;
} }
/*
* When running in M-mode we need to ignore the S-mode handler.
* Here we assume it always comes later, but that might be a
* little fragile.
*/
handler = per_cpu_ptr(&plic_handlers, cpu); handler = per_cpu_ptr(&plic_handlers, cpu);
if (handler->present) { if (handler->present) {
pr_warn("handler already present for context %d.\n", i); pr_warn("handler already present for context %d.\n", i);
continue; threshold = 0xffffffff;
goto done;
} }
handler->present = true; handler->present = true;
...@@ -279,8 +286,9 @@ static int __init plic_init(struct device_node *node, ...@@ -279,8 +286,9 @@ static int __init plic_init(struct device_node *node,
handler->enable_base = handler->enable_base =
plic_regs + ENABLE_BASE + i * ENABLE_PER_HART; plic_regs + ENABLE_BASE + i * ENABLE_PER_HART;
done:
/* priority must be > threshold to trigger an interrupt */ /* priority must be > threshold to trigger an interrupt */
writel(0, handler->hart_base + CONTEXT_THRESHOLD); writel(threshold, handler->hart_base + CONTEXT_THRESHOLD);
for (hwirq = 1; hwirq <= nr_irqs; hwirq++) for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
plic_toggle(handler, hwirq, 0); plic_toggle(handler, hwirq, 0);
nr_handlers++; nr_handlers++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment