]> git.baikalelectronics.ru Git - kernel.git/commitdiff
irqchip/sifive-plic: set max threshold for ignored handlers
authorChristoph Hellwig <hch@lst.de>
Tue, 3 Sep 2019 09:32:20 +0000 (11:32 +0200)
committerPaul Walmsley <paul.walmsley@sifive.com>
Thu, 5 Sep 2019 08:59:55 +0000 (01:59 -0700)
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: Christoph Hellwig <hch@lst.de>
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
drivers/irqchip/irq-sifive-plic.c

index cf755964f2f8b49dde24dda29e0664317f2149b4..c72c036aea768001a19d5d702f490f005f6636cd 100644 (file)
@@ -244,6 +244,7 @@ static int __init plic_init(struct device_node *node,
                struct plic_handler *handler;
                irq_hw_number_t hwirq;
                int cpu, hartid;
+               u32 threshold = 0;
 
                if (of_irq_parse_one(node, i, &parent)) {
                        pr_err("failed to parse parent for context %d.\n", i);
@@ -266,10 +267,16 @@ static int __init plic_init(struct device_node *node,
                        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);
                if (handler->present) {
                        pr_warn("handler already present for context %d.\n", i);
-                       continue;
+                       threshold = 0xffffffff;
+                       goto done;
                }
 
                handler->present = true;
@@ -279,8 +286,9 @@ static int __init plic_init(struct device_node *node,
                handler->enable_base =
                        plic_regs + ENABLE_BASE + i * ENABLE_PER_HART;
 
+done:
                /* 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++)
                        plic_toggle(handler, hwirq, 0);
                nr_handlers++;