summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-09-12 16:45:18 -0700
committerGerrit <chrome-bot@google.com>2012-09-17 12:16:01 -0700
commitc0a2d9befb9863f4569c302b5137e6a666722436 (patch)
treeb9031f2c68f787dd9c6e4c1a9912baa206b68f20
parent78474d4eeb29537e7fd0ca071cf0a78a464e5f90 (diff)
downloadchrome-ec-c0a2d9befb9863f4569c302b5137e6a666722436.tar.gz
Reset LPC from-host channel status on LPC reset
This works around a LM4 bug where the LPC module stops triggering interrupts for a channel if bytes are written too rapidly to that channel. This should only affect port 80 because other channels use busy-status-handshaking to avoid flooding the EC. BUG=chrome-os-partner:12349 BRANCH=link TEST=manual 1. From a root shell: ectool port80flood 2. Repeat until the EC console stops showing port 80 codes coming in 3. From a root shell: reboot 4. Port 80 codes should be printed by EC as the BIOS boots Change-Id: I3b3463ce668727cad9900b576fdeb531986a415e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/33142 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--chip/lm4/lpc.c14
-rw-r--r--chip/lm4/registers.h1
-rw-r--r--util/ectool.c12
3 files changed, 25 insertions, 2 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index 74c31ebd97..34929285a2 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -573,10 +573,20 @@ static void lpc_interrupt(void)
/* Debugging: print changes to LPC0RESET */
if (mis & (1 << 31)) {
- /* Store port 80 event so we know where reset happened */
- if (LM4_LPC_LPCSTS & (1 << 10))
+ if (LM4_LPC_LPCSTS & (1 << 10)) {
+ int i;
+
+ /* Store port 80 reset event */
port_80_write(PORT_80_EVENT_RESET);
+ /*
+ * Workaround for crosbug.com/p/12349; clear all FRMH
+ * bits so host writes will trigger interrupts.
+ */
+ for (i = 0; i < 8; i++)
+ LM4_LPC_ST(i) &= ~LM4_LPC_ST_FRMH;
+ }
+
CPRINTF("[%T LPC RESET# %sasserted]\n",
(LM4_LPC_LPCSTS & (1<<10)) ? "" : "de");
}
diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h
index 2a481abe2b..f351bb2814 100644
--- a/chip/lm4/registers.h
+++ b/chip/lm4/registers.h
@@ -119,6 +119,7 @@ static inline int lm4_lpc_addr(int ch, int offset)
#define LM4_LPC_CTL(ch) LM4LPCREG(ch, 0x000)
#define LM4_LPC_ST(ch) LM4LPCREG(ch, 0x004)
#define LM4_LPC_ST_TOH (1 << 0) /* TO Host bit */
+#define LM4_LPC_ST_FRMH (1 << 1) /* FRoM Host bit */
#define LM4_LPC_ST_CMD (1 << 3) /* Last from-host byte was command */
#define LM4_LPC_ST_PRESENT (1 << 8)
#define LM4_LPC_ST_SCI (1 << 9)
diff --git a/util/ectool.c b/util/ectool.c
index 4fbc6ce781..b4e9dd20a0 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -92,6 +92,8 @@ const char help_str[] =
" Write I2C bus\n"
" lightbar [CMDS]\n"
" Various lightbar control commands\n"
+ " port80flood\n"
+ " Rapidly write bytes to port 80\n"
" pstoreinfo\n"
" Prints information on the EC host persistent storage\n"
" pstoreread <offset> <size> <outfile>\n"
@@ -2190,6 +2192,15 @@ int cmd_console(int argc, char *argv[])
return 0;
}
+/* Flood port 80 with byte writes */
+int cmd_port_80_flood(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ outb(i, 0x80);
+ return 0;
+}
struct command {
const char *name;
@@ -2243,6 +2254,7 @@ const struct command commands[] = {
{"rtcget", cmd_rtc_get},
{"rtcset", cmd_rtc_set},
{"sertest", cmd_serial_test},
+ {"port80flood", cmd_port_80_flood},
{"switches", cmd_switches},
{"temps", cmd_temperature},
{"tempsinfo", cmd_temp_sensor_info},