summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/include/soc/pm.h1
-rw-r--r--src/soc/intel/apollolake/pmutil.c19
-rw-r--r--src/soc/intel/apollolake/smihandler.c1
3 files changed, 20 insertions, 1 deletions
diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h
index c889453f2e..856872ed97 100644
--- a/src/soc/intel/apollolake/include/soc/pm.h
+++ b/src/soc/intel/apollolake/include/soc/pm.h
@@ -100,6 +100,7 @@
#define MC_SMI_STS 12
#define GPIO_UNLOCK_SMI_STS 11
#define GPIO_SMI_STS 10
+#define FAKE_PM1_SMI_STS 8
#define SWSMI_TMR_SMI_STS 6
#define APM_SMI_STS 5
#define SLP_SMI_STS 4
diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c
index bebc1c7178..6e47911fcd 100644
--- a/src/soc/intel/apollolake/pmutil.c
+++ b/src/soc/intel/apollolake/pmutil.c
@@ -60,6 +60,7 @@ static uint32_t print_smi_status(uint32_t smi_sts)
[SLP_SMI_STS] = "SLP_SMI",
[APM_SMI_STS] = "APM",
[SWSMI_TMR_SMI_STS] = "SWSMI_TMR",
+ [FAKE_PM1_SMI_STS] = "PM1",
[GPIO_SMI_STS]= "GPIO_SMI",
[GPIO_UNLOCK_SMI_STS]= "GPIO_UNLOCK_SSMI",
[MC_SMI_STS] = "MCSMI",
@@ -96,7 +97,23 @@ static uint32_t reset_smi_status(void)
uint32_t clear_smi_status(void)
{
- return print_smi_status(reset_smi_status());
+ uint32_t sts = reset_smi_status();
+
+ /*
+ * Check for power button status if nothing else is indicating an SMI
+ * and SMIs aren't turned into SCIs. Apparently, there is no PM1 status
+ * bit in the SMI status register. That makes things difficult for
+ * determining if the power button caused an SMI.
+ */
+ if (sts == 0 && !(inl(ACPI_PMIO_BASE + PM1_CNT) & SCI_EN)) {
+ uint16_t pm1_sts = inw(ACPI_PMIO_BASE + PM1_STS);
+
+ /* Fake PM1 status bit if power button pressed. */
+ if (pm1_sts & PWRBTN_STS)
+ sts |= (1 << FAKE_PM1_SMI_STS);
+ }
+
+ return print_smi_status(sts);
}
uint32_t get_smi_en(void)
diff --git a/src/soc/intel/apollolake/smihandler.c b/src/soc/intel/apollolake/smihandler.c
index fd175e30d8..1521920fa1 100644
--- a/src/soc/intel/apollolake/smihandler.c
+++ b/src/soc/intel/apollolake/smihandler.c
@@ -46,6 +46,7 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void)
const smi_handler_t southbridge_smi[32] = {
[SLP_SMI_STS] = southbridge_smi_sleep,
[APM_SMI_STS] = southbridge_smi_apmc,
+ [FAKE_PM1_SMI_STS] = southbridge_smi_pm1,
[TCO_SMI_STS] = southbridge_smi_tco,
[PERIODIC_SMI_STS] = southbridge_smi_periodic,
};