Skip to content

Commit a9e4991

Browse files
soburifabiobaltieri
authored andcommitted
drivers: interrupt_controller: Add icu driver for Renesas RA series
To avoid complicating the initial code for supporting the SoC, I have implemented only the bare minimum for now. Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 04b723e commit a9e4991

File tree

10 files changed

+380
-3
lines changed

10 files changed

+380
-3
lines changed

drivers/interrupt_controller/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c)
3636
zephyr_library_sources_ifdef(CONFIG_NXP_S32_WKPU intc_wkpu_nxp_s32.c)
3737
zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c)
3838
zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c)
39+
zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ICU intc_ra_icu.c)
3940

4041
if(CONFIG_INTEL_VTD_ICTL)
4142
zephyr_library_include_directories(${ZEPHYR_BASE}/arch/x86/include)

drivers/interrupt_controller/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,6 @@ source "drivers/interrupt_controller/Kconfig.nxp_pint"
102102

103103
source "drivers/interrupt_controller/Kconfig.vim"
104104

105+
source "drivers/interrupt_controller/Kconfig.ra"
106+
105107
endmenu
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2023 TOKITA Hiroshi <[email protected]>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config RENESAS_RA_ICU
5+
bool "Renesas RA series interrupt controller unit"
6+
default y
7+
depends on DT_HAS_RENESAS_RA_INTERRUPT_CONTROLLER_UNIT_ENABLED
8+
help
9+
Renesas RA series interrupt controller unit
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2023 TOKITTA Hiroshi <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT renesas_ra_interrupt_controller_unit
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/irq.h>
11+
#include <soc.h>
12+
#include <zephyr/drivers/interrupt_controller/intc_ra_icu.h>
13+
#include <zephyr/sw_isr_table.h>
14+
#include <errno.h>
15+
16+
#define IELSRn_REG(n) (DT_INST_REG_ADDR(0) + IELSRn_OFFSET + (n * 4))
17+
#define IRQCRi_REG(i) (DT_INST_REG_ADDR(0) + IRQCRi_OFFSET + (i))
18+
19+
#define IRQCRi_IRQMD_POS 0
20+
#define IRQCRi_IRQMD_MASK BIT_MASK(2)
21+
#define IELSRn_IR_POS 16
22+
#define IELSRn_IR_MASK BIT_MASK(1)
23+
24+
enum {
25+
IRQCRi_OFFSET = 0x0,
26+
IELSRn_OFFSET = 0x300,
27+
};
28+
29+
int ra_icu_query_exists_irq(uint32_t event)
30+
{
31+
for (uint32_t i = 0; i < CONFIG_NUM_IRQS; i++) {
32+
uint32_t els = sys_read32(IELSRn_REG(i)) & UINT8_MAX;
33+
34+
if (event == els) {
35+
return i;
36+
}
37+
}
38+
39+
return -EINVAL;
40+
}
41+
42+
int ra_icu_query_available_irq(uint32_t event)
43+
{
44+
int irq = -EINVAL;
45+
46+
if (ra_icu_query_exists_irq(event) > 0) {
47+
return -EINVAL;
48+
}
49+
50+
for (uint32_t i = 0; i < CONFIG_NUM_IRQS; i++) {
51+
if (_sw_isr_table[i].isr == z_irq_spurious) {
52+
irq = i;
53+
break;
54+
}
55+
}
56+
57+
return irq;
58+
}
59+
60+
void ra_icu_clear_int_flag(unsigned int irqn)
61+
{
62+
uint32_t cfg = sys_read32(IELSRn_REG(irqn));
63+
64+
sys_write32(cfg & ~BIT(IELSRn_IR_POS), IELSRn_REG(irqn));
65+
}
66+
67+
void ra_icu_query_irq_config(unsigned int irq, uint32_t *intcfg, ra_isr_handler *cb,
68+
const void **cbarg)
69+
{
70+
*intcfg = sys_read32(IELSRn_REG(irq));
71+
*cb = _sw_isr_table[irq].isr;
72+
*cbarg = (void *)_sw_isr_table[irq].arg;
73+
}
74+
75+
static void ra_icu_irq_configure(unsigned int irqn, uint32_t intcfg)
76+
{
77+
uint8_t reg = sys_read8(IRQCRi_REG(irqn)) & ~(IRQCRi_IRQMD_MASK);
78+
79+
sys_write8(reg | (intcfg & IRQCRi_IRQMD_MASK), IRQCRi_REG(irqn));
80+
}
81+
82+
int ra_icu_irq_connect_dynamic(unsigned int irq, unsigned int priority,
83+
void (*routine)(const void *parameter), const void *parameter,
84+
uint32_t flags)
85+
{
86+
uint32_t event = ((flags & RA_ICU_FLAG_EVENT_MASK) >> RA_ICU_FLAG_EVENT_OFFSET);
87+
uint32_t intcfg = ((flags & RA_ICU_FLAG_INTCFG_MASK) >> RA_ICU_FLAG_INTCFG_OFFSET);
88+
int irqn = irq;
89+
90+
if (irq == RA_ICU_IRQ_UNSPECIFIED) {
91+
irqn = ra_icu_query_available_irq(event);
92+
if (irqn < 0) {
93+
return irqn;
94+
}
95+
}
96+
97+
irq_disable(irqn);
98+
sys_write32(event, IELSRn_REG(irqn));
99+
z_isr_install(irqn, routine, parameter);
100+
z_arm_irq_priority_set(irqn, priority, flags);
101+
ra_icu_irq_configure(event, intcfg);
102+
irq_enable(irqn);
103+
104+
return irqn;
105+
}
106+
107+
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY,
108+
NULL);

dts/arm/renesas/ra/ra-cm4-common.dtsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@
7272
};
7373

7474
soc {
75+
interrupt-parent = <&icu>;
76+
icu: interrupt-controller@40006000 {
77+
compatible = "renesas,ra-interrupt-controller-unit";
78+
reg = <0x40006000 0x40>;
79+
reg-names = "icu";
80+
interrupt-controller;
81+
#interrupt-cells = <3>;
82+
};
83+
7584
cgc: cgc@4001e000 {
7685
compatible = "renesas,ra-clock-generation-circuit";
7786
reg = <0x4001e000 0x40 0x40047000 0x10>;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright (c) 2023, TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Renesas RA series interrupt controller unit
5+
6+
compatible: "renesas,ra-interrupt-controller-unit"
7+
8+
include: [interrupt-controller.yaml, base.yaml]
9+
10+
properties:
11+
reg:
12+
required: true
13+
14+
"#interrupt-cells":
15+
const: 3
16+
17+
interrupt-cells:
18+
- irq
19+
- priority
20+
- flags

dts/bindings/pinctrl/renesas,ra-pinctrl.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ child-binding:
1313
Definitions for a pinctrl state.
1414
child-binding:
1515

16-
include:
17-
- name: pincfg-node.yaml
18-
1916
properties:
2017
pinmux:
2118
required: true
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2023 TOKITA Hiroshi <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/dt-bindings/interrupt-controller/renesas-ra-icu.h>
8+
9+
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_
10+
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_
11+
12+
#define RA_ICU_FLAG_EVENT_OFFSET 8
13+
#define RA_ICU_FLAG_EVENT_MASK (BIT_MASK(8) << RA_ICU_FLAG_EVENT_OFFSET)
14+
#define RA_ICU_FLAG_INTCFG_OFFSET 16
15+
#define RA_ICU_FLAG_INTCFG_MASK (BIT_MASK(8) << RA_ICU_FLAG_INTCFG_OFFSET)
16+
17+
enum icu_irq_mode {
18+
ICU_FALLING,
19+
ICU_RISING,
20+
ICU_BOTH_EDGE,
21+
ICU_LOW_LEVEL,
22+
};
23+
24+
typedef void (*ra_isr_handler)(const void *);
25+
26+
extern void ra_icu_clear_int_flag(unsigned int irqn);
27+
28+
extern int ra_icu_query_available_irq(uint32_t event);
29+
extern int ra_icu_query_exists_irq(uint32_t event);
30+
31+
extern void ra_icu_query_irq_config(unsigned int irq, uint32_t *intcfg, ra_isr_handler *pisr,
32+
const void **cbarg);
33+
34+
extern int ra_icu_irq_connect_dynamic(unsigned int irq, unsigned int priority,
35+
void (*routine)(const void *parameter), const void *parameter,
36+
uint32_t flags);
37+
38+
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RA_ICU_H_ */

0 commit comments

Comments
 (0)