summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscott worley <scott.worley@microchip.corp-partner.google.com>2018-05-10 09:12:08 -0400
committerchrome-bot <chrome-bot@chromium.org>2018-05-22 21:57:04 -0700
commit67ed6ee3e79400996e276c87eeb32765f6d124e2 (patch)
tree97b87ba57e930d862c3736c6cb4ce7ed5374e728
parentb34a5973cd8a5cc66c4c931a86317a114f68d792 (diff)
downloadchrome-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.c54
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