diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-04-25 10:05:40 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-04-26 07:32:23 +0000 |
commit | cce53bed31cbc0737bda852a6f98d279a4906e09 (patch) | |
tree | 74daea9e654e929c7d67ea3b73d794f9cdd4654e | |
parent | 96ef35acba6656bd27aa7e4162d5bafa9e915900 (diff) | |
download | chrome-ec-cce53bed31cbc0737bda852a6f98d279a4906e09.tar.gz |
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 <vpalatin@chromium.org>
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 <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Vic Yang <victoryang@chromium.org>
-rw-r--r-- | chip/stm32/gpio-stm32f.c | 3 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32f0.c | 3 | ||||
-rw-r--r-- | 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; |