Move ACPI query-event handling to LPC interrupt

And only support it for port 62/66.

Also remove 'ectool queryec', because it can't touch port 62/66 once
the kernel/ACPI owns it, and query-event isn't supported on the user
command port.

BUG=chrome-os-partner:11240
TEST=boot system and check EC console output; should see event clears between
host commands 0x23, 0x8e, but no hostcmd 0x84.

[0.396780 LPC RESET# deasserted]
[0.486953 Port 80: 0x29]
[0.487415 hostcmd1 0x23]
[0.764407 Port 80: 0x88]
[0.764579 event clear 0x00000008 -> 00002080]
[0.764928 event clear 0x00000080 -> 00002000]
[0.765224 event clear 0x00002000 -> 00000000]
[0.765578 hostcmd1 0x8e]
[0.765868 hostcmd1 0x06]

Change-Id: I8ed161dbccd396d685ddf6829a27dfef87d919fb
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27095
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
Randall Spangler
2012-07-10 16:30:52 -07:00
committed by Gerrit
parent 2daf748e0e
commit f2400b869e
4 changed files with 51 additions and 55 deletions

View File

@@ -319,6 +319,53 @@ uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
}
/* Handle an ACPI command on the kernel channel */
static void handle_acpi_command(void)
{
int cmd;
int result = 0;
int i;
/* Set the busy bit */
LM4_LPC_ST(LPC_CH_KERNEL) |= (1 << 12);
/*
* Read the command byte and pass to the host command handler.
* This clears the FRMH bit in the status byte.
*/
cmd = LPC_POOL_KERNEL[0];
/* Process the command */
switch (cmd) {
case EC_CMD_ACPI_QUERY_EVENT:
for (i = 0; i < 32; i++) {
if (host_events & (1 << i)) {
lpc_clear_host_events(1 << i);
result = i + 1; /* Events are 1-based */
break;
}
}
break;
default:
/* Something we don't handle; ignore it */
break;
}
/* Write the response */
LPC_POOL_KERNEL[1] = result;
/* Clear the busy bit */
LM4_LPC_ST(LPC_CH_KERNEL) &= ~(1 << 12);
/*
* ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty / Output Buffer
* Full condition on the kernel channel.
*/
lpc_generate_sci();
}
/* LPC interrupt handler */
static void lpc_interrupt(void)
{
@@ -329,18 +376,9 @@ static void lpc_interrupt(void)
#ifdef CONFIG_TASK_HOSTCMD
/* Handle host kernel/user command writes */
if (mis & LM4_LPC_INT_MASK(LPC_CH_KERNEL, 4)) {
/* Set the busy bit */
LM4_LPC_ST(LPC_CH_KERNEL) |= (1 << 12);
if (mis & LM4_LPC_INT_MASK(LPC_CH_KERNEL, 4))
handle_acpi_command();
/* Read the command byte and pass to the host command handler.
* This clears the FRMH bit in the status byte. */
host_command_received(0, LPC_POOL_KERNEL[0]);
/* ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty
* condition on the kernel channel. */
lpc_generate_sci();
}
if (mis & LM4_LPC_INT_MASK(LPC_CH_USER, 4)) {
/* Set the busy bit */
LM4_LPC_ST(LPC_CH_USER) |= (1 << 12);

View File

@@ -132,29 +132,6 @@ static int host_command_read_memmap(uint8_t *data, int *resp_size)
DECLARE_HOST_COMMAND(EC_CMD_READ_MEMMAP, host_command_read_memmap);
#endif
#ifdef CONFIG_LPC
/* ACPI query event handler. Note that the returned value is NOT actually
* an EC_RES enum; it's 0 if no event was pending, or the 1-based
* index of the lowest bit which was set. */
static int host_command_acpi_query_event(uint8_t *data, int *resp_size)
{
uint32_t events = lpc_get_host_events();
int i;
for (i = 0; i < 32; i++) {
if (events & (1 << i)) {
lpc_clear_host_events(1 << i);
return i + 1;
}
}
/* No events pending */
return 0;
}
DECLARE_HOST_COMMAND(EC_CMD_ACPI_QUERY_EVENT, host_command_acpi_query_event);
#endif /* CONFIG_LPC */
/* Finds a command by command number. Returns the command structure, or NULL if
* no match found. */
static const struct host_command *find_host_command(int command)

View File

@@ -760,6 +760,8 @@ struct ec_params_reboot_ec {
* This clears the lowest-order bit in the currently pending host events, and
* sets the result code to the 1-based index of the bit (event 0x00000001 = 1,
* event 0x80000000 = 32), or 0 if no event was pending.
*
* This command is valid ONLY on port 62/66.
*/
#define EC_CMD_ACPI_QUERY_EVENT 0x84

View File

@@ -1230,26 +1230,6 @@ int cmd_pstore_write(int argc, char *argv[])
}
int cmd_acpi_query_ec(int argc, char *argv[])
{
int rv;
rv = ec_command(EC_CMD_ACPI_QUERY_EVENT, NULL, 0, NULL, 0);
if (rv < 0) {
/*
* ACPI query-event follows different rules for its return
* code; it returns the next pending event instead of an error
* code. So turn the return code back into a positive number.
*/
rv = -rv;
printf("Got host event %d (mask 0x%08x)\n", rv, 1 << (rv - 1));
} else {
printf("No host event pending.\n");
}
return 0;
}
int cmd_host_event_get_raw(int argc, char *argv[])
{
uint32_t events = read_mapped_mem32(EC_MEMMAP_HOST_EVENTS);
@@ -1720,7 +1700,6 @@ const struct command commands[] = {
{"pwmgetkblight", cmd_pwm_get_keyboard_backlight},
{"pwmsetfanrpm", cmd_pwm_set_fan_rpm},
{"pwmsetkblight", cmd_pwm_set_keyboard_backlight},
{"queryec", cmd_acpi_query_ec},
{"readtest", cmd_read_test},
{"reboot_ec", cmd_reboot_ec},
{"sertest", cmd_serial_test},