diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-09-17 12:40:01 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-09-17 18:06:33 -0700 |
commit | 72948eaf4e7829ee5af59f2d7e3edd0b983723ef (patch) | |
tree | 283ca00e54c949688d46fc0d81fe6ebb89f90b80 | |
parent | c0a2d9befb9863f4569c302b5137e6a666722436 (diff) | |
download | chrome-ec-72948eaf4e7829ee5af59f2d7e3edd0b983723ef.tar.gz |
Improve handling of bursts of port 80 writes
Loop on FRMH bit set in the interrupt handler. This has 2 benefits:
1) FRMH is checked every LPC interrupt. So if port 80 gets stuck, any
LPC activity like keyboard or host commands will unstick it.
2) Bursts of rapid writes to port 80 are captured more accurately.
This also seems to prevent the port 80 channel from getting stuck.
There's a small drawback that if the host spams port 80 non-stop for
several seconds it can watchdog the EC, but if the host has access to
write to I/O ports it could already accomplish a similar result simply
by writing the 0xd1 reboot command to the host interface.
BUG=chrome-os-partner:12349
BRANCH=link
TEST=manual
1. From a root shell, 'ectool port80flood' repeatedly (20x or so).
2. Reboot. Port 80 codes should still be captured.
Change-Id: I7a51dfe6a384a0d08cfeb91a539217fc59488637
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/33444
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | chip/lm4/lpc.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c index 34929285a2..21314267b2 100644 --- a/chip/lm4/lpc.c +++ b/chip/lm4/lpc.c @@ -539,8 +539,14 @@ static void lpc_interrupt(void) } #endif - /* Handle port 80 writes (CH0MIS1) */ - if (mis & LM4_LPC_INT_MASK(LPC_CH_PORT80, 2)) + /* + * Handle port 80 writes (CH0MIS1). Due to crosbug.com/p/12349 the + * interrupt status (mis & LM4_LPC_INT_MASK(LPC_CH_PORT80, 2)) + * apparently gets lost on back-to-back writes to port 80, so check the + * FRMH bit in the channel status register to see if a write is + * pending. Loop to handle bursts of back-to-back writes. + */ + while (LM4_LPC_ST(LPC_CH_PORT80) & LM4_LPC_ST_FRMH) port_80_write(LPC_POOL_PORT80[0]); #ifdef CONFIG_TASK_I8042CMD |