summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@chromium.org>2017-10-09 22:02:22 -0700
committerCommit Bot <commit-bot@chromium.org>2020-12-11 15:48:40 +0000
commit7f0710ffeb9ee48d36c6db0e943bdea3a3ebb983 (patch)
treea5c8f881db5b5a6e7887154bdb692d60beb18441
parentb163b4bbd688cd13876db49531d204af710204f0 (diff)
downloadchrome-ec-7f0710ffeb9ee48d36c6db0e943bdea3a3ebb983.tar.gz
host_event: Move host events and mask handling into common code
Instead of duplicating the handling of host events and host event masks in chip lpc drivers, add routines in common code to provide basic functions like setting/getting of masks, setting/getting of events and handling of masks transitions across sysjump. BUG=None BRANCH=None TEST=make -j buildall. Verified following: 1. Event masks are correctly retained across sysjumps. 2. Wake from S3 works fine. 3. Wake from S0ix works fine. 4. SCI generated correctly. Change-Id: Ie409f91b12788e4b902b2627e31ba5ce40ff1d27 Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/707771 Reviewed-by: Shawn N <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2585065 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
-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 1127e93576..7545d47e46 100644
--- a/chip/it83xx/lpc.c
+++ b/chip/it83xx/lpc.c
@@ -29,8 +29,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,
@@ -56,8 +54,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 */
@@ -212,7 +208,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;
@@ -223,7 +219,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;
@@ -232,7 +228,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);
@@ -241,12 +237,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)
@@ -357,54 +354,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);
@@ -599,32 +548,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;
@@ -760,14 +683,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 e8b59f12d3..6f64703bda 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 */
@@ -141,6 +137,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);
@@ -175,9 +173,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);
}
/**
@@ -185,6 +183,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);
@@ -220,9 +220,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);
}
/**
@@ -428,7 +428,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;
@@ -438,7 +438,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;
@@ -446,7 +446,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);
@@ -454,12 +454,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)
@@ -470,54 +471,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;
@@ -695,28 +648,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)
@@ -1022,9 +956,6 @@ static void lpc_init(void)
/* Clear status */
NPCX_SMC_STS = NPCX_SMC_STS;
- /* Restore event masks if needed */
- lpc_post_sysjump();
-
/* Create mailbox */
/*
@@ -1085,7 +1016,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 0364474de0..6352bb2c74 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 13f2be53ac..96e2880784 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -132,7 +132,7 @@ static void s0ix_lpc_disable_wake_mask_for_lid_open(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)
;
}
}