Unverified Commit 6b7ce892 authored by Anup Patel's avatar Anup Patel Committed by Palmer Dabbelt
Browse files

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: default avatarPalmer Dabbelt <palmer@dabbelt.com>
Signed-off-by: default avatarAnup Patel <anup.patel@wdc.com>
[Palmer: Cleaned up warnings]
Signed-off-by: default avatarPalmer Dabbelt <palmer@dabbelt.com>
parent d175d699
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ config RISCV
	select GENERIC_SMP_IDLE_THREAD
	select GENERIC_STRNCPY_FROM_USER if MMU
	select GENERIC_STRNLEN_USER if MMU
	select HANDLE_DOMAIN_IRQ
	select HAVE_ARCH_AUDITSYSCALL
	select HAVE_ARCH_KASAN if MMU && 64BIT
	select HAVE_ARCH_KGDB
+0 −2
Original line number Diff line number Diff line
@@ -10,8 +10,6 @@
#include <linux/interrupt.h>
#include <linux/linkage.h>

#define NR_IRQS         0

void riscv_timer_interrupt(void);

#include <asm-generic/irq.h>
+3 −30
Original line number Diff line number Diff line
@@ -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.");
}
+0 −2
Original line number Diff line number Diff line
@@ -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);
}
+13 −0
Original line number Diff line number Diff line
@@ -493,6 +493,19 @@ config TI_SCI_INTA_IRQCHIP
	  If you wish to use interrupt aggregator irq resources managed by the
	  TI System Controller, say Y here. Otherwise, say N.

config RISCV_INTC
	bool "RISC-V Local Interrupt Controller"
	depends on RISCV
	default y
	help
	   This enables support for the per-HART local interrupt controller
	   found in standard RISC-V systems.  The per-HART local interrupt
	   controller handles timer interrupts, software interrupts, and
	   hardware interrupts. Without a per-HART local interrupt controller,
	   a RISC-V system will be unable to handle any interrupts.

	   If you don't know what to do here, say Y.

config SIFIVE_PLIC
	bool "SiFive Platform-Level Interrupt Controller"
	depends on RISCV
Loading