Page MenuHomeFreeBSD

D57673.id180135.diff
No OneTemporary

D57673.id180135.diff

diff --git a/sys/dev/hid/hid.c b/sys/dev/hid/hid.c
--- a/sys/dev/hid/hid.c
+++ b/sys/dev/hid/hid.c
@@ -66,7 +66,7 @@
#define MAXUSAGE 64
#define MAXPUSH 4
#define MAXID 16
-#define MAXLOCCNT 2048
+#define MAXLOCCNT 4096
struct hid_pos_data {
uint32_t rid;
diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
--- a/sys/dev/ichiic/ig4_iic.c
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -913,6 +913,7 @@
ig4iic_set_config(ig4iic_softc_t *sc, bool reset)
{
uint32_t v;
+ int i;
v = reg_read(sc, IG4_REG_DEVIDLE_CTRL);
if (IG4_HAS_ADDREGS(sc->version) && (v & IG4_RESTORE_REQUIRED)) {
@@ -928,6 +929,17 @@
} else if (IG4_HAS_ADDREGS(sc->version) && reset) {
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL);
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL);
+ /*
+ * The DesignWare core's register bank is inaccessible (reads
+ * back as zero) until it leaves reset. Poll the fixed
+ * component-type signature so we proceed exactly when the core
+ * is ready, rather than waiting a fixed, guessed interval.
+ */
+ for (i = 0; i < 100; i++) {
+ if (reg_read(sc, IG4_REG_COMP_TYPE) == IG4_COMP_TYPE)
+ break;
+ DELAY(10);
+ }
}
if (sc->version == IG4_ATOM)
@@ -1130,6 +1142,33 @@
int error;
sx_xlock(&sc->call_lock);
+
+ if (IG4_HAS_ADDREGS(sc->version)) {
+ /*
+ * ig4iic_suspend() places the controller in the LPSS "device
+ * idle" state (IG4_DEVICE_IDLE) and asserts core reset. While
+ * idle the DesignWare core is power-gated: its register bank
+ * reads back as zero and writes are dropped until the core is
+ * taken back out of the idle state.
+ *
+ * ig4iic_set_config() performs that un-idle handshake only when
+ * it observes IG4_RESTORE_REQUIRED set in DEVIDLE_CTRL. Some
+ * platforms (e.g. Intel Alder Lake-P) do not raise that status
+ * across suspend-to-idle (S0ix), so the core is left gated:
+ * set_config()'s register writes have no effect, it nonetheless
+ * returns success, and every subsequent transfer fails with
+ * IIC_ETIMEOUT. This leaves child I2C-HID devices (touchpad,
+ * touchscreen) dead after resume.
+ *
+ * Perform the un-idle handshake unconditionally here, symmetric
+ * with ig4iic_suspend(), so the core is reliably restored before
+ * reconfiguration regardless of the RESTORE_REQUIRED status.
+ */
+ reg_write(sc, IG4_REG_DEVIDLE_CTRL,
+ IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED);
+ reg_write(sc, IG4_REG_DEVIDLE_CTRL, 0);
+ }
+
if (ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version)))
device_printf(sc->dev, "controller error during resume\n");
sx_xunlock(&sc->call_lock);

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 27, 10:38 AM (11 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34386409
Default Alt Text
D57673.id180135.diff (2 KB)

Event Timeline