2023-12-04 20:38:43

by Ben Wolsieffer

[permalink] [raw]
Subject: [PATCH 0/2] stm32: fix GPIO level interrupts

GPIO level interrupts on the STM32 were behaving like edge interrupts.
The STM32 lacks hardware support for GPIO level interrupts, therefore
the pinctrl driver contains code to emulate them using edge interrupts,
but this was not working.

First, the STM32 EXTI interrupt controller driver lacked support for
retriggering interrupts, and second, the wrong IRQ handler was being
used because the parent interrupt was an edge interrupt.

Ben Wolsieffer (2):
irqchip/stm32-exti: support retriggering on STM32 MCUs
pinctrl: stm32: fix GPIO level interrupts

drivers/irqchip/irq-stm32-exti.c | 13 +++++++++++++
drivers/pinctrl/stm32/pinctrl-stm32.c | 3 +++
2 files changed, 16 insertions(+)

--
2.42.1


2023-12-04 20:39:06

by Ben Wolsieffer

[permalink] [raw]
Subject: [PATCH 1/2] irqchip/stm32-exti: support retriggering on STM32 MCUs

EXTI retriggering support was missing on STM32 MCUs. Retriggering is
required to emulate GPIO level interrupts using edge interrupts in the
STM32 pinctrl driver.

Signed-off-by: Ben Wolsieffer <[email protected]>
---
drivers/irqchip/irq-stm32-exti.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 971240e2e31b..6b3f54457812 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -328,6 +328,18 @@ static void stm32_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}

+static int stm32_irq_retrigger(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct stm32_exti_chip_data *chip_data = gc->private;
+ const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
+ u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
+
+ irq_reg_writel(gc, mask, stm32_bank->swier_ofst);
+
+ return 0;
+}
+
static int stm32_exti_set_type(struct irq_data *d,
unsigned int type, u32 *rtsr, u32 *ftsr)
{
@@ -856,6 +868,7 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
gc->chip_types->chip.irq_ack = stm32_irq_ack;
gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
+ gc->chip_types->chip.irq_retrigger = stm32_irq_retrigger;
gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
gc->chip_types->chip.irq_set_wake = irq_gc_set_wake;
gc->suspend = stm32_irq_suspend;
--
2.42.1