diff options
Diffstat (limited to 'chip/stm32/gpio.c')
-rw-r--r-- | chip/stm32/gpio.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c index ef7fc818ba..d58ce29328 100644 --- a/chip/stm32/gpio.c +++ b/chip/stm32/gpio.c @@ -16,9 +16,8 @@ /* Console output macros */ #define CPRINTS(format, args...) cprints(CC_GPIO, format, ## args) - /* For each EXTI bit, record which GPIO entry is using it */ -static const struct gpio_info *exti_events[16]; +static uint8_t exti_events[16]; void gpio_pre_init(void) { @@ -75,19 +74,23 @@ void gpio_set_level(enum gpio_signal signal, int value) int gpio_enable_interrupt(enum gpio_signal signal) { const struct gpio_info *g = gpio_list + signal; + const struct gpio_info *g_old = gpio_list; + uint32_t bit, group, shift, bank; /* Fail if not implemented or no interrupt handler */ - if (!g->mask || !g->irq_handler) + if (!g->mask || signal >= GPIO_IH_COUNT) return EC_ERROR_INVAL; bit = 31 - __builtin_clz(g->mask); - if ((exti_events[bit]) && (exti_events[bit] != g)) { + g_old += exti_events[bit]; + + if ((exti_events[bit]) && (exti_events[bit] != signal)) { CPRINTS("Overriding %s with %s on EXTI%d", - exti_events[bit]->name, g->name, bit); + g_old->name, g->name, bit); } - exti_events[bit] = g; + exti_events[bit] = signal; group = bit / 4; shift = (bit % 4) * 4; @@ -115,17 +118,17 @@ int gpio_enable_interrupt(enum gpio_signal signal) void gpio_interrupt(void) { int bit; - const struct gpio_info *g; /* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */ uint32_t pending = STM32_EXTI_PR & 0xFFFF; + uint8_t signal; STM32_EXTI_PR = pending; while (pending) { bit = get_next_bit(&pending); - g = exti_events[bit]; - if (g && g->irq_handler) - g->irq_handler(g - gpio_list); + signal = exti_events[bit]; + if (signal < GPIO_IH_COUNT) + gpio_irq_handlers[signal](signal); } } #ifdef CHIP_FAMILY_STM32F0 |