Skip to content

Commit de22c56

Browse files
KozhinovAlexandermathieuchopstm
authored andcommitted
drivers: interrupt_controller: intc_gpio_stm32: update to new EXTI binding
integrate intc_exti_stm32 to intc_gpio_stm32 Co-authored-by: Mathieu CHOPLAIN <[email protected]> Signed-off-by: Alexander Kozhinov <[email protected]>
1 parent 5eb84df commit de22c56

File tree

1 file changed

+38
-134
lines changed

1 file changed

+38
-134
lines changed

drivers/interrupt_controller/intc_gpio_stm32.c

Lines changed: 38 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
* Copyright (c) 2017 RnDity Sp. z o.o.
44
* Copyright (c) 2019-23 Linaro Limited
55
* Copyright (C) 2025 Savoir-faire Linux, Inc.
6+
* Copyright (c) 2025 Alexander Kozhinov <[email protected]>
67
*
78
* SPDX-License-Identifier: Apache-2.0
89
*/
910

1011
/**
11-
* @brief Driver for External interrupt/event controller in STM32 MCUs
12+
* @brief Driver for STM32 External interrupt/event controller
1213
*/
1314

14-
#define EXTI_NODE DT_INST(0, st_stm32_exti)
15-
1615
#include <zephyr/device.h>
1716
#include <soc.h>
1817
#include <stm32_ll_bus.h>
@@ -23,20 +22,26 @@
2322
#include <zephyr/sys/util.h>
2423
#include <zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h> /* For STM32L0 series */
2524
#include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
25+
#include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
2626
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
2727
#include <zephyr/irq.h>
2828

2929
#include "stm32_hsem.h"
30+
#include "intc_exti_stm32_priv.h"
3031

3132
/** @brief EXTI lines range mapped to a single interrupt line */
3233
struct stm32_exti_range {
33-
/** Start of the range */
34+
/* Start of the range */
3435
uint8_t start;
35-
/** Range length */
36+
/* Range length */
3637
uint8_t len;
3738
};
3839

39-
#define NUM_EXTI_LINES DT_PROP(EXTI_NODE, num_lines)
40+
#define EXTI_NUM_LINES_TOTAL DT_PROP(EXTI_NODE, num_lines)
41+
#define NUM_EXTI_LINES DT_PROP(EXTI_NODE, num_gpio_lines)
42+
43+
BUILD_ASSERT(EXTI_NUM_LINES_TOTAL >= NUM_EXTI_LINES,
44+
"The total number of EXTI lines must be greater or equal than the number of GPIO lines");
4045

4146
static IRQn_Type exti_irq_table[NUM_EXTI_LINES] = {[0 ... NUM_EXTI_LINES - 1] = 0xFF};
4247

@@ -47,11 +52,13 @@ struct __exti_cb {
4752
};
4853

