mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 02:35:28 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user