summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/ish/ipc.c11
-rw-r--r--chip/it83xx/lpc.c94
-rw-r--r--chip/lm4/lpc.c110
-rw-r--r--chip/mec1322/lpc.c98
-rw-r--r--chip/npcx/lpc.c103
-rw-r--r--common/acpi.c2
-rw-r--r--common/host_event_commands.c99
-rw-r--r--include/lpc.h27
-rw-r--r--power/intel_x86.c2
9 files changed, 172 insertions, 374 deletions
diff --git a/chip/ish/ipc.c b/chip/ish/ipc.c
index 958a26d440..a50d84d5f2 100644
--- a/chip/ish/ipc.c
+++ b/chip/ish/ipc.c
@@ -235,19 +235,10 @@ static void ipc_send_response_packet(struct host_packet *pkt)
ipc_write(IPC_PEER_HOST_ID, pkt->response, pkt->response_size);
}
-void lpc_set_host_event_state(uint32_t mask)
+void lpc_update_host_event_status(void)
{
}
-void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask)
-{
-}
-
-uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
-{
- return 0;
-}
-
void lpc_clear_acpi_status_mask(uint8_t mask)
{
}
diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c
index a7e1609419..71ce9fa16b 100644
--- a/chip/it83xx/lpc.c
+++ b/chip/it83xx/lpc.c
@@ -30,8 +30,6 @@
#define CPUTS(outstr) cputs(CC_LPC, outstr)
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
-#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
-
/* LPC PM channels */
enum lpc_pm_ch {
LPC_PM1 = 0,
@@ -57,8 +55,6 @@ static uint8_t acpi_ec_memmap[EC_MEMMAP_SIZE]
static uint8_t host_cmd_memmap[256]
__attribute__((section(".h2ram.pool.hostcmd")));
-static uint32_t host_events; /* Currently pending SCI/SMI events */
-static uint32_t event_mask[3]; /* Event masks for each type */
static struct host_packet lpc_packet;
static struct host_cmd_handler_args host_cmd_args;
static uint8_t host_cmd_flags; /* Flags from host command */
@@ -213,7 +209,7 @@ static void lpc_send_response(struct host_cmd_handler_args *args)
pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 0);
}
-static void update_host_event_status(void)
+void lpc_update_host_event_status(void)
{
int need_sci = 0;
int need_smi = 0;
@@ -224,7 +220,7 @@ static void update_host_event_status(void)
/* Disable PMC1 interrupt while updating status register */
task_disable_irq(IT83XX_IRQ_PMC_IN);
- if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) {
/* Only generate SMI for first event */
if (!(pm_get_status(LPC_ACPI_CMD) & EC_LPC_STATUS_SMI_PENDING))
need_smi = 1;
@@ -233,7 +229,7 @@ static void update_host_event_status(void)
pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SMI_PENDING, 0);
}
- if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) {
/* Generate SCI for every event */
need_sci = 1;
pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SCI_PENDING, 1);
@@ -242,12 +238,13 @@ static void update_host_event_status(void)
}
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events;
+ *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ lpc_get_host_events();
task_enable_irq(IT83XX_IRQ_PMC_IN);
/* Process the wake events. */
- lpc_update_wake(host_events & event_mask[LPC_HOST_EVENT_WAKE]);
+ lpc_update_wake(lpc_get_host_events_by_type(LPC_HOST_EVENT_WAKE));
/* Send pulse on SMI signal if needed */
if (need_smi)
@@ -358,54 +355,6 @@ void lpc_keyboard_resume_irq(void)
}
}
-void lpc_set_host_event_state(uint32_t mask)
-{
- if (mask != host_events) {
- host_events = mask;
- update_host_event_status();
- }
-}
-
-int lpc_query_host_event_state(void)
-{
- const uint32_t any_mask = event_mask[0] | event_mask[1] | event_mask[2];
- int evt_index = 0;
- int i;
-
- for (i = 0; i < 32; i++) {
- const uint32_t e = (1 << i);
-
- if (host_events & e) {
- host_clear_events(e);
-
- /*
- * If host hasn't unmasked this event, drop it. We do
- * this at query time rather than event generation time
- * so that the host has a chance to unmask events
- * before they're dropped by a query.
- */
- if (!(e & any_mask))
- continue;
-
- evt_index = i + 1; /* Events are 1-based */
- break;
- }
- }
-
- return evt_index;
-}
-
-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];
-}
-
void lpc_set_acpi_status_mask(uint8_t mask)
{
pm_set_status(LPC_ACPI_CMD, mask, 1);
@@ -600,32 +549,6 @@ void pm5_ibf_interrupt(void)
task_clear_pending_irq(IT83XX_IRQ_PMC5_IN);
}
-/**
- * Preserve event masks across a sysjump.
- */
-static void lpc_sysjump(void)
-{
- system_add_jump_tag(LPC_SYSJUMP_TAG, 1,
- sizeof(event_mask), event_mask);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT);
-
-/**
- * Restore event masks after a sysjump.
- */
-static void lpc_post_sysjump(void)
-{
- const uint32_t *prev_mask;
- int size, version;
-
- prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
- &version, &size);
- if (!prev_mask || version != 1 || size != sizeof(event_mask))
- return;
-
- memcpy(event_mask, prev_mask, sizeof(event_mask));
-}
-
static void lpc_init(void)
{
enum ec2i_message ec2i_r;
@@ -761,14 +684,11 @@ static void lpc_init(void)
task_clear_pending_irq(IT83XX_IRQ_PMC3_IN);
task_enable_irq(IT83XX_IRQ_PMC3_IN);
- /* Restore event masks if needed */
- lpc_post_sysjump();
-
/* Sufficiently initialized */
init_done = 1;
/* Update host events now that we can copy them to memmap */
- update_host_event_status();
+ lpc_update_host_event_status();
}
/*
* Set prio to higher than default; this way LPC memory mapped data is ready
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index 4da0f8e1f8..c374fb686e 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -54,10 +54,6 @@
#define CPUTS(outstr) cputs(CC_LPC, outstr)
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
-#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
-
-static uint32_t host_events; /* Currently pending SCI/SMI events */
-static uint32_t event_mask[3]; /* Event masks for each type */
static struct host_packet lpc_packet;
static struct host_cmd_handler_args host_cmd_args;
static uint8_t host_cmd_flags; /* Flags from host command */
@@ -153,6 +149,8 @@ static inline void keyboard_irq_assert(void)
*/
static void lpc_generate_smi(void)
{
+ uint32_t smi;
+
/* Enforce signal-high for long enough to debounce high */
gpio_set_level(GPIO_PCH_SMI_L, 1);
udelay(65);
@@ -162,9 +160,9 @@ static void lpc_generate_smi(void)
/* Set signal high, now that we've generated the edge */
gpio_set_level(GPIO_PCH_SMI_L, 1);
- if (host_events & event_mask[LPC_HOST_EVENT_SMI])
- CPRINTS("smi 0x%08x",
- host_events & event_mask[LPC_HOST_EVENT_SMI]);
+ smi = lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI);
+ if (smi)
+ CPRINTS("smi 0x%08x", smi);
}
/**
@@ -172,6 +170,8 @@ static void lpc_generate_smi(void)
*/
static void lpc_generate_sci(void)
{
+ uint32_t sci;
+
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
gpio_set_level(CONFIG_SCI_GPIO, 1);
@@ -185,9 +185,9 @@ static void lpc_generate_sci(void)
LM4_LPC_LPCCTL |= LM4_LPC_SCI_START;
#endif
- if (host_events & event_mask[LPC_HOST_EVENT_SCI])
- CPRINTS("sci 0x%08x",
- host_events & event_mask[LPC_HOST_EVENT_SCI]);
+ sci = lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI);
+ if (sci)
+ CPRINTS("sci 0x%08x", sci);
}
/**
@@ -341,7 +341,7 @@ void lpc_comx_put_char(int c)
* - SMI pulse via EC_SMI_L GPIO
* - SCI pulse via LPC0SCI
*/
-static void update_host_event_status(void)
+void lpc_update_host_event_status(void)
{
int need_sci = 0;
int need_smi = 0;
@@ -352,7 +352,7 @@ static void update_host_event_status(void)
/* Disable LPC interrupt while updating status register */
task_disable_irq(LM4_IRQ_LPC);
- if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) {
/* Only generate SMI for first event */
if (!(LM4_LPC_ST(LPC_CH_ACPI) & LM4_LPC_ST_SMI))
need_smi = 1;
@@ -360,7 +360,7 @@ static void update_host_event_status(void)
} else
LM4_LPC_ST(LPC_CH_ACPI) &= ~LM4_LPC_ST_SMI;
- if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) {
/* Generate SCI for every event */
need_sci = 1;
LM4_LPC_ST(LPC_CH_ACPI) |= LM4_LPC_ST_SCI;
@@ -368,12 +368,13 @@ static void update_host_event_status(void)
LM4_LPC_ST(LPC_CH_ACPI) &= ~LM4_LPC_ST_SCI;
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events;
+ *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ lpc_get_host_events();
task_enable_irq(LM4_IRQ_LPC);
/* Process the wake events. */
- lpc_update_wake(host_events & event_mask[LPC_HOST_EVENT_WAKE]);
+ lpc_update_wake(lpc_get_host_events_by_type(LPC_HOST_EVENT_WAKE));
/* Send pulse on SMI signal if needed */
if (need_smi)
@@ -384,54 +385,6 @@ static void update_host_event_status(void)
lpc_generate_sci();
}
-void lpc_set_host_event_state(uint32_t mask)
-{
- if (mask != host_events) {
- host_events = mask;
- update_host_event_status();
- }
-}
-
-int lpc_query_host_event_state(void)
-{
- const uint32_t any_mask = event_mask[0] | event_mask[1] | event_mask[2];
- int evt_index = 0;
- int i;
-
- for (i = 0; i < 32; i++) {
- const uint32_t e = (1 << i);
-
- if (host_events & e) {
- host_clear_events(e);
-
- /*
- * If host hasn't unmasked this event, drop it. We do
- * this at query time rather than event generation time
- * so that the host has a chance to unmask events
- * before they're dropped by a query.
- */
- if (!(e & any_mask))
- continue;
-
- evt_index = i + 1; /* Events are 1-based */
- break;
- }
- }
-
- return evt_index;
-}
-
-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];
-}
-
void lpc_set_acpi_status_mask(uint8_t mask)
{
uint32_t set_mask = 0;
@@ -667,32 +620,6 @@ void lpc_interrupt(void)
}
DECLARE_IRQ(LM4_IRQ_LPC, lpc_interrupt, 2);
-/**
- * Preserve event masks across a sysjump.
- */
-static void lpc_sysjump(void)
-{
- system_add_jump_tag(LPC_SYSJUMP_TAG, 1,
- sizeof(event_mask), event_mask);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT);
-
-/**
- * Restore event masks after a sysjump.
- */
-static void lpc_post_sysjump(void)
-{
- const uint32_t *prev_mask;
- int size, version;
-
- prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
- &version, &size);
- if (!prev_mask || version != 1 || size != sizeof(event_mask))
- return;
-
- memcpy(event_mask, prev_mask, sizeof(event_mask));
-}
-
/* Enable LPC ACPI-EC interrupts */
void lpc_enable_acpi_interrupts(void)
{
@@ -862,14 +789,11 @@ static void lpc_init(void)
uart_comx_enable();
#endif
- /* Restore event masks if needed */
- lpc_post_sysjump();
-
/* Sufficiently initialized */
init_done = 1;
/* Update host events now that we can copy them to memmap */
- update_host_event_status();
+ lpc_update_host_event_status();
}
/*
* Set prio to higher than default; this way LPC memory mapped data is ready
diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c
index e5eae508ae..5f4d1f43a6 100644
--- a/chip/mec1322/lpc.c
+++ b/chip/mec1322/lpc.c
@@ -24,12 +24,8 @@
#define CPUTS(outstr) cputs(CC_LPC, outstr)
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
-#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
-
static uint8_t mem_mapped[0x200] __attribute__((section(".bss.big_align")));
-static uint32_t host_events; /* Currently pending SCI/SMI events */
-static uint32_t event_mask[3]; /* Event masks for each type */
static struct host_packet lpc_packet;
static struct host_cmd_handler_args host_cmd_args;
static uint8_t host_cmd_flags; /* Flags from host command */
@@ -126,7 +122,7 @@ static uint8_t *lpc_get_hostcmd_data_range(void)
* - SMI pulse via PCH_SMI_L GPIO
* - SCI pulse via PCH_SCI_L GPIO
*/
-static void update_host_event_status(void)
+void lpc_update_host_event_status(void)
{
int need_sci = 0;
int need_smi = 0;
@@ -137,7 +133,7 @@ static void update_host_event_status(void)
/* Disable LPC interrupt while updating status register */
task_disable_irq(MEC1322_IRQ_ACPIEC0_IBF);
- if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) {
/* Only generate SMI for first event */
if (!(MEC1322_ACPI_EC_STATUS(0) & EC_LPC_STATUS_SMI_PENDING))
need_smi = 1;
@@ -146,7 +142,7 @@ static void update_host_event_status(void)
MEC1322_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_SMI_PENDING;
}
- if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) {
/* Generate SCI for every event */
need_sci = 1;
MEC1322_ACPI_EC_STATUS(0) |= EC_LPC_STATUS_SCI_PENDING;
@@ -155,12 +151,13 @@ static void update_host_event_status(void)
}
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events;
+ *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ lpc_get_host_events();
task_enable_irq(MEC1322_IRQ_ACPIEC0_IBF);
/* Process the wake events. */
- lpc_update_wake(host_events & event_mask[LPC_HOST_EVENT_WAKE]);
+ lpc_update_wake(lpc_get_host_events_by_type(LPC_HOST_EVENT_WAKE));
/* Send pulse on SMI signal if needed */
if (need_smi)
@@ -184,34 +181,6 @@ static void lpc_send_response_packet(struct host_packet *pkt)
MEC1322_ACPI_EC_STATUS(1) &= ~EC_LPC_STATUS_PROCESSING;
}
-/**
- * Preserve event masks across a sysjump.
- */
-static void lpc_sysjump(void)
-{
- system_add_jump_tag(LPC_SYSJUMP_TAG, 1,
- sizeof(event_mask), event_mask);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT);
-
-/**
- * Restore event masks after a sysjump.
- */
-static void lpc_post_sysjump(void)
-{
- const uint32_t *prev_mask;
- int size, version;
-
- prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
- &version, &size);
- if (!prev_mask || version != 1 || size != sizeof(event_mask))
- return;
-
- memcpy(event_mask, prev_mask, sizeof(event_mask));
-}
-
-
-
/*
* Most registers in LPC module are reset when the host is off. We need to
* set up LPC again when the host is starting up.
@@ -288,7 +257,7 @@ static void setup_lpc(void)
init_done = 1;
/* Update host events now that we can copy them to memmap */
- update_host_event_status();
+ lpc_update_host_event_status();
}
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, setup_lpc, HOOK_PRIO_FIRST);
@@ -308,8 +277,6 @@ static void lpc_resume(void)
}
DECLARE_HOOK(HOOK_CHIPSET_RESUME, lpc_resume, HOOK_PRIO_DEFAULT);
-
-
static void lpc_init(void)
{
/* Activate LPC interface */
@@ -326,9 +293,6 @@ static void lpc_init(void)
memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);
setup_lpc();
-
- /* Restore event masks if needed */
- lpc_post_sysjump();
}
/*
* Set prio to higher than default; this way LPC memory mapped data is ready
@@ -517,54 +481,6 @@ void lpc_keyboard_resume_irq(void)
keyboard_irq_assert();
}
-void lpc_set_host_event_state(uint32_t mask)
-{
- if (mask != host_events) {
- host_events = mask;
- update_host_event_status();
- }
-}
-
-int lpc_query_host_event_state(void)
-{
- const uint32_t any_mask = event_mask[0] | event_mask[1] | event_mask[2];
- int evt_index = 0;
- int i;
-
- for (i = 0; i < 32; i++) {
- const uint32_t e = (1 << i);
-
- if (host_events & e) {
- host_clear_events(e);
-
- /*
- * If host hasn't unmasked this event, drop it. We do
- * this at query time rather than event generation time
- * so that the host has a chance to unmask events
- * before they're dropped by a query.
- */
- if (!(e & any_mask))
- continue;
-
- evt_index = i + 1; /* Events are 1-based */
- break;
- }
- }
-
- return evt_index;
-}
-
-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];
-}
-
void lpc_set_acpi_status_mask(uint8_t mask)
{
MEC1322_ACPI_EC_STATUS(0) |= mask;
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index 556276dbc8..6bc07fedfb 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -35,8 +35,6 @@
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
#endif
-#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
-
/* PM channel definitions */
#define PMC_ACPI PM_CHAN_1
#define PMC_HOST_CMD PM_CHAN_2
@@ -59,8 +57,6 @@
#define LPC_HOST_TRANSACTION_TIMEOUT_US 5
#endif
-static uint32_t host_events; /* Currently pending SCI/SMI events */
-static uint32_t event_mask[3]; /* Event masks for each type */
static struct host_packet lpc_packet;
static struct host_cmd_handler_args host_cmd_args;
static uint8_t host_cmd_flags; /* Flags from host command */
@@ -139,6 +135,8 @@ static void lpc_task_disable_irq(void)
*/
static void lpc_generate_smi(void)
{
+ uint32_t smi;
+
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
gpio_set_level(GPIO_PCH_SMI_L, 1);
@@ -173,9 +171,9 @@ static void lpc_generate_smi(void)
/* Set signal high */
SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIB);
#endif
- if (host_events & event_mask[LPC_HOST_EVENT_SMI])
- CPRINTS("smi 0x%08x",
- host_events & event_mask[LPC_HOST_EVENT_SMI]);
+ smi = lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI);
+ if (smi)
+ CPRINTS("smi 0x%08x", smi);
}
/**
@@ -183,6 +181,8 @@ static void lpc_generate_smi(void)
*/
static void lpc_generate_sci(void)
{
+ uint32_t sci;
+
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
gpio_set_level(CONFIG_SCI_GPIO, 1);
@@ -218,9 +218,9 @@ static void lpc_generate_sci(void)
SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SCIB);
#endif
- if (host_events & event_mask[LPC_HOST_EVENT_SCI])
- CPRINTS("sci 0x%08x",
- host_events & event_mask[LPC_HOST_EVENT_SCI]);
+ sci = lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI);
+ if (sci)
+ CPRINTS("sci 0x%08x", sci);
}
/**
@@ -422,7 +422,7 @@ void lpc_keyboard_resume_irq(void)
* - SMI pulse via EC_SMI_L GPIO
* - SCI pulse via LPC0SCI
*/
-static void update_host_event_status(void)
+void lpc_update_host_event_status(void)
{
int need_sci = 0;
int need_smi = 0;
@@ -432,7 +432,7 @@ static void update_host_event_status(void)
/* Disable LPC interrupt while updating status register */
lpc_task_disable_irq();
- if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) {
/* Only generate SMI for first event */
if (!(NPCX_HIPMST(PMC_ACPI) & NPCX_HIPMST_ST2))
need_smi = 1;
@@ -440,7 +440,7 @@ static void update_host_event_status(void)
} else
CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST2);
- if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
+ if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) {
/* Generate SCI for every event */
need_sci = 1;
SET_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST1);
@@ -448,12 +448,13 @@ static void update_host_event_status(void)
CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST1);
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events;
+ *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ lpc_get_host_events();
lpc_task_enable_irq();
/* Process the wake events. */
- lpc_update_wake(host_events & event_mask[LPC_HOST_EVENT_WAKE]);
+ lpc_update_wake(lpc_get_host_events_by_type(LPC_HOST_EVENT_WAKE));
/* Send pulse on SMI signal if needed */
if (need_smi)
@@ -464,54 +465,6 @@ static void update_host_event_status(void)
lpc_generate_sci();
}
-void lpc_set_host_event_state(uint32_t mask)
-{
- if (mask != host_events) {
- host_events = mask;
- update_host_event_status();
- }
-}
-
-int lpc_query_host_event_state(void)
-{
- const uint32_t any_mask = event_mask[0] | event_mask[1] | event_mask[2];
- int evt_index = 0;
- int i;
-
- for (i = 0; i < 32; i++) {
- const uint32_t e = (1 << i);
-
- if (host_events & e) {
- host_clear_events(e);
-
- /*
- * If host hasn't unmasked this event, drop it. We do
- * this at query time rather than event generation time
- * so that the host has a chance to unmask events
- * before they're dropped by a query.
- */
- if (!(e & any_mask))
- continue;
-
- evt_index = i + 1; /* Events are 1-based */
- break;
- }
- }
-
- return evt_index;
-}
-
-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];
-}
-
void lpc_set_acpi_status_mask(uint8_t mask)
{
NPCX_HIPMST(PMC_ACPI) |= mask;
@@ -689,28 +642,9 @@ static void lpc_sysjump(void)
/* Reset base address for Win 1 and 2. */
NPCX_WIN_BASE(0) = 0xfffffff8;
NPCX_WIN_BASE(1) = 0xfffffff8;
-
- system_add_jump_tag(LPC_SYSJUMP_TAG, 1,
- sizeof(event_mask), event_mask);
}
DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT);
-/**
- * Restore event masks after a sysjump.
- */
-static void lpc_post_sysjump(void)
-{
- const uint32_t *prev_mask;
- int size, version;
-
- prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
- &version, &size);
- if (!prev_mask || version != 1 || size != sizeof(event_mask))
- return;
-
- memcpy(event_mask, prev_mask, sizeof(event_mask));
-}
-
/* Super-IO read/write function */
void lpc_sib_write_reg(uint8_t io_offset, uint8_t index_value,
uint8_t io_data)
@@ -1011,9 +945,6 @@ static void lpc_init(void)
/* Clear status */
NPCX_SMC_STS = NPCX_SMC_STS;
- /* Restore event masks if needed */
- lpc_post_sysjump();
-
/* Create mailbox */
/*
@@ -1074,7 +1005,7 @@ static void lpc_init(void)
init_done = 1;
/* Update host events now that we can copy them to memmap */
- update_host_event_status();
+ lpc_update_host_event_status();
/*
* TODO: For testing LPC with Chromebox, please make sure LPC_CLK is
diff --git a/common/acpi.c b/common/acpi.c
index 2097beeda8..76c90127d1 100644
--- a/common/acpi.c
+++ b/common/acpi.c
@@ -266,7 +266,7 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
}
} else if (acpi_cmd == EC_CMD_ACPI_QUERY_EVENT && !acpi_data_count) {
/* Clear and return the lowest host event */
- int evt_index = lpc_query_host_event_state();
+ int evt_index = lpc_get_next_host_event();
CPRINTS("ACPI query = %d", evt_index);
*resultptr = evt_index;
retval = 1;
diff --git a/common/host_event_commands.c b/common/host_event_commands.c
index 1dc9ac5c0c..714eaf42ec 100644
--- a/common/host_event_commands.c
+++ b/common/host_event_commands.c
@@ -8,15 +8,114 @@
#include "atomic.h"
#include "common.h"
#include "console.h"
+#include "hooks.h"
#include "host_command.h"
#include "lpc.h"
#include "mkbp_event.h"
+#include "system.h"
#include "util.h"
/* Console output macros */
#define CPUTS(outstr) cputs(CC_EVENTS, outstr)
#define CPRINTS(format, args...) cprints(CC_EVENTS, format, ## args)
+#ifdef CONFIG_LPC
+
+#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
+#define LPC_SYSJUMP_VERSION 1
+
+static uint32_t lpc_host_events;
+static uint32_t lpc_host_event_mask[LPC_HOST_EVENT_COUNT];
+
+void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask)
+{
+ lpc_host_event_mask[type] = mask;
+ lpc_update_host_event_status();
+}
+
+uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
+{
+ return lpc_host_event_mask[type];
+}
+
+static void lpc_set_host_event_state(uint32_t events)
+{
+ if (events == lpc_host_events)
+ return;
+
+ lpc_host_events = events;
+ lpc_update_host_event_status();
+}
+
+uint32_t lpc_get_host_events_by_type(enum lpc_host_event_type type)
+{
+ return lpc_host_events & lpc_get_host_event_mask(type);
+}
+
+uint32_t lpc_get_host_events(void)
+{
+ return lpc_host_events;
+}
+
+int lpc_get_next_host_event(void)
+{
+ int evt_index = 0;
+ int i;
+ const uint32_t any_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI) |
+ lpc_get_host_event_mask(LPC_HOST_EVENT_SCI) |
+ lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE);
+
+ for (i = 0; i < 32; i++) {
+ const uint32_t e = (1 << i);
+
+ if (lpc_host_events & e) {
+ host_clear_events(e);
+
+ /*
+ * If host hasn't unmasked this event, drop it. We do
+ * this at query time rather than event generation time
+ * so that the host has a chance to unmask events
+ * before they're dropped by a query.
+ */
+ if (!(e & any_mask))
+ continue;
+
+ evt_index = i + 1; /* Events are 1-based */
+ break;
+ }
+ }
+
+ return evt_index;
+}
+
+static void lpc_sysjump_save_mask(void)
+{
+ system_add_jump_tag(LPC_SYSJUMP_TAG, LPC_SYSJUMP_VERSION,
+ sizeof(lpc_host_event_mask), lpc_host_event_mask);
+}
+DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump_save_mask, HOOK_PRIO_DEFAULT);
+
+static void lpc_post_sysjump_restore_mask(void)
+{
+ const uint32_t *prev_mask;
+ int size, version;
+
+ prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
+ &version, &size);
+ if (!prev_mask || version != LPC_SYSJUMP_VERSION ||
+ size != sizeof(lpc_host_event_mask))
+ return;
+
+ memcpy(lpc_host_event_mask, prev_mask, sizeof(lpc_host_event_mask));
+}
+/*
+ * This hook is required to run before chip gets to initialize LPC because
+ * update host events will need the masks to be correctly restored.
+ */
+DECLARE_HOOK(HOOK_INIT, lpc_post_sysjump_restore_mask, HOOK_PRIO_INIT_LPC - 1);
+
+#endif
+
/*
* Maintain two copies of the events that are set.
*
diff --git a/include/lpc.h b/include/lpc.h
index 03699dab35..ff9642b6f5 100644
--- a/include/lpc.h
+++ b/include/lpc.h
@@ -71,17 +71,20 @@ enum lpc_host_event_type {
LPC_HOST_EVENT_SMI = 0,
LPC_HOST_EVENT_SCI,
LPC_HOST_EVENT_WAKE,
+ LPC_HOST_EVENT_COUNT,
};
/**
- * Set the event state.
+ * Get current state of host events.
*/
-void lpc_set_host_event_state(uint32_t mask);
+uint32_t lpc_get_host_events(void);
/**
- * Clear and return the lowest host event.
+ * Get host events that are set based on the type provided.
+ *
+ * @param type Event type
*/
-int lpc_query_host_event_state(void);
+uint32_t lpc_get_host_events_by_type(enum lpc_host_event_type type);
/**
* Set the event mask for the specified event type.
@@ -92,11 +95,18 @@ int lpc_query_host_event_state(void);
void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask);
/**
- * Return the event mask for the specified event type.
+ * Get host event mask based on the type provided.
+ *
+ * @param type Event type
*/
uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type);
/**
+ * Clear and return the lowest host event.
+ */
+int lpc_get_next_host_event(void);
+
+/**
* Set the EC_LPC_STATUS_* mask for the specified status.
*/
void lpc_set_acpi_status_mask(uint8_t mask);
@@ -124,4 +134,11 @@ void lpc_disable_acpi_interrupts(void);
/* Enable LPC ACPI interrupts */
void lpc_enable_acpi_interrupts(void);
+/**
+ * Update host event status. This function is called whenever host event bits
+ * need to be updated based on initialization complete or host event mask
+ * update or when a new host event is set or cleared.
+ */
+void lpc_update_host_event_status(void);
+
#endif /* __CROS_EC_LPC_H */
diff --git a/power/intel_x86.c b/power/intel_x86.c
index c1f49353fd..3da8c9eba7 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -142,7 +142,7 @@ static void s0ix_lpc_disable_wake_mask(void)
lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, mask);
/* clear host events */
- while (lpc_query_host_event_state() != 0)
+ while (lpc_get_next_host_event() != 0)
;
}
}