summaryrefslogtreecommitdiff
path: root/src/superio/ite
diff options
context:
space:
mode:
Diffstat (limited to 'src/superio/ite')
-rw-r--r--src/superio/ite/it8772f/it8772f.h1
-rw-r--r--src/superio/ite/it8772f/superio.c36
2 files changed, 37 insertions, 0 deletions
diff --git a/src/superio/ite/it8772f/it8772f.h b/src/superio/ite/it8772f/it8772f.h
index 43e7d4cf43..d1d898aea6 100644
--- a/src/superio/ite/it8772f/it8772f.h
+++ b/src/superio/ite/it8772f/it8772f.h
@@ -70,6 +70,7 @@
#define IT8772F_FAN_CTL_AUTO_SMOOTHING_DIS (0 << 7)
#define IT8772F_FAN_CTL_AUTO_SMOOTHING_EN (1 << 7)
#define IT8772F_EXTEMP_STATUS 0x88
+#define IT8772F_EXTEMP_STATUS_HOST_BUSY (1 << 0)
#define IT8772F_EXTEMP_ADDRESS 0x89
#define IT8772F_EXTEMP_WRITE_LENGTH 0x8a
#define IT8772F_EXTEMP_READ_LENGTH 0x8b
diff --git a/src/superio/ite/it8772f/superio.c b/src/superio/ite/it8772f/superio.c
index ca103518a4..4d83280241 100644
--- a/src/superio/ite/it8772f/superio.c
+++ b/src/superio/ite/it8772f/superio.c
@@ -22,6 +22,7 @@
#include <device/pnp.h>
#include <pc80/keyboard.h>
#include <arch/io.h>
+#include <delay.h>
#include <stdlib.h>
#include <superio/conf_mode.h>
@@ -40,6 +41,34 @@ static inline void it8772f_envc_write(struct resource *res, u8 addr, u8 value)
outb(value, res->base + 6);
}
+static void it8772f_extemp_force_idle_status(struct resource *res)
+{
+ u8 reg;
+ int retries = 10;
+
+ /* Wait up to 10ms for non-busy state. */
+ while (retries > 0) {
+ reg = it8772f_envc_read(res, IT8772F_EXTEMP_STATUS);
+
+ if ((reg & IT8772F_EXTEMP_STATUS_HOST_BUSY) == 0x0)
+ break;
+
+ retries--;
+
+ mdelay(1);
+ }
+
+ if (retries == 0 && (reg & IT8772F_EXTEMP_STATUS_HOST_BUSY) == 0x1) {
+ /*
+ * SIO is busy due to unfinished peci transaction.
+ * Re-configure Register 0x8E to terminate processes.
+ */
+ it8772f_envc_write(res, IT8772F_EXTEMP_CONTROL,
+ IT8772F_EXTEMP_CONTROL_AUTO_4HZ |
+ IT8772F_EXTEMP_CONTROL_AUTO_START);
+ }
+}
+
/*
* Setup External Temperature to read via PECI into TMPINx register
*/
@@ -142,6 +171,13 @@ static void it8772f_init(struct device *dev)
it8772f_enable_fan(res, 2);
if (conf->fan3_enable)
it8772f_enable_fan(res, 3);
+
+ /*
+ * System may get wrong temperature data when SIO is in
+ * busy state. Therefore, check the status and terminate
+ * processes if needed.
+ */
+ it8772f_extemp_force_idle_status(res);
break;
case IT8772F_GPIO:
/* Set GPIO output levels */