4954
/* EXTI driver data */
50-
struct stm32_exti_data {
55+
struct stm32_intc_gpio_data {
5156
/* per-line callbacks */
5257
struct __exti_cb cb[NUM_EXTI_LINES];
5358
};
5459

60+
static struct stm32_intc_gpio_data intc_gpio_data;
61+
5562
/**
5663
* @returns the LL_<PPP>_EXTI_LINE_xxx define that corresponds to specified @p linenum
5764
* This value can be used with the LL EXTI source configuration functions.
@@ -72,54 +79,6 @@ static inline uint32_t stm32_exti_linenum_to_src_cfg_line(gpio_pin_t linenum)
7279
#endif
7380
}
7481

75-
/**
76-
* @brief Checks interrupt pending bit for specified EXTI line
77-
*
78-
* @param line EXTI line number
79-
*/
80-
static inline int stm32_exti_is_pending(stm32_gpio_irq_line_t line)
81-
{
82-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
83-
return (LL_EXTI_IsActiveRisingFlag_0_31(line) ||
84-
LL_EXTI_IsActiveFallingFlag_0_31(line));
85-
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
86-
return LL_C2_EXTI_IsActiveFlag_0_31(line);
87-
#elif defined(CONFIG_SOC_SERIES_STM32MP2X)
88-
return LL_EXTI_IsActiveRisingFlag_0_31(EXTI2, line) ||
89-
LL_EXTI_IsActiveFallingFlag_0_31(EXTI2, line);
90-
#else
91-
return LL_EXTI_IsActiveFlag_0_31(line);
92-
#endif
93-
}
94-
95-
/**
96-
* @brief Clears interrupt pending bit for specified EXTI line
97-
*
98-
* @param line EXTI line number
99-
*/
100-
static inline void stm32_exti_clear_pending(stm32_gpio_irq_line_t line)
101-
{
102-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
103-
LL_EXTI_ClearRisingFlag_0_31(line);
104-
LL_EXTI_ClearFallingFlag_0_31(line);
105-
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
106-
LL_C2_EXTI_ClearFlag_0_31(line);
107-
#elif defined(CONFIG_SOC_SERIES_STM32MP2X)
108-
LL_EXTI_ClearRisingFlag_0_31(EXTI2, line);
109-
LL_EXTI_ClearFallingFlag_0_31(EXTI2, line);
110-
#else
111-
LL_EXTI_ClearFlag_0_31(line);
112-
#endif
113-
}
114-
115-
/**
116-
* @returns the LL_EXTI_LINE_n define for EXTI line number @p linenum
117-
*/
118-
static inline stm32_gpio_irq_line_t linenum_to_ll_exti_line(gpio_pin_t linenum)
119-
{
120-
return BIT(linenum);
121-
}
122-
12382
/**
12483
* @returns EXTI line number for LL_EXTI_LINE_n define
12584
*/
@@ -135,68 +94,34 @@ static inline gpio_pin_t ll_exti_line_to_linenum(stm32_gpio_irq_line_t line)
13594
*
13695
* @param exti_range Pointer to a exti_range structure
13796
*/
138-
static void stm32_exti_isr(const void *exti_range)
97+
static void stm32_intc_gpio_isr(const void *exti_range)
13998
{
140-
const struct device *dev = DEVICE_DT_GET(EXTI_NODE);
141-
struct stm32_exti_data *data = dev->data;
99+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
142100
const struct stm32_exti_range *range = exti_range;
143101
stm32_gpio_irq_line_t line;
144102
uint32_t line_num;
145103

146104
/* see which bits are set */
147105
for (uint8_t i = 0; i <= range->len; i++) {
148106
line_num = range->start + i;
149-
line = linenum_to_ll_exti_line(line_num);
150107

151108
/* check if interrupt is pending */
152-
if (stm32_exti_is_pending(line) != 0) {
109+
if (stm32_exti_is_pending(line_num)) {
153110
/* clear pending interrupt */
154-
stm32_exti_clear_pending(line);
111+
stm32_exti_clear_pending(line_num);
155112

156113
/* run callback only if one is registered */
157114
if (!data->cb[line_num].cb) {
158115
continue;
159116
}
160117

161118
/* `line` can be passed as-is because LL_EXTI_LINE_n is (1 << n) */
119+
line = exti_linenum_to_ll_exti_line(line_num);
162120
data->cb[line_num].cb(line, data->cb[line_num].data);
163121
}
164122
}
165123
}
166124

167-
/** Enables the peripheral clock required to access EXTI registers */
168-
static int stm32_exti_enable_registers(void)
169-
{
170-
/* Initialize to 0 for series where there is nothing to do. */
171-
int ret = 0;
172-
#if defined(CONFIG_SOC_SERIES_STM32F2X) || \
173-
defined(CONFIG_SOC_SERIES_STM32F3X) || \
174-
defined(CONFIG_SOC_SERIES_STM32F4X) || \
175-
defined(CONFIG_SOC_SERIES_STM32F7X) || \
176-
defined(CONFIG_SOC_SERIES_STM32H7X) || \
177-
defined(CONFIG_SOC_SERIES_STM32H7RSX) || \
178-
defined(CONFIG_SOC_SERIES_STM32L1X) || \
179-
defined(CONFIG_SOC_SERIES_STM32L4X) || \
180-
defined(CONFIG_SOC_SERIES_STM32G4X)
181-
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
182-
struct stm32_pclken pclken = {
183-
#if defined(CONFIG_SOC_SERIES_STM32H7X)
184-
.bus = STM32_CLOCK_BUS_APB4,
185-
.enr = LL_APB4_GRP1_PERIPH_SYSCFG
186-
#elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
187-
.bus = STM32_CLOCK_BUS_APB4,
188-
.enr = LL_APB4_GRP1_PERIPH_SBS
189-
#else
190-
.bus = STM32_CLOCK_BUS_APB2,
191-
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
192-
#endif /* CONFIG_SOC_SERIES_STM32H7X */
193-
};
194-
195-
ret = clock_control_on(clk, (clock_control_subsys_t) &pclken);
196-
#endif
197-
return ret;
198-
}
199-
200125
static void stm32_fill_irq_table(int8_t start, int8_t len, int32_t irqn)
201126
{
202127
for (int i = 0; i < len; i++) {
@@ -206,7 +131,7 @@ static void stm32_fill_irq_table(int8_t start, int8_t len, int32_t irqn)
206131

207132
/* This macro:
208133
* - populates line_range_x from line_range dt property
209-
* - fill exti_irq_table through stm32_fill_irq_table()
134+
* - fills exti_irq_table through stm32_fill_irq_table()
210135
* - calls IRQ_CONNECT for each interrupt and matching line_range
211136
*/
212137
#define STM32_EXTI_INIT_LINE_RANGE(node_id, interrupts, idx) \
@@ -219,28 +144,21 @@ static void stm32_fill_irq_table(int8_t start, int8_t len, int32_t irqn)
219144
DT_IRQ_BY_IDX(node_id, idx, irq)); \
220145
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
221146
DT_IRQ_BY_IDX(node_id, idx, priority), \
222-
stm32_exti_isr, &line_range_##idx, 0);
147+
stm32_intc_gpio_isr, &line_range_##idx, 0);
223148

224149
/**
225150
* @brief Initializes the EXTI GPIO interrupt controller driver
226151
*/
227-
static int stm32_exti_init(const struct device *dev)
152+
static int stm32_exti_gpio_intc_init(void)
228153
{
229-
ARG_UNUSED(dev);
230-
231154
DT_FOREACH_PROP_ELEM(EXTI_NODE,
232155
interrupt_names,
233156
STM32_EXTI_INIT_LINE_RANGE);
234157

235-
return stm32_exti_enable_registers();
158+
return 0;
236159
}
237160

238-
static struct stm32_exti_data exti_data;
239-
DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
240-
NULL,
241-
&exti_data, NULL,
242-
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY,
243-
NULL);
161+
SYS_INIT(stm32_exti_gpio_intc_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY);
244162

245163
/**
246164
* @brief EXTI GPIO interrupt controller API implementation
@@ -260,7 +178,7 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
260178
stm32_gpio_irq_line_t stm32_gpio_intc_get_pin_irq_line(uint32_t port, gpio_pin_t pin)
261179
{
262180
ARG_UNUSED(port);
263-
return linenum_to_ll_exti_line(pin);
181+
return exti_linenum_to_ll_exti_line(pin);
264182
}
265183

266184
void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line)
@@ -275,27 +193,15 @@ void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line)
275193
__ASSERT_NO_MSG(irqnum != 0xFF);
276194

277195
/* Enable requested line interrupt */
278-
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
279-
LL_C2_EXTI_EnableIT_0_31(line);
280-
#elif defined(CONFIG_SOC_SERIES_STM32MP2X)
281-
LL_C2_EXTI_EnableIT_0_31(EXTI2, line);
282-
#else
283-
LL_EXTI_EnableIT_0_31(line);
284-
#endif
196+
EXTI_ENABLE_IT(0_31, line);
285197

286198
/* Enable exti irq interrupt */
287199
irq_enable(irqnum);
288200
}
289201

290202
void stm32_gpio_intc_disable_line(stm32_gpio_irq_line_t line)
291203
{
292-
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
293-
LL_C2_EXTI_DisableIT_0_31(line);
294-
#elif defined(CONFIG_SOC_SERIES_STM32MP2X)
295-
LL_C2_EXTI_DisableIT_0_31(EXTI2, line);
296-
#else
297-
LL_EXTI_DisableIT_0_31(line);
298-
#endif
204+
EXTI_DISABLE_IT(0_31, line);
299205
}
300206

301207
void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t trg)
@@ -322,20 +228,20 @@ void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t tr
322228
break;
323229
#else /* CONFIG_SOC_SERIES_STM32MP2X */
324230
case STM32_GPIO_IRQ_TRIG_NONE:
325-
LL_EXTI_DisableRisingTrig_0_31(line);
326-
LL_EXTI_DisableFallingTrig_0_31(line);
231+
EXTI_DISABLE_RISING_TRIG(0_31, line);
232+
EXTI_DISABLE_FALLING_TRIG(0_31, line);
327233
break;
328234
case STM32_GPIO_IRQ_TRIG_RISING:
329-
LL_EXTI_EnableRisingTrig_0_31(line);
330-
LL_EXTI_DisableFallingTrig_0_31(line);
235+
EXTI_ENABLE_RISING_TRIG(0_31, line);
236+
EXTI_DISABLE_FALLING_TRIG(0_31, line);
331237
break;
332238
case STM32_GPIO_IRQ_TRIG_FALLING:
333-
LL_EXTI_EnableFallingTrig_0_31(line);
334-
LL_EXTI_DisableRisingTrig_0_31(line);
239+
EXTI_ENABLE_FALLING_TRIG(0_31, line);
240+
EXTI_DISABLE_RISING_TRIG(0_31, line);
335241
break;
336242
case STM32_GPIO_IRQ_TRIG_BOTH:
337-
LL_EXTI_EnableRisingTrig_0_31(line);
338-
LL_EXTI_EnableFallingTrig_0_31(line);
243+
EXTI_ENABLE_RISING_TRIG(0_31, line);
244+
EXTI_ENABLE_FALLING_TRIG(0_31, line);
339245
break;
340246
#endif /* CONFIG_SOC_SERIES_STM32MP2X */
341247
default:
@@ -347,15 +253,14 @@ void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t tr
347253

348254
int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line, stm32_gpio_irq_cb_t cb, void *user)
349255
{
350-
const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
351-
struct stm32_exti_data *data = dev->data;
256+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
352257
uint32_t line_num = ll_exti_line_to_linenum(line);
353258

354259
if ((data->cb[line_num].cb == cb) && (data->cb[line_num].data == user)) {
355260
return 0;
356261
}
357262

358-
/* if callback already exists/maybe-running return busy */
263+
/* if callback already exists/is running, return busy */
359264
if (data->cb[line_num].cb != NULL) {
360265
return -EBUSY;
361266
}
@@ -368,8 +273,7 @@ int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line, stm32_gpio_irq_
368273

369274
void stm32_gpio_intc_remove_irq_callback(stm32_gpio_irq_line_t line)
370275
{
371-
const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
372-
struct stm32_exti_data *data = dev->data;
276+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
373277
uint32_t line_num = ll_exti_line_to_linenum(line);
374278

375279
data->cb[line_num].cb = NULL;

0 commit comments

Comments
 (0)