ec/acpi: add mechanisms to clear EC output queue

EC's output could be considered as a queue, and sometimes (observed on
Thinkpad T400s during cold boot) a few (only one observed) garbage bytes
may detained in such queue after power up. Those garbage bytes should be
checked and discarded first before real interactions, otherwise they may
disrupt the interaction during EC's enablement, causing a locked rfkill.

Change-Id: Iee031306c02f5211a4512c6b4ec90f7f0db196ae
Signed-off-by: Bill XIE <persmule@gmail.com>
Reviewed-on: https://review.coreboot.org/22180
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Bill XIE 2017-10-26 11:45:49 +08:00 committed by Patrick Georgi
parent c467334620
commit eb4ded6925
2 changed files with 16 additions and 0 deletions

View File

@ -111,6 +111,21 @@ u8 recv_ec_data(void)
return data;
}
void ec_clear_out_queue(void)
{
int timeout = 0x7fff;
printk(BIOS_SPEW, "Clearing EC output queue...\n");
while (--timeout && (inb(ec_cmd_reg) & EC_OBF)) {
u8 data = inb(ec_data_reg);
printk(BIOS_SPEW, "Discarding a garbage byte: 0x%02x\n", data);
udelay(10);
}
if (!timeout)
printk(BIOS_ERR, "Timeout while clearing EC output queue!\n");
else
printk(BIOS_SPEW, "EC output queue has been cleared.\n");
}
u8 ec_read(u8 addr)
{
send_ec_command(0x80);

View File

@ -40,6 +40,7 @@ int send_ec_command(u8 command);
int send_ec_data(u8 data);
int send_ec_data_nowait(u8 data);
u8 recv_ec_data(void);
void ec_clear_out_queue(void);
u8 ec_status(void);
u8 ec_query(void);
u8 ec_read(u8 addr);