Skip to content

Commit 020a0d3

Browse files
Quang Lekartben
authored andcommitted
drivers: interrupt controller: Add support for RZ/N2L
Add interrupt controller driver support for RZ/N2L Signed-off-by: Quang Le <[email protected]> Signed-off-by: Nhut Nguyen <[email protected]>
1 parent 6a00473 commit 020a0d3

File tree

5 files changed

+259
-13
lines changed

5 files changed

+259
-13
lines changed

drivers/interrupt_controller/intc_renesas_rz_ext_irq.c

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Renesas Electronics Corporation
2+
* Copyright (c) 2024-2025 Renesas Electronics Corporation
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -9,12 +9,17 @@
99
#include <zephyr/device.h>
1010
#include <zephyr/devicetree.h>
1111
#include <zephyr/kernel.h>
12-
#include <zephyr/irq.h>
1312
#include <zephyr/drivers/pinctrl.h>
13+
#include <zephyr/irq.h>
1414
#include <zephyr/logging/log.h>
15+
#if defined(CONFIG_SOC_SERIES_RZG3S)
1516
#include <instances/rzg/r_intc_irq.h>
1617
#include <instances/rzg/r_intc_nmi.h>
18+
#elif defined(CONFIG_SOC_SERIES_RZN2L)
19+
#include <instances/rzn/r_icu.h>
20+
#endif /* CONFIG_SOC_SERIES_* */
1721
#include <zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h>
22+
#include <zephyr/dt-bindings/interrupt-controller/arm-gic.h>
1823

1924
LOG_MODULE_REGISTER(rz_ext_irq, CONFIG_INTC_LOG_LEVEL);
2025

@@ -31,8 +36,12 @@ struct intc_rz_ext_irq_data {
3136
};
3237

3338
/* FSP interruption handlers. */
39+
#if defined(CONFIG_SOC_SERIES_RZG3S)
3440
void r_intc_irq_isr(void);
3541
void r_intc_nmi_isr(void);
42+
#elif defined(CONFIG_SOC_SERIES_RZN2L)
43+
void r_icu_isr(void);
44+
#endif /* CONFIG_SOC_SERIES_* */
3645

3746
int intc_rz_ext_irq_enable(const struct device *dev)
3847
{
@@ -74,6 +83,29 @@ int intc_rz_ext_irq_set_callback(const struct device *dev, intc_rz_ext_irq_callb
7483
return 0;
7584
}
7685

86+
int intc_rz_ext_irq_set_type(const struct device *dev, uint8_t trig)
87+
{
88+
const struct intc_rz_ext_irq_config *config = dev->config;
89+
struct intc_rz_ext_irq_data *data = dev->data;
90+
fsp_err_t err = FSP_SUCCESS;
91+
external_irq_cfg_t *p_cfg = (external_irq_cfg_t *)config->fsp_cfg;
92+
93+
p_cfg->trigger = (external_irq_trigger_t)trig;
94+
err = config->fsp_api->close(data->fsp_ctrl);
95+
96+
if (err != FSP_SUCCESS) {
97+
return -EIO;
98+
}
99+
100+
err = config->fsp_api->open(data->fsp_ctrl, config->fsp_cfg);
101+
102+
if (err != FSP_SUCCESS) {
103+
return -EIO;
104+
}
105+
106+
return 0;
107+
}
108+
77109
static int intc_rz_ext_irq_init(const struct device *dev)
78110
{
79111
const struct intc_rz_ext_irq_config *config = dev->config;
@@ -109,16 +141,22 @@ static void intc_rz_ext_irq_callback(external_irq_callback_args_t *args)
109141
}
110142
}
111143

112-
#define EXT_IRQ_RZG_IRQ_CONNECT(index, isr, isr_nmi) \
144+
#ifdef CONFIG_CPU_CORTEX_M
145+
#define GET_IRQ_FLAGS(index) 0
146+
#else /* Cortex-A/R */
147+
#define GET_IRQ_FLAGS(index) DT_INST_IRQ_BY_IDX(index, 0, flags)
148+
#endif
149+
150+
#define EXT_IRQ_RZ_IRQ_CONNECT(index, isr, isr_nmi) \
113151
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(index, 0, irq), DT_INST_IRQ_BY_IDX(index, 0, priority), \
114152
COND_CODE_0(DT_INST_IRQ_BY_IDX(index, 0, irq), \
115-
(isr_nmi), (isr)), NULL, 0);
153+
(isr_nmi), (isr)), NULL, GET_IRQ_FLAGS(index));
116154

117155
#define INTC_RZG_EXT_IRQ_INIT(index) \
118156
static const external_irq_cfg_t g_external_irq##index##_cfg = { \
119157
.trigger = DT_INST_ENUM_IDX_OR(index, trigger_type, 0), \
120158
.filter_enable = true, \
121-
.pclk_div = EXTERNAL_IRQ_PCLK_DIV_BY_1, \
159+
.clock_source_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_1, \
122160
.p_callback = intc_rz_ext_irq_callback, \
123161
.p_context = DEVICE_DT_INST_GET(index), \
124162
.p_extend = NULL, \
@@ -149,12 +187,53 @@ static void intc_rz_ext_irq_callback(external_irq_callback_args_t *args)
149187
\
150188
static int intc_rz_ext_irq_init_##index(const struct device *dev) \
151189
{ \
152-
EXT_IRQ_RZG_IRQ_CONNECT(index, r_intc_irq_isr, r_intc_nmi_isr) \
190+
EXT_IRQ_RZ_IRQ_CONNECT(index, r_intc_irq_isr, r_intc_nmi_isr) \
191+
return intc_rz_ext_irq_init(dev); \
192+
}; \
193+
\
194+
DEVICE_DT_INST_DEFINE(index, intc_rz_ext_irq_init_##index, NULL, \
195+
&intc_rz_ext_irq_data##index, &intc_rz_ext_irq_config##index, \
196+
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL);
197+
198+
#define INTC_RZTN_EXT_IRQ_INIT(index) \
199+
static const external_irq_cfg_t g_external_irq##index##_cfg = { \
200+
.trigger = DT_INST_ENUM_IDX_OR(index, trigger_type, 0), \
201+
.filter_enable = true, \
202+
.clock_source_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_1, \
203+
.p_callback = intc_rz_ext_irq_callback, \
204+
.p_context = DEVICE_DT_INST_GET(index), \
205+
.p_extend = NULL, \
206+
.ipl = DT_INST_IRQ_BY_IDX(index, 0, priority), \
207+
.irq = DT_INST_IRQ_BY_IDX(index, 0, irq), \
208+
.channel = DT_INST_REG_ADDR(index), \
209+
}; \
210+
\
211+
PINCTRL_DT_INST_DEFINE(index); \
212+
\
213+
struct intc_rz_ext_irq_config intc_rz_ext_irq_config##index = { \
214+
.pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
215+
.fsp_cfg = (external_irq_cfg_t *)&g_external_irq##index##_cfg, \
216+
.fsp_api = &g_external_irq_on_icu, \
217+
}; \
218+
\
219+
icu_instance_ctrl_t g_external_irq##index##_ctrl; \
220+
\
221+
static struct intc_rz_ext_irq_data intc_rz_ext_irq_data##index = { \
222+
.fsp_ctrl = (icu_instance_ctrl_t *)&g_external_irq##index##_ctrl, \
223+
}; \
224+
\
225+
static int intc_rz_ext_irq_init_##index(const struct device *dev) \
226+
{ \
227+
EXT_IRQ_RZ_IRQ_CONNECT(index, r_icu_isr, NULL); \
153228
return intc_rz_ext_irq_init(dev); \
154229
}; \
155230
\
156231
DEVICE_DT_INST_DEFINE(index, intc_rz_ext_irq_init_##index, NULL, \
157232
&intc_rz_ext_irq_data##index, &intc_rz_ext_irq_config##index, \
158233
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL);
159234

235+
#if defined(CONFIG_SOC_SERIES_RZG3S)
160236
DT_INST_FOREACH_STATUS_OKAY(INTC_RZG_EXT_IRQ_INIT)
237+
#elif defined(CONFIG_SOC_SERIES_RZN2L)
238+
DT_INST_FOREACH_STATUS_OKAY(INTC_RZTN_EXT_IRQ_INIT)
239+
#endif

