diff options
-rw-r--r-- | chip/ish/ipc.c | 11 | ||||
-rw-r--r-- | chip/it83xx/lpc.c | 94 | ||||
-rw-r--r-- | chip/lm4/lpc.c | 110 | ||||
-rw-r--r-- | chip/mec1322/lpc.c | 98 | ||||
-rw-r--r-- | chip/npcx/lpc.c | 103 | ||||
-rw-r--r-- | common/acpi.c | 2 | ||||
-rw-r--r-- | common/host_event_commands.c | 99 | ||||
-rw-r--r-- | include/lpc.h | 27 | ||||
-rw-r--r-- | power/intel_x86.c | 2 |
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) ; } } |