summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-06-01 14:45:40 +0530
committerPalmer Dabbelt <palmerdabbelt@google.com>2020-06-09 19:11:21 -0700
commit6b7ce8927b5a4d739670d4dc0de301f2abfd9a5c (patch)
tree114283592a0541d13736f2f77cd8df5004d48df3 /arch/riscv/kernel
parentd175d699df07041befda3779f29bf7126c298730 (diff)
downloadlwn-6b7ce8927b5a4d739670d4dc0de301f2abfd9a5c.tar.gz
lwn-6b7ce8927b5a4d739670d4dc0de301f2abfd9a5c.zip
irqchip: RISC-V per-HART local interrupt controller driver
The RISC-V per-HART local interrupt controller manages software interrupts, timer interrupts, external interrupts (which are routed via the platform level interrupt controller) and other per-HART local interrupts. We add a driver for the RISC-V local interrupt controller, which eventually replaces the RISC-V architecture code, allowing for a better split between arch code and drivers. The driver is compliant with RISC-V Hart-Level Interrupt Controller DT bindings located at: Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt Co-developed-by: Palmer Dabbelt <palmer@dabbelt.com> Signed-off-by: Anup Patel <anup.patel@wdc.com> [Palmer: Cleaned up warnings] Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r--arch/riscv/kernel/irq.c33
-rw-r--r--arch/riscv/kernel/traps.c2
2 files changed, 3 insertions, 32 deletions
diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index bb0bfcd537e7..eb8777642ce6 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -7,7 +7,6 @@
#include <linux/interrupt.h>
#include <linux/irqchip.h>
-#include <linux/irqdomain.h>
#include <linux/seq_file.h>
#include <asm/smp.h>
@@ -19,39 +18,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)
asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs)
{
- struct pt_regs *old_regs;
-
- switch (regs->cause & ~CAUSE_IRQ_FLAG) {
- case RV_IRQ_TIMER:
- old_regs = set_irq_regs(regs);
- irq_enter();
- riscv_timer_interrupt();
- irq_exit();
- set_irq_regs(old_regs);
- break;
-#ifdef CONFIG_SMP
- case RV_IRQ_SOFT:
- /*
- * We only use software interrupts to pass IPIs, so if a non-SMP
- * system gets one, then we don't know what to do.
- */
- handle_IPI(regs);
- break;
-#endif
- case RV_IRQ_EXT:
- old_regs = set_irq_regs(regs);
- irq_enter();
+ if (handle_arch_irq)
handle_arch_irq(regs);
- irq_exit();
- set_irq_regs(old_regs);
- break;
- default:
- pr_alert("unexpected interrupt cause 0x%lx", regs->cause);
- BUG();
- }
}
void __init init_IRQ(void)
{
irqchip_init();
+ if (!handle_arch_irq)
+ panic("No interrupt controller found.");
}
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 5080fdf8c296..ecec1778e3a4 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -183,6 +183,4 @@ void trap_init(void)
csr_write(CSR_SCRATCH, 0);
/* Set the exception vector address */
csr_write(CSR_TVEC, &handle_exception);
- /* Enable interrupts */
- csr_write(CSR_IE, IE_SIE);
}