dts/arm/renesas/rz/rzn/r9a07g084.dtsi

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,157 @@
8888
};
8989
};
9090

91+
icu: icu@81048000 {
92+
reg = <0x81048000 0x1000>;
93+
interrupt-parent = <&gic>;
94+
#address-cells = <1>;
95+
#size-cells = <0>;
96+
97+
irq0: irq0@0 {
98+
compatible = "renesas,rz-ext-irq";
99+
reg = <0x0>;
100+
interrupts = <GIC_SPI 6 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
101+
interrupt-controller;
102+
#interrupt-cells = <2>;
103+
status = "disabled";
104+
};
105+
106+
irq1: irq@1 {
107+
compatible = "renesas,rz-ext-irq";
108+
reg = <0x1>;
109+
interrupts = <GIC_SPI 7 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
110+
interrupt-controller;
111+
#interrupt-cells = <2>;
112+
status = "disabled";
113+
};
114+
115+
irq2: irq@2 {
116+
compatible = "renesas,rz-ext-irq";
117+
reg = <0x2>;
118+
interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
119+
interrupt-controller;
120+
#interrupt-cells = <2>;
121+
status = "disabled";
122+
};
123+
124+
irq3: irq@3 {
125+
compatible = "renesas,rz-ext-irq";
126+
reg = <0x3>;
127+
interrupts = <GIC_SPI 9 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
128+
interrupt-controller;
129+
#interrupt-cells = <2>;
130+
status = "disabled";
131+
};
132+
133+
irq4: irq@4 {
134+
compatible = "renesas,rz-ext-irq";
135+
reg = <0x4>;
136+
interrupts = <GIC_SPI 10 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
137+
interrupt-controller;
138+
#interrupt-cells = <2>;
139+
status = "disabled";
140+
};
141+
142+
irq5: irq@5 {
143+
compatible = "renesas,rz-ext-irq";
144+
reg = <0x5>;
145+
interrupts = <GIC_SPI 11 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
146+
interrupt-controller;
147+
#interrupt-cells = <2>;
148+
status = "disabled";
149+
};
150+
151+
irq6: irq@6 {
152+
compatible = "renesas,rz-ext-irq";
153+
reg = <0x6>;
154+
interrupts = <GIC_SPI 12 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
155+
interrupt-controller;
156+
#interrupt-cells = <2>;
157+
status = "disabled";
158+
};
159+
160+
irq7: irq@7 {
161+
compatible = "renesas,rz-ext-irq";
162+
reg = <0x7>;
163+
interrupts = <GIC_SPI 13 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
164+
interrupt-controller;
165+
#interrupt-cells = <2>;
166+
status = "disabled";
167+
};
168+
169+
irq8: irq@8 {
170+
compatible = "renesas,rz-ext-irq";
171+
reg = <0x8>;
172+
interrupts = <GIC_SPI 14 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
173+
interrupt-controller;
174+
#interrupt-cells = <2>;
175+
status = "disabled";
176+
};
177+
178+
irq9: irq@9 {
179+
compatible = "renesas,rz-ext-irq";
180+
reg = <0x9>;
181+
interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
182+
interrupt-controller;
183+
#interrupt-cells = <2>;
184+
status = "disabled";
185+
};
186+
187+
irq10: irq@a {
188+
compatible = "renesas,rz-ext-irq";
189+
reg = <0xa>;
190+
interrupts = <GIC_SPI 16 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
191+
interrupt-controller;
192+
#interrupt-cells = <2>;
193+
status = "disabled";
194+
};
195+
196+
irq11: irq@b {
197+
compatible = "renesas,rz-ext-irq";
198+
reg = <0xb>;
199+
interrupts = <GIC_SPI 17 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
200+
interrupt-controller;
201+
#interrupt-cells = <2>;
202+
status = "disabled";
203+
};
204+
205+
irq12: irq@c {
206+
compatible = "renesas,rz-ext-irq";
207+
reg = <0xc>;
208+
interrupts = <GIC_SPI 18 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
209+
interrupt-controller;
210+
#interrupt-cells = <2>;
211+
status = "disabled";
212+
};
213+
214+
irq13: irq@d {
215+
compatible = "renesas,rz-ext-irq";
216+
reg = <0xd>;
217+
interrupts = <GIC_SPI 19 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
218+
interrupt-controller;
219+
#interrupt-cells = <2>;
220+
status = "disabled";
221+
};
222+
223+
irq14: irq@e {
224+
compatible = "renesas,rz-ext-irq";
225+
reg = <0xe>;
226+
interrupts = <GIC_SPI 394 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
227+
interrupt-controller;
228+
#interrupt-cells = <2>;
229+
status = "disabled";
230+
};
231+
232+
irq15: irq@f {
233+
compatible = "renesas,rz-ext-irq";
234+
reg = <0xf>;
235+
interrupts = <GIC_SPI 395 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
236+
interrupt-controller;
237+
#interrupt-cells = <2>;
238+
status = "disabled";
239+
};
240+
};
241+
91242
pinctrl: pinctrl@800a0000 {
92243
compatible = "renesas,rzn-pinctrl";
93244
reg = <0x800a0000 0x1000 0x81030c00 0x1000>;

dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
# Copyright (c) 2024 Renesas Electronics Corporation
22
# SPDX-License-Identifier: Apache-2.0
33

4-
description: Renesas RZG external interrupt controller
4+
description: Renesas RZ external interrupt controller
55

66
compatible: "renesas,rz-ext-irq"
77

88
include: [interrupt-controller.yaml, base.yaml, pinctrl-device.yaml]
99

1010
properties:
11-
"#address-cells":
12-
const: 0
13-
1411
"#interrupt-cells":
1512
const: 2
1613

include/zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
/*
2-
* Copyright (c) 2024 Renesas Electronics Corporation
2+
* Copyright (c) 2024-2025 Renesas Electronics Corporation
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_
88
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_
99

10+
#define RZ_EXT_IRQ_TRIG_FALLING 0
11+
#define RZ_EXT_IRQ_TRIG_RISING 1
12+
#define RZ_EXT_IRQ_TRIG_BOTH_EDGE 2
13+
#define RZ_EXT_IRQ_TRIG_LEVEL_LOW 3
14+
1015
/** RZ external interrupt callback */
1116
typedef void (*intc_rz_ext_irq_callback_t)(void *arg);
1217

1318
/**
14-
* @brief Enable external interrupt for specified channel at NVIC.
19+
* @brief Enable external interrupt for specified channel.
1520
*
1621
* @param dev: pointer to interrupt controller instance
1722
* @return 0 on success, or negative value on error
1823
*/
1924
int intc_rz_ext_irq_enable(const struct device *dev);
2025

2126
/**
22-
* @brief Disable external interrupt for specified channel at NVIC.
27+
* @brief Disable external interrupt for specified channel.
2328
*
2429
* @param dev: pointer to interrupt controller instance
2530
* @return 0 on success, or negative value on error
@@ -37,4 +42,13 @@ int intc_rz_ext_irq_disable(const struct device *dev);
3742
int intc_rz_ext_irq_set_callback(const struct device *dev, intc_rz_ext_irq_callback_t cb,
3843
void *arg);
3944

45+
/**
46+
* @brief Change trigger external interrupt type for specified channel.
47+
*
48+
* @param dev: pointer to interrupt controller instance
49+
* @param trig: trigger type to be changed
50+
* @return 0 on success, or negative value on error
51+
*/
52+
int intc_rz_ext_irq_set_type(const struct device *dev, uint8_t trig);
53+
4054
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_ */

modules/Kconfig.renesas_fsp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,9 @@ config USE_RZ_FSP_SCI_UART
218218
help
219219
Enable RZ FSP SCI UART driver
220220

221+
config USE_RZ_FSP_EXT_IRQ
222+
bool
223+
help
224+
Enable RZ FSP External IRQ driver
225+
221226
endif

0 commit comments

Comments
 (0)