summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorchrome-bot <chrome-bot@google.com>2012-02-03 00:45:52 -0800
committerGerrit Code Review <gerrit@gerrit-int.golo.chromium.org>2012-02-03 00:45:52 -0800
commit249467b9f291e2b10a7aafdbb584c68c8b0a4e88 (patch)
treeea04ae0e2a81c49a04b737d6b8a81a6d2f053cdc /chip
parenta72b9cc07ea79a89bd08e3b80ac3e84136016ba2 (diff)
parent088b79f285fe2dcfac2babb3b1fca6c27a4e2bf6 (diff)
downloadchrome-ec-249467b9f291e2b10a7aafdbb584c68c8b0a4e88.tar.gz
Merge "Use udelay for more stable manual IRQ firing."
Diffstat (limited to 'chip')
-rw-r--r--chip/lm4/lpc.c24
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;
}