google/chromeec: Ensure data is ready before reading it
Before reading the data provided by EC to the host, ensure that data ready flag is set. Otherwise, it could result in reading stale/incorrect data from the data buffer. BUG=chrome-os-partner:56395 BRANCH=None TEST=Verified that lidclose event is read correctly by host on reef. Change-Id: I88e345d64256af8325b3dbf670467d09f09420f0 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://review.coreboot.org/16258 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
3828e55a8c
commit
63e424cec2
|
@ -96,7 +96,7 @@ static inline u8 write_byte(u8 val, u16 port)
|
||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int google_chromeec_wait_ready(u16 port)
|
static int google_chromeec_status_check(u16 port, u8 mask, u8 cond)
|
||||||
{
|
{
|
||||||
u8 ec_status = read_byte(port);
|
u8 ec_status = read_byte(port);
|
||||||
u32 time_count = 0;
|
u32 time_count = 0;
|
||||||
|
@ -108,8 +108,7 @@ static int google_chromeec_wait_ready(u16 port)
|
||||||
*/
|
*/
|
||||||
#define MAX_EC_TIMEOUT_US 1000000
|
#define MAX_EC_TIMEOUT_US 1000000
|
||||||
|
|
||||||
while (ec_status &
|
while ((ec_status & mask) != cond) {
|
||||||
(EC_LPC_CMDR_PENDING | EC_LPC_CMDR_BUSY)) {
|
|
||||||
udelay(1);
|
udelay(1);
|
||||||
if (time_count++ == MAX_EC_TIMEOUT_US)
|
if (time_count++ == MAX_EC_TIMEOUT_US)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -118,6 +117,13 @@ static int google_chromeec_wait_ready(u16 port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int google_chromeec_wait_ready(u16 port)
|
||||||
|
{
|
||||||
|
return google_chromeec_status_check(port,
|
||||||
|
EC_LPC_CMDR_PENDING |
|
||||||
|
EC_LPC_CMDR_BUSY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#if CONFIG_EC_GOOGLE_CHROMEEC_ACPI_MEMMAP
|
#if CONFIG_EC_GOOGLE_CHROMEEC_ACPI_MEMMAP
|
||||||
/* Read memmap data through ACPI port 66/62 */
|
/* Read memmap data through ACPI port 66/62 */
|
||||||
static int read_memmap(u8 *data, u8 offset)
|
static int read_memmap(u8 *data, u8 offset)
|
||||||
|
@ -481,6 +487,12 @@ struct chip_operations ec_google_chromeec_ops = {
|
||||||
|
|
||||||
#endif /* __SMM__ */
|
#endif /* __SMM__ */
|
||||||
|
|
||||||
|
static int google_chromeec_data_ready(u16 port)
|
||||||
|
{
|
||||||
|
return google_chromeec_status_check(port, EC_LPC_CMDR_DATA,
|
||||||
|
EC_LPC_CMDR_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
u8 google_chromeec_get_event(void)
|
u8 google_chromeec_get_event(void)
|
||||||
{
|
{
|
||||||
if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
|
if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
|
||||||
|
@ -496,6 +508,11 @@ u8 google_chromeec_get_event(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (google_chromeec_data_ready(EC_LPC_ADDR_ACPI_CMD)) {
|
||||||
|
printk(BIOS_ERR, "Timeout waiting for data ready!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Event (or 0 if none) is returned directly in the data byte */
|
/* Event (or 0 if none) is returned directly in the data byte */
|
||||||
return read_byte(EC_LPC_ADDR_ACPI_DATA);
|
return read_byte(EC_LPC_ADDR_ACPI_DATA);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue