mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-05 14:31:31 +00:00
Simplify host event processing
Now both copies of the event state live in host_event_commands.c, and lpc / memmap just shadows the main copy. BUG=chrome-os-partner:11172 TEST=manual Boot system. should see events 0x2000, 0x80, 0x08 get set and then cleared. At U-boot prompt, type on keyboard. Should set event 0x1000 get set, but only on the first keypress (because U-boot doesn't consume that event). Then from EC console, hostevent clear 0x1000 -> see event 0x1000 clear hostevent clear 0x1000 -> no debug output (it's already clear) hostevent clearb 0x1000 -> see event copy B 0x1000 clear hostevent clearb 0x1000 -> no debug output (copy B is already clear) Change-Id: I855c035865649ba1490cd9027157d5bcdcc9895f Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/27321
This commit is contained in:
@@ -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)
|
||||
void lpc_set_host_event_state(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();
|
||||
if (mask != host_events) {
|
||||
host_events = mask;
|
||||
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)
|
||||
{
|
||||
return host_events;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ static const char *channel_names[CC_CHANNEL_COUNT] = {
|
||||
"charger",
|
||||
"chipset",
|
||||
"dma",
|
||||
"events",
|
||||
"gpio",
|
||||
"hostcmd",
|
||||
"i2c",
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* This is separate from the main copy, which affects ACPI/SCI/SMI/wake.
|
||||
* The primary copy is mirrored in mapped memory and used to trigger interrupts
|
||||
* on the host via ACPI/SCI/SMI/GPIO.
|
||||
*
|
||||
* Setting an event sets both copies. Copies are cleared separately. */
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ enum console_channel {
|
||||
CC_CHARGER,
|
||||
CC_CHIPSET,
|
||||
CC_DMA,
|
||||
CC_EVENTS,
|
||||
CC_GPIO,
|
||||
CC_HOSTCMD,
|
||||
CC_I2C,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user