diff options
-rw-r--r-- | chip/lm4/lpc.c | 49 | ||||
-rw-r--r-- | common/console_output.c | 1 | ||||
-rw-r--r-- | common/host_event_commands.c | 50 | ||||
-rw-r--r-- | include/console.h | 1 | ||||
-rw-r--r-- | include/lpc.h | 26 |
5 files changed, 65 insertions, 62 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c index 993208679d..597eb80f71 100644 --- a/chip/lm4/lpc.c +++ b/chip/lm4/lpc.c @@ -248,15 +248,13 @@ void lpc_comx_put_char(int c) } -/* Update the host event status. - * Sends a pulse if masked event status becomes non-zero: - * SMI pulse via EC_SMIn GPIO - * SCI pulse via LPC0SCI +/** + * Update the host event status. Sends a pulse if masked event status becomes + * non-zero: + * - SMI pulse via EC_SMIn GPIO + * - SCI pulse via LPC0SCI */ static void update_host_event_status(void) { - uint32_t *mapped_raw_events = - (uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS); - int need_sci = 0; int need_smi = 0; @@ -279,7 +277,7 @@ static void update_host_event_status(void) { LM4_LPC_ST(LPC_CH_ACPI) &= ~LPC_STATUS_MASK_SCI; /* Copy host events to mapped memory */ - *mapped_raw_events = host_events; + *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events; task_enable_irq(LM4_IRQ_LPC); @@ -298,48 +296,25 @@ static void update_host_event_status(void) { lpc_generate_sci(); } - -void lpc_set_host_events(uint32_t mask) -{ - if ((host_events & mask) == mask) - return; - - host_events |= mask; - CPRINTF("[%T event set 0x%08x -> %08x]\n", mask, host_events); - update_host_event_status(); -} - - -void lpc_clear_host_events(uint32_t mask) -{ - if (!(host_events & mask)) - return; - - host_events &= ~mask; - CPRINTF("[%T event clear 0x%08x -> %08x]\n", mask, host_events); - update_host_event_status(); -} - - -uint32_t lpc_get_host_events(void) +void lpc_set_host_event_state(uint32_t mask) { - return host_events; + if (mask != host_events) { + host_events = mask; + update_host_event_status(); + } } - void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask) { event_mask[type] = mask; update_host_event_status(); } - uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type) { return event_mask[type]; } - /* Handle an ACPI command */ static void handle_acpi_command(void) { @@ -361,7 +336,7 @@ static void handle_acpi_command(void) case EC_CMD_ACPI_QUERY_EVENT: for (i = 0; i < 32; i++) { if (host_events & (1 << i)) { - lpc_clear_host_events(1 << i); + host_clear_events(1 << i); result = i + 1; /* Events are 1-based */ break; } diff --git a/common/console_output.c b/common/console_output.c index e9f7bf0d97..e3334ee20d 100644 --- a/common/console_output.c +++ b/common/console_output.c @@ -22,6 +22,7 @@ static const char *channel_names[CC_CHANNEL_COUNT] = { "charger", "chipset", "dma", + "events", "gpio", "hostcmd", "i2c", diff --git a/common/host_event_commands.c b/common/host_event_commands.c index b4a161068a..670212c430 100644 --- a/common/host_event_commands.c +++ b/common/host_event_commands.c @@ -12,41 +12,59 @@ #include "lpc.h" #include "util.h" -/* Copy B of current events mask. +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_EVENTS, outstr) +#define CPRINTF(format, args...) cprintf(CC_EVENTS, format, ## args) + +/* + * Maintain two copies of the events that are set. + * + * The primary copy is mirrored in mapped memory and used to trigger interrupts + * on the host via ACPI/SCI/SMI/GPIO. * - * This is separate from the main copy, which affects ACPI/SCI/SMI/wake. + * The secondary (B) copy is used to track events at a non-interrupt level (for + * example, so a user-level process can find out what events have happened + * since the last call, even though a kernel-level process is consuming events + * from the first copy). * - * Setting an event sets both copies. Copies are cleared separately. */ + * Setting an event sets both copies. Copies are cleared separately. + */ +static uint32_t events; static uint32_t events_copy_b; uint32_t host_get_events(void) { -#ifdef CONFIG_LPC - return lpc_get_host_events(); -#else - uint32_t *mapped_raw_events = - (uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS); - return *mapped_raw_events; -#endif + return events; } void host_set_events(uint32_t mask) { + /* Only print if something's about to change */ + if ((events & mask) != mask || (events_copy_b & mask) != mask) + CPRINTF("[%T event set 0x%08x]\n", mask); + + atomic_or(&events, mask); atomic_or(&events_copy_b, mask); #ifdef CONFIG_LPC - lpc_set_host_events(mask); + lpc_set_host_event_state(events); #else - *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) |= mask; + *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events; #endif } void host_clear_events(uint32_t mask) { + /* Only print if something's about to change */ + if (events & mask) + CPRINTF("[%T event clear 0x%08x]\n", mask); + + atomic_clear(&events, mask); + #ifdef CONFIG_LPC - lpc_clear_host_events(mask); + lpc_set_host_event_state(events); #else - *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) &= ~mask; + *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events; #endif } @@ -58,6 +76,10 @@ void host_clear_events(uint32_t mask) */ static void host_clear_events_b(uint32_t mask) { + /* Only print if something's about to change */ + if (events_copy_b & mask) + CPRINTF("[%T event clear B 0x%08x]\n", mask); + atomic_clear(&events_copy_b, mask); } diff --git a/include/console.h b/include/console.h index 37d44bfc55..66bc5ba8e3 100644 --- a/include/console.h +++ b/include/console.h @@ -33,6 +33,7 @@ enum console_channel { CC_CHARGER, CC_CHIPSET, CC_DMA, + CC_EVENTS, CC_GPIO, CC_HOSTCMD, CC_I2C, diff --git a/include/lpc.h b/include/lpc.h index e9f5cad690..8c33b401b2 100644 --- a/include/lpc.h +++ b/include/lpc.h @@ -10,13 +10,16 @@ #include "common.h" -/* Manually generate an IRQ to host. +/* + * Manually generate an IRQ to host. * Note that the irq_num == 0 would set the AH bit (Active High). */ void lpc_manual_irq(int irq_num); -/* Return a pointer to the memory-mapped buffer. This buffer is writable at - * any time, and the host can read it at any time. */ +/* + * Return a pointer to the memory-mapped buffer. This buffer is writable at + * any time, and the host can read it at any time. + */ uint8_t *lpc_get_memmap_range(void); /* Return true if the TOH is still set */ @@ -40,6 +43,13 @@ int lpc_comx_get_char(void); /* Put a character to the COMx LPC interface. */ void lpc_comx_put_char(int c); +/* + * Low-level LPC interface for host events. + * + * For use by host_event_commands.c. Other modules should use the methods + * provided in host_command.h. + */ + /* Types of host events */ enum lpc_host_event_type { LPC_HOST_EVENT_SMI = 0, @@ -47,14 +57,8 @@ enum lpc_host_event_type { LPC_HOST_EVENT_WAKE, }; -/* Set one or more SCI/SMI event bits. */ -void lpc_set_host_events(uint32_t mask); - -/* Clear one or more SCI/SMI event bits. Write 1 to a bit to clear it. */ -void lpc_clear_host_events(uint32_t mask); - -/* Return the raw SCI/SMI event state. */ -uint32_t lpc_get_host_events(void); +/* Set the event state */ +void lpc_set_host_event_state(uint32_t mask); /* Set the event mask for the specified event type. */ void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask); |