Skip to content

interrupt_controller: gic: Support PPIs #19860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions drivers/interrupt_controller/gic-400.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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)
Expand Down
41 changes: 27 additions & 14 deletions dts/arm/xilinx/zynqmp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
reg = <0xf9010000 0x1000>,
<0xf9020000 0x100>;
interrupt-controller;
#interrupt-cells = <3>;
#interrupt-cells = <4>;
label = "GIC";
status = "okay";
};
Expand All @@ -47,17 +47,21 @@
compatible = "xlnx,xuartps";
reg = <0xff000000 0x4c>;
status = "disabled";
interrupts = <21 0 IRQ_TYPE_LEVEL>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>;
interrupt-names = "irq_0";
label = "UART_0";
};

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 = <GIC_SPI 36 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 37 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 38 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>;
interrupt-names = "irq_0", "irq_1", "irq_2";
reg = <0xff110000 0x1000>;
label = "ttc0";
Expand All @@ -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 = <GIC_SPI 39 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 40 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 41 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>;
interrupt-names = "irq_0", "irq_1", "irq_2";
reg = <0xff120000 0x1000>;
label = "ttc1";
Expand All @@ -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 = <GIC_SPI 42 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 43 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 44 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>;
interrupt-names = "irq_0", "irq_1", "irq_2";
reg = <0xff130000 0x1000>;
label = "ttc2";
Expand All @@ -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 = <GIC_SPI 45 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 46 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>,
<GIC_SPI 47 IRQ_TYPE_LEVEL
IRQ_DEFAULT_PRIORITY>;
interrupt-names = "irq_0", "irq_1", "irq_2";
reg = <0xff140000 0x1000>;
label = "ttc3";
Expand Down
3 changes: 2 additions & 1 deletion dts/bindings/interrupt-controller/arm,gic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ properties:
required: true

interrupt-cells:
- type
- irq
- priority
- flags
- priority
3 changes: 3 additions & 0 deletions include/dt-bindings/interrupt-controller/arm-gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 17 additions & 1 deletion scripts/dts/gen_defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,20 @@ def irq_name_alias(irq, cell_name):
alias += "_" + str2ident(cell_name)
return alias

def map_arm_gic_irq_type(irq, irq_num):
# Maps ARM GIC IRQ (type)+(index) combo to linear IRQ number
if "type" not in irq.data:
err("Expected binding for {!r} to have 'type' in interrupt-cells"
.format(irq.controller))
irq_type = irq.data["type"]

if irq_type == 0: # GIC_SPI
return irq_num + 32
if irq_type == 1: # GIC_PPI
return irq_num + 16
err("Invalid interrupt type specified for {!r}"
.format(irq))

def encode_zephyr_multi_level_irq(irq, irq_num):
# See doc/reference/kernel/other/interrupts.rst for details
# on how this encoding works
Expand All @@ -493,7 +507,7 @@ def encode_zephyr_multi_level_irq(irq, irq_num):
while irq_ctrl.interrupts:
irq_num = (irq_num + 1) << 8
if "irq" not in irq_ctrl.interrupts[0].data:
err("Expected binding for {!r} to have 'irq' in *-cells"
err("Expected binding for {!r} to have 'irq' in interrupt-cells"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... had missed this one. :)

.format(irq_ctrl))
irq_num |= irq_ctrl.interrupts[0].data["irq"]
irq_ctrl = irq_ctrl.interrupts[0].controller
Expand All @@ -503,6 +517,8 @@ def encode_zephyr_multi_level_irq(irq, irq_num):
for cell_name, cell_value in irq.data.items():
ident = "IRQ_{}".format(irq_i)
if cell_name == "irq":
if "arm,gic" in irq.controller.compats:
cell_value = map_arm_gic_irq_type(irq, cell_value)
cell_value = encode_zephyr_multi_level_irq(irq, cell_value)
else:
ident += "_" + str2ident(cell_name)
Expand Down