summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2012-02-03 11:12:30 +0800
committerLouis Yung-Chieh Lo <yjlou@chromium.org>2012-02-03 12:38:42 +0800
commit088b79f285fe2dcfac2babb3b1fca6c27a4e2bf6 (patch)
tree07bce9ac50027263eb7d52aeb7b4293995447995 /chip
parent54f36995a4b626280b868f1efe6049591f3fc53c (diff)
downloadchrome-ec-088b79f285fe2dcfac2babb3b1fca6c27a4e2bf6.tar.gz
Use udelay for more stable manual IRQ firing.
Original code tests SND bit, but it is not reliable to indicate the SERIRQ frame has been sent out because the EC always clears it immediately. Unfortunately the SIRQRIS is always asserted in continuous mode so that we cannot rely on it. So, the udelay(4us) method is the best way we can use now. Note: the quiet mode? Forget it. My EC never sends out further frames after the first has been sent. BUG=none TEST=on bds board. Change-Id: Ica79b463f3dbe7435fe75f3db4cef00ad7ad5ec0
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;
}