drivers: interrupt_controller: add LiteX interrupt controller driver

Add LiteX interrupt controller driver and bindings for this device.

Signed-off-by: Filip Kokosinski <fkokosinski@internships.antmicro.com>
Signed-off-by: Mateusz Holenko <mholenko@antmicro.com>
diff --git a/CODEOWNERS b/CODEOWNERS
index 69d6d27..5f6f38b 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -122,6 +122,7 @@
 /drivers/i2s/i2s_ll_stm32*                @avisconti
 /drivers/ieee802154/                      @jukkar @tbursztyka
 /drivers/interrupt_controller/            @andrewboie
+/drivers/*/vexriscv_litex.c               @mateusz-holenko @kgugala @pgielda
 /drivers/led/                             @Mani-Sadhasivam
 /drivers/led_strip/                       @mbolivar
 /drivers/modem/                           @mike-scott
@@ -174,6 +175,7 @@
 /dts/bindings/sensor/ams*                 @alexanderwachter
 /dts/bindings/*/sifive*                   @mateusz-holenko @kgugala @pgielda @nategraff-sifive
 /dts/bindings/*/litex*                    @mateusz-holenko @kgugala @pgielda
+/dts/bindings/*/vexriscv*                 @mateusz-holenko @kgugala @pgielda
 /ext/fs/                                  @nashif @wentongwu
 /ext/hal/atmel/asf/sam/include/same70*/   @aurel32
 /ext/hal/atmel/asf/sam0/include/samr21/   @benpicco
diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt
index 93cc8d6..2ee8dea 100644
--- a/drivers/interrupt_controller/CMakeLists.txt
+++ b/drivers/interrupt_controller/CMakeLists.txt
@@ -13,3 +13,4 @@
 zephyr_sources_ifdef(CONFIG_DW_ICTL                 dw_ictl.c)
 zephyr_sources_ifdef(CONFIG_RV32M1_INTMUX           rv32m1_intmux.c)
 zephyr_sources_ifdef(CONFIG_SAM0_EIC                sam0_eic.c)
+zephyr_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ      vexriscv_litex.c)
diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig
index 3266561..80201e8 100644
--- a/drivers/interrupt_controller/Kconfig
+++ b/drivers/interrupt_controller/Kconfig
@@ -119,6 +119,12 @@
 	  Platform Level Interrupt Controller provides support
 	  for external interrupt lines defined by the RISC-V SoC;
 
+config VEXRISCV_LITEX_IRQ
+	bool "VexRiscv LiteX Interrupt controller"
+	depends on SOC_RISCV32_LITEX_VEXRISCV
+	help
+	  IRQ implementation for LiteX VexRiscv
+
 config DW_ICTL
 	bool "Designware Interrupt Controller"
 	depends on MULTI_LEVEL_INTERRUPTS
diff --git a/drivers/interrupt_controller/vexriscv_litex.c b/drivers/interrupt_controller/vexriscv_litex.c
new file mode 100644
index 0000000..a94cf13
--- /dev/null
+++ b/drivers/interrupt_controller/vexriscv_litex.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <kernel.h>
+#include <arch/cpu.h>
+#include <init.h>
+#include <irq.h>
+#include <device.h>
+#include <zephyr.h>
+#include <zephyr/types.h>
+
+#define IRQ_MASK		DT_VEXRISCV_INTC0_0_IRQ_MASK_BASE_ADDRESS
+#define IRQ_PENDING		DT_VEXRISCV_INTC0_0_IRQ_PENDING_BASE_ADDRESS
+
+#define TIMER0_IRQ		DT_LITEX_TIMER0_E0002800_IRQ_0
+#define UART0_IRQ		DT_LITEX_UART0_E0001800_IRQ_0
+static inline void vexriscv_litex_irq_setmask(u32_t mask)
+{
+	__asm__ volatile ("csrw %0, %1" :: "i"(IRQ_MASK), "r"(mask));
+}
+
+static inline u32_t vexriscv_litex_irq_getmask(void)
+{
+	u32_t mask;
+
+	__asm__ volatile ("csrr %0, %1" : "=r"(mask) : "i"(IRQ_MASK));
+	return mask;
+}
+
+static inline u32_t vexriscv_litex_irq_pending(void)
+{
+	u32_t pending;
+
+	__asm__ volatile ("csrr %0, %1" : "=r"(pending) : "i"(IRQ_PENDING));
+	return pending;
+}
+
+static inline void vexriscv_litex_irq_setie(u32_t ie)
+{
+	if (ie) {
+		__asm__ volatile ("csrrs x0, mstatus, %0"
+				:: "r"(SOC_MSTATUS_IEN));
+	} else {
+		__asm__ volatile ("csrrc x0, mstatus, %0"
+				:: "r"(SOC_MSTATUS_IEN));
+	}
+}
+
+static void vexriscv_litex_irq_handler(void *device)
+{
+	struct _isr_table_entry *ite;
+	u32_t pending, mask, irqs;
+
+	pending = vexriscv_litex_irq_pending();
+	mask = vexriscv_litex_irq_getmask();
+	irqs = pending & mask;
+
+#ifdef CONFIG_LITEX_TIMER
+	if (irqs & (1 << TIMER0_IRQ)) {
+		ite = &_sw_isr_table[TIMER0_IRQ];
+		ite->isr(ite->arg);
+	}
+#endif
+
+#ifdef CONFIG_UART_INTERRUPT_DRIVEN
+	if (irqs & (1 << UART0_IRQ)) {
+		ite = &_sw_isr_table[UART0_IRQ];
+		ite->isr(ite->arg);
+	}
+#endif
+}
+
+void z_arch_irq_enable(unsigned int irq)
+{
+	vexriscv_litex_irq_setmask(vexriscv_litex_irq_getmask() | (1 << irq));
+}
+
+void z_arch_irq_disable(unsigned int irq)
+{
+	vexriscv_litex_irq_setmask(vexriscv_litex_irq_getmask() & ~(1 << irq));
+}
+
+int z_arch_irq_is_enabled(unsigned int irq)
+{
+	return vexriscv_litex_irq_getmask() & (1 << irq);
+}
+
+static int vexriscv_litex_irq_init(struct device *dev)
+{
+	ARG_UNUSED(dev);
+	__asm__ volatile ("csrrs x0, mie, %0"
+			:: "r"((1 << RISCV_MACHINE_TIMER_IRQ)
+				| (1 << RISCV_MACHINE_EXT_IRQ)));
+	vexriscv_litex_irq_setie(1);
+	IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, 0, vexriscv_litex_irq_handler,
+			NULL, 0);
+
+	return 0;
+}
+
+SYS_INIT(vexriscv_litex_irq_init, PRE_KERNEL_2,
+		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
diff --git a/dts/bindings/interrupt-controller/vexriscv,intc0.yaml b/dts/bindings/interrupt-controller/vexriscv,intc0.yaml
new file mode 100644
index 0000000..331a196
--- /dev/null
+++ b/dts/bindings/interrupt-controller/vexriscv,intc0.yaml
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+---
+title: LiteX VexRiscV Interrupt Controller
+version: 0.1
+
+description: >
+    This binding describes LiteX VexRiscV Interrupt Controller
+
+properties:
+  compatible:
+      category: required
+      type: string
+      description: compatible strings
+      constraint: "vexriscv,intc0"
+      generation: define
+
+  reg:
+      category: required
+      type: int
+      description: mmio register space
+      generation: define
+
+  riscv,max-priority:
+      type: int
+      description: maximum interrupt priority
+      category: required
+      generation: define
+
+"#cells":
+  - irq
+  - priority
+...