diff options
author | scott worley <scott.worley@microchip.corp-partner.google.com> | 2018-05-10 09:12:08 -0400 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-05-22 21:57:04 -0700 |
commit | 67ed6ee3e79400996e276c87eeb32765f6d124e2 (patch) | |
tree | 97b87ba57e930d862c3736c6cb4ce7ed5374e728 | |
parent | b34a5973cd8a5cc66c4c931a86317a114f68d792 (diff) | |
download | chrome-ec-67ed6ee3e79400996e276c87eeb32765f6d124e2.tar.gz |
ec_chip_mchp: Fix bug in GPIO interrupt handling.
The previous chip level GPIO itnerrupt change introduced
a bug in calculation of the gpio table index. Bug only
manifested if GPIOs in different banks were configured
for interrupts.
BRANCH=none
BUG=
TEST=Configure board with at least one GPIO interrupt
per bank. Check proper handler is called when pin
interrupt is triggered.
CQ-DEPEND=CL:1053576
Change-Id: I9dd5d18be5f9df0e338e76b072fb82ed2df3e2de
Signed-off-by: scott worley <scott.worley@microchip.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/1053827
Commit-Ready: Randall Spangler <rspangler@chromium.org>
Tested-by: Scott Worley <scott.worley@microchip.corp-partner.google.com>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/mchp/gpio.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/chip/mchp/gpio.c b/chip/mchp/gpio.c index 8a89619fbc..282c643a95 100644 --- a/chip/mchp/gpio.c +++ b/chip/mchp/gpio.c @@ -26,9 +26,10 @@ struct gpio_int_mapping { int8_t port_offset; }; -/* TODO will this mapping change for other MEC chips? +/* * Mapping from GPIO port to GIRQ info - * MEC1701 each bank contains 32 GPIO's. Pin Id is the bit position [0:31] + * MEC17xx each bank contains 32 GPIO's. + * Pin Id is the bit position [0:31] * Bank GPIO's GIRQ * 0 0000 - 0036 11 * 1 0040 - 0076 10 @@ -369,40 +370,53 @@ DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); * GPIO interrupt handlers. * * @param girq GIRQ index - * @param port_offset GPIO port offset for the given GIRQ + * @param port zero based GPIO port number [0, 5] + * @note __builtin_ffs(x) returns bitpos+1 of least significant 1-bit + * in x or 0 if no bits are set. */ -static void gpio_interrupt(int girq) +static void gpio_interrupt(int girq, int port) { int i, bit; const struct gpio_info *g = gpio_list; uint32_t sts = MCHP_INT_RESULT(girq); - /* CPRINTS("MEC1701 GPIO GIRQ %d result = 0x%08x", girq, sts); */ - trace12(0, GPIO, 0, "GPIO GIRQ %d result = 0x%08x", girq, sts); - /* RW1C, no need for read-modify-write */ MCHP_INT_SOURCE(girq) = sts; - for (i = 0; i < GPIO_IH_COUNT && sts; ++i, ++g) { - bit = __builtin_ffs(g->mask) - 1; - if (sts & (1 << bit)) - gpio_irq_handlers[i](i); - sts &= ~(1 << bit); + trace12(0, GPIO, 0, "GPIO GIRQ %d result = 0x%08x", girq, sts); + trace12(0, GPIO, 0, "GPIO ParIn[%d] = 0x%08x", + port, MCHP_GPIO_PARIN(port)); + + for (i = 0; (i < GPIO_IH_COUNT) && sts; ++i, ++g) { + if (g->port != port) + continue; + + bit = __builtin_ffs(g->mask); + if (bit) { + bit--; + if (sts & (1 << bit)) { + trace12(0, GPIO, 0, + "Bit[%d]: handler @ 0x%08x", bit, + (uint32_t)gpio_irq_handlers[i]); + gpio_irq_handlers[i](i); + } + sts &= ~(1 << bit); + } } } -#define GPIO_IRQ_FUNC(irqfunc, girq) \ +#define GPIO_IRQ_FUNC(irqfunc, girq, port)\ void irqfunc(void) \ { \ - gpio_interrupt(girq); \ + gpio_interrupt(girq, port);\ } -GPIO_IRQ_FUNC(__girq_8_interrupt, 8); -GPIO_IRQ_FUNC(__girq_9_interrupt, 9); -GPIO_IRQ_FUNC(__girq_10_interrupt, 10); -GPIO_IRQ_FUNC(__girq_11_interrupt, 11); -GPIO_IRQ_FUNC(__girq_12_interrupt, 12); -GPIO_IRQ_FUNC(__girq_26_interrupt, 26); +GPIO_IRQ_FUNC(__girq_8_interrupt, 8, 3); +GPIO_IRQ_FUNC(__girq_9_interrupt, 9, 2); +GPIO_IRQ_FUNC(__girq_10_interrupt, 10, 1); +GPIO_IRQ_FUNC(__girq_11_interrupt, 11, 0); +GPIO_IRQ_FUNC(__girq_12_interrupt, 12, 4); +GPIO_IRQ_FUNC(__girq_26_interrupt, 26, 5); #undef GPIO_IRQ_FUNC |