From 7baf3f74a973fe4e1b2a3d5b359fef84fd83595e Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 18 Oct 2019 10:32:24 +0100 Subject: [PATCH] interrupt_controller: gic: Support PPIs The GIC-400 driver currently only supports SPIs because the (32) offset for the INTIDs is hard-coded in the driver. At the driver level there is no really difference between PPIs and SPIs so we can easily extend the driver to support PPIs as well. This is useful if we want to add support for the ARM Generic Timers that use INTIDs in the PPI range. SPI interrupts are in the range [0-987]. PPI interrupts are in the range [0-15]. This commit adds interrupt 'type' cell to the GIC device tree binding and changes the 'irq' cell to use interrupt type-specific index, rather than a linear IRQ number. The 'type'+'irq (index)' combo is automatically fixed up into a linear IRQ number by the scripts/dts/gen_defines.py script. Signed-off-by: Stephanos Ioannidis Signed-off-by: Carlo Caione --- drivers/interrupt_controller/gic-400.c | 8 +--- dts/arm/xilinx/zynqmp.dtsi | 41 ++++++++++++------- .../interrupt-controller/arm,gic.yaml | 3 +- .../interrupt-controller/arm-gic.h | 3 ++ 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/interrupt_controller/gic-400.c b/drivers/interrupt_controller/gic-400.c index 774aedb5118..5351b40f774 100644 --- a/drivers/interrupt_controller/gic-400.c +++ b/drivers/interrupt_controller/gic-400.c @@ -133,7 +133,6 @@ static void gic_irq_enable(struct device *dev, unsigned int irq) { int int_grp, int_off; - irq += GIC_SPI_INT_BASE; int_grp = irq / 32; int_off = irq % 32; @@ -144,7 +143,6 @@ static void gic_irq_disable(struct device *dev, unsigned int irq) { int int_grp, int_off; - irq += GIC_SPI_INT_BASE; int_grp = irq / 32; int_off = irq % 32; @@ -162,14 +160,12 @@ static void gic_irq_set_priority(struct device *dev, int int_grp, int_off; u8_t val; - irq += GIC_SPI_INT_BASE; - /* Set priority */ sys_write8(prio & 0xff, GICD_IPRIORITYRn + irq); /* Set interrupt type */ int_grp = irq / 4; - int_off = (irq % 4) * 2; + int_off = (irq % 16) * 2; val = sys_read8(GICD_ICFGRn + int_grp); val &= ~(GIC_INT_TYPE_MASK << int_off); @@ -193,7 +189,7 @@ static void gic_isr(void *arg) return; } - isr_offset = cfg->isr_table_offset + irq - GIC_SPI_INT_BASE; + isr_offset = cfg->isr_table_offset + irq; gic_isr_handle = _sw_isr_table[isr_offset].isr; if (gic_isr_handle) diff --git a/dts/arm/xilinx/zynqmp.dtsi b/dts/arm/xilinx/zynqmp.dtsi index f984d7aeaa1..453b589e876 100644 --- a/dts/arm/xilinx/zynqmp.dtsi +++ b/dts/arm/xilinx/zynqmp.dtsi @@ -28,7 +28,7 @@ reg = <0xf9010000 0x1000>, <0xf9020000 0x100>; interrupt-controller; - #interrupt-cells = <3>; + #interrupt-cells = <4>; label = "GIC"; status = "okay"; }; @@ -47,7 +47,8 @@ compatible = "xlnx,xuartps"; reg = <0xff000000 0x4c>; status = "disabled"; - interrupts = <21 0 IRQ_TYPE_LEVEL>; + interrupts = ; interrupt-names = "irq_0"; label = "UART_0"; }; @@ -55,9 +56,12 @@ ttc0: timer@ff110000 { compatible = "cdns,ttc"; status = "disabled"; - interrupts = <36 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <37 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <38 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>; + interrupts = , + , + ; interrupt-names = "irq_0", "irq_1", "irq_2"; reg = <0xff110000 0x1000>; label = "ttc0"; @@ -66,9 +70,12 @@ ttc1: timer@ff120000 { compatible = "cdns,ttc"; status = "disabled"; - interrupts = <39 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <40 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <41 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>; + interrupts = , + , + ; interrupt-names = "irq_0", "irq_1", "irq_2"; reg = <0xff120000 0x1000>; label = "ttc1"; @@ -77,9 +84,12 @@ ttc2: timer@ff130000 { compatible = "cdns,ttc"; status = "disabled"; - interrupts = <42 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <43 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <44 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>; + interrupts = , + , + ; interrupt-names = "irq_0", "irq_1", "irq_2"; reg = <0xff130000 0x1000>; label = "ttc2"; @@ -88,9 +98,12 @@ ttc3: timer@ff140000 { compatible = "cdns,ttc"; status = "disabled"; - interrupts = <45 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <46 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>, - <47 IRQ_DEFAULT_PRIORITY IRQ_TYPE_LEVEL>; + interrupts = , + , + ; interrupt-names = "irq_0", "irq_1", "irq_2"; reg = <0xff140000 0x1000>; label = "ttc3"; diff --git a/dts/bindings/interrupt-controller/arm,gic.yaml b/dts/bindings/interrupt-controller/arm,gic.yaml index 66a6f82ff8a..547504d0b5d 100644 --- a/dts/bindings/interrupt-controller/arm,gic.yaml +++ b/dts/bindings/interrupt-controller/arm,gic.yaml @@ -18,6 +18,7 @@ properties: required: true interrupt-cells: + - type - irq - - priority - flags + - priority diff --git a/include/dt-bindings/interrupt-controller/arm-gic.h b/include/dt-bindings/interrupt-controller/arm-gic.h index 5fbba6d1095..800a109e79b 100644 --- a/include/dt-bindings/interrupt-controller/arm-gic.h +++ b/include/dt-bindings/interrupt-controller/arm-gic.h @@ -18,6 +18,9 @@ #define IRQ_TYPE_LEVEL 0x0 #define IRQ_TYPE_EDGE 0x1 +#define GIC_SPI 0x0 +#define GIC_PPI 0x1 + #define IRQ_DEFAULT_PRIORITY 0xa #endif