diff options
author | chrome-bot <chrome-bot@google.com> | 2012-02-03 00:45:52 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit-int.golo.chromium.org> | 2012-02-03 00:45:52 -0800 |
commit | 249467b9f291e2b10a7aafdbb584c68c8b0a4e88 (patch) | |
tree | ea04ae0e2a81c49a04b737d6b8a81a6d2f053cdc /chip | |
parent | a72b9cc07ea79a89bd08e3b80ac3e84136016ba2 (diff) | |
parent | 088b79f285fe2dcfac2babb3b1fca6c27a4e2bf6 (diff) | |
download | chrome-ec-249467b9f291e2b10a7aafdbb584c68c8b0a4e88.tar.gz |
Merge "Use udelay for more stable manual IRQ firing."
Diffstat (limited to 'chip')
-rw-r--r-- | chip/lm4/lpc.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c index fae068343f..e7841576ec 100644 --- a/chip/lm4/lpc.c +++ b/chip/lm4/lpc.c @@ -14,6 +14,7 @@ #include "port80.h" #include "registers.h" #include "task.h" +#include "timer.h" #include "uart.h" @@ -37,6 +38,17 @@ static void configure_gpio(void) } +static void wait_send_serirq(uint32_t lpcirqctl) { + LM4_LPC_LPCIRQCTL = lpcirqctl; + + /* TODO: udelay() is not graceful. Since the SIRQRIS is almost not + * cleared in continuous mode and EC has problem to file + * more than 1 frame in the quiet mode, this is the best way + * we can do right now. */ + udelay(4); /* 4 us is the time of 2 SERIRQ frames, which is long + * enough to guarantee the IRQ has been sent out. */ +} + /* Manually generates an IRQ to host (edge-trigger). * * For SERIRQ quite mode, we need to set LM4_LPC_LPCIRQCTL twice. @@ -51,13 +63,11 @@ void lpc_manual_irq(int irq_num) { 0x00000002 | /* ONCHG - for quiet mode */ 0x00000001; /* SND - send immediately */ - while (LM4_LPC_LPCIRQCTL & 1); /* wait until SND is cleared */ - LM4_LPC_LPCIRQCTL = (1 << (irq_num + 16)) | common_bits; + /* send out the IRQ first. */ + wait_send_serirq((1 << (irq_num + 16)) | common_bits); - while (LM4_LPC_LPCIRQCTL & 1); /* wait until SND is cleared */ - LM4_LPC_LPCIRQCTL = common_bits; /* generate a all-high frame to - * simulate a rising edge. */ - while (LM4_LPC_LPCIRQCTL & 1); /* wait until SND is cleared */ + /* generate a all-high frame to simulate a rising edge. */ + wait_send_serirq(common_bits); } @@ -174,7 +184,7 @@ void lpc_send_host_response(int slot, int status) /* Return true if the TOH is still set */ -int lpc_keyboard_has_char() { +int lpc_keyboard_has_char(void) { return (LM4_LPC_ST(LPC_CH_KEYBOARD) & (1 << 0 /* TOH */)) ? 1 : 0; } |