summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-04-03 16:42:06 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-04-03 23:54:26 +0000
commit569651b82e309ddd86b9c165d131e34cb7f7b2b5 (patch)
tree9dc9d7f25e3944509d7be05cbb8d1d3c82d2e38b
parent6a9cebfb94f85215c3c3dd430d6c00b3d0eec178 (diff)
downloadchrome-ec-569651b82e309ddd86b9c165d131e34cb7f7b2b5.tar.gz
lm4: Ensure falling edges on outputs to edge-sensitive host inputs
The KBD_IRQ#, SMI#, and SCI# lines on the host are sensitive to falling edges. When generating an interrupt, wait long enough to make sure the lines are high before pulling them low, so that it reliably generates a falling edge. This solves a problem where calling the IRQ-generation function twice in rapid succession could cause two low pulses without an intervening logic-high as seen by the host (and thus not a falling edge as seen by the host). This is most visible on the keyboard line, because it can generate back-to-back events on multi-byte scan codes. Once the keyboard mailbox is full, the EC will never attempt to fill it, and thus it also won't attempt to generate another keyboard IRQ. And since the host missed the IRQ, it doesn't know it needs to empty the mailbox. It could theoretically happen for the other lines, so fix them now just to be safe. This change should be low-impact and free from side effects. 4 usec is a very small additional delay. Even 65 usec added delay for SCI/SMI is small, given that SCI/SMI events are typically much less frequent (if they're happening very frequently, something else is tragically wrong with the system...) BUG=chrome-os-partner:27222 BRANCH=rambi TEST=Bang on the keyboard like a monkey. Keyboard shouldn't get stuck. Change-Id: Id4e6de793b1f007f713bac8aa195ddd78feeea3e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/193173 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-by: Benson Leung <bleung@chromium.org>
-rw-r--r--chip/lm4/lpc.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index aa15e1fbfe..eb1e53a802 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -86,9 +86,18 @@ static void wait_irq_sent(void)
#ifdef CONFIG_KEYBOARD_IRQ_GPIO
static void keyboard_irq_assert(void)
{
- /* Negative edge-triggered keyboard interrupt. */
+ /*
+ * Enforce signal-high for long enough for the signal to be pulled high
+ * by the external pullup resistor. This ensures the host will see the
+ * following falling edge, regardless of the line state before this
+ * function call.
+ */
+ gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
+ udelay(4);
+ /* Generate a falling edge */
gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 0);
- wait_irq_sent();
+ udelay(4);
+ /* Set signal high, now that we've generated the edge */
gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
}
#else
@@ -139,8 +148,13 @@ static inline void keyboard_irq_assert(void)
*/
static void lpc_generate_smi(void)
{
+ /* Enforce signal-high for long enough to debounce high */
+ gpio_set_level(GPIO_PCH_SMI_L, 1);
+ udelay(65);
+ /* Generate a falling edge */
gpio_set_level(GPIO_PCH_SMI_L, 0);
udelay(65);
+ /* Set signal high, now that we've generated the edge */
gpio_set_level(GPIO_PCH_SMI_L, 1);
if (host_events & event_mask[LPC_HOST_EVENT_SMI])
@@ -154,8 +168,13 @@ static void lpc_generate_smi(void)
static void lpc_generate_sci(void)
{
#ifdef CONFIG_SCI_GPIO
+ /* Enforce signal-high for long enough to debounce high */
+ gpio_set_level(CONFIG_SCI_GPIO, 1);
+ udelay(65);
+ /* Generate a falling edge */
gpio_set_level(CONFIG_SCI_GPIO, 0);
udelay(65);
+ /* Set signal high, now that we've generated the edge */
gpio_set_level(CONFIG_SCI_GPIO, 1);
#else
LM4_LPC_LPCCTL |= LM4_LPC_SCI_START;