summaryrefslogtreecommitdiff
path: root/chip/mec1322/lpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/mec1322/lpc.c')
-rw-r--r--chip/mec1322/lpc.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c
index 673edfe62d..7cdc120330 100644
--- a/chip/mec1322/lpc.c
+++ b/chip/mec1322/lpc.c
@@ -14,6 +14,7 @@
#include "lpc.h"
#include "port80.h"
#include "registers.h"
+#include "system.h"
#include "task.h"
#include "timer.h"
#include "util.h"
@@ -22,6 +23,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 */
@@ -180,6 +183,34 @@ 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.
@@ -257,6 +288,20 @@ static void setup_lpc(void)
}
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, setup_lpc, HOOK_PRIO_FIRST);
+static void lpc_resume(void)
+{
+ /* Mask all host events until the host unmasks them itself. */
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, 0);
+
+ /* Store port 80 event so we know where resume happened */
+ port_80_write(PORT_80_EVENT_RESUME);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, lpc_resume, HOOK_PRIO_DEFAULT);
+
+
+
static void lpc_init(void)
{
/* Activate LPC interface */
@@ -265,6 +310,13 @@ static void lpc_init(void)
/* Initialize host args and memory map to all zero */
memset(lpc_host_args, 0, sizeof(*lpc_host_args));
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
@@ -508,7 +560,7 @@ int lpc_get_pltrst_asserted(void)
/* On boards without a host, this command is used to set up LPC */
static int lpc_command_init(int argc, char **argv)
{
- setup_lpc();
+ lpc_init();
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(lpcinit, lpc_command_init, NULL, NULL, NULL);