From cce53bed31cbc0737bda852a6f98d279a4906e09 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Fri, 25 Apr 2014 10:05:40 -0700 Subject: [PATCH] stm32: fix GPIO EXTINT masking The external interrupts above 15 are not used for GPIO IRQ handling, but for special purpose interrupts from internal peripherals (e.g. RTC, comparator, wake-up ...). When processing the GPIO interrupts, we should explicitly skip those interrupts, else if a GPIO interrupt happens first followed by another EXTINT, the loop in gpio_interrupt() will try to process it and do an out-of-bound read of the exti_events array. This will retrieve a garbage handler triggering a memory fault. Signed-off-by: Vincent Palatin BRANCH=none BUG=chrome-os-partner:28296 TEST=on Firefly, press the buttons to trigger GPIO interrupts while there are a bunch of comparator interrupt on EXTIN21 (due to on-going USB PD communication). I no longer see HardFaults. Change-Id: Id90fab30215b0f7f8060c19de63a7ca8418b7b3c Reviewed-on: https://chromium-review.googlesource.com/197019 Commit-Queue: Vincent Palatin Tested-by: Vincent Palatin Reviewed-by: Vic Yang --- chip/stm32/gpio-stm32f.c | 3 ++- chip/stm32/gpio-stm32f0.c | 3 ++- chip/stm32/gpio-stm32l.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/chip/stm32/gpio-stm32f.c b/chip/stm32/gpio-stm32f.c index 79fc2235d0..eb733e470b 100644 --- a/chip/stm32/gpio-stm32f.c +++ b/chip/stm32/gpio-stm32f.c @@ -231,7 +231,8 @@ void gpio_interrupt(void) { int bit; const struct gpio_info *g; - uint32_t pending = STM32_EXTI_PR; + /* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */ + uint32_t pending = STM32_EXTI_PR & 0xFFFF; STM32_EXTI_PR = pending; diff --git a/chip/stm32/gpio-stm32f0.c b/chip/stm32/gpio-stm32f0.c index 8e756ab183..a6d1b7b87c 100644 --- a/chip/stm32/gpio-stm32f0.c +++ b/chip/stm32/gpio-stm32f0.c @@ -232,7 +232,8 @@ void gpio_interrupt(void) { int bit; const struct gpio_info *g; - uint32_t pending = STM32_EXTI_PR; + /* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */ + uint32_t pending = STM32_EXTI_PR & 0xFFFF; STM32_EXTI_PR = pending; diff --git a/chip/stm32/gpio-stm32l.c b/chip/stm32/gpio-stm32l.c index ca627dd701..edc2fba652 100644 --- a/chip/stm32/gpio-stm32l.c +++ b/chip/stm32/gpio-stm32l.c @@ -236,7 +236,8 @@ void gpio_interrupt(void) { int bit; const struct gpio_info *g; - uint32_t pending = STM32_EXTI_PR; + /* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */ + uint32_t pending = STM32_EXTI_PR & 0xFFFF; STM32_EXTI_PR = pending;