From nobody Sun Jun 21 05:29:51 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gjfzN1Y0Gz6hygp for ; Sun, 21 Jun 2026 05:29:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gjfzM5kShz3qy8 for ; Sun, 21 Jun 2026 05:29:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782019791; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HB9ZCgCMVnnZe4gKy6rHEdc9SIkYtJDBI4NIBdCI4hg=; b=ZauGgwJG3G1uxkiySK2gFYX1TyoA3CL9STpR0T51YV+eOFKxB65a+NWxe8+w7oJOxSbyH/ iZpTbymWfUaZ/4nmtzy41r+WvJdzw3JBlWpUnOjxTZwgaAGSTpg4O53YaJ0yTipQqs30nf vqBTDaZPNoPl60WyvR3Rcy43lsjOjc7DMfVv9BLdo37Vtl53E61Bid8l1Q47II84P43McX 9kfFrIEIulp/2tHFowBlakSiJmYUHv+Bi9Tq9jxG5HOMXlZgYDzYBMzsV/s8dr0UuUJjxm xHlkxTOL4MvwVC1ZgYBXBRLRo/itM52wfZEeTY2XXRevcnt0EUzhDCl9Y93OFA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782019791; a=rsa-sha256; cv=none; b=qU+yNfcm2nnE6WUNSm07/aRyn2l33izyjkbZQccQBNIAp8VpamPcf12LJubmO6SjeNzCNL CPPR6SrXlovUxfdxIkT275pHzVOQ4onjALmr9+sJhAId1CaGj41Cs5EcK4I82zAF6FVMiQ 1GBHqJHpAYVMZlDEoAIyFN8g++1gySq0hM3YGl+/WYYYVkCDmHGsSTCRbPFa+l4GTrvszn z3Z/4vZopWNedVqafKg+eo4Iuz3ZvEymYjAD/tVWc0q8LwsTC17RipjdghbvTH7RyoXE5d x5RC5LVYg0SZA0vjLFj+KO5xOX1xT5cUNptFJmJX1te2lzz+22MKwPuvVSrmBw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782019791; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HB9ZCgCMVnnZe4gKy6rHEdc9SIkYtJDBI4NIBdCI4hg=; b=l0Z6SHZ0e/YMzBT2rgQdPFIN9Vq3XJKykeYADxFRBhm2+Y5B4JFxXE6RVwofyLoUn7eXsP j0PD/WsrDvsrlerAqU1Fg1aUOP5dDIDWY0i7CmRloW8kP0ElhJwjfmG3xMzw0TPgQ0udbh TatVkj2HFeed6kmm49IMRbMJVq72uPd6P0n+i0DEgVYRjw/2zv+afayUgfkFrpp+Y97XoZ WJG8D0S/Dlmol6wN/qrKrMnA8DdtFk2JkS24AVW6V2b/zs/cxupHcya3l4T7LeqHpV4N6y szWvxSBd3Wo8WJ452BxqIQICtU7XJUkcVVymce+hHE+rfTlWrKZGBIYZ3QJu8w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gjfzM4XrFz13Md for ; Sun, 21 Jun 2026 05:29:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 25854 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 21 Jun 2026 05:29:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Devin Teske Subject: git: a4ed783cee2a - main - ig4: unconditionally un-idle the controller core on resume List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dteske X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a4ed783cee2a10629db7a6c254712f96bd820288 Auto-Submitted: auto-generated Date: Sun, 21 Jun 2026 05:29:51 +0000 Message-Id: <6a3776cf.25854.233f603c@gitrepo.freebsd.org> The branch main has been updated by dteske: URL: https://cgit.FreeBSD.org/src/commit/?id=a4ed783cee2a10629db7a6c254712f96bd820288 commit a4ed783cee2a10629db7a6c254712f96bd820288 Author: Devin Teske AuthorDate: 2026-06-19 17:24:58 +0000 Commit: Devin Teske CommitDate: 2026-06-21 05:28:47 +0000 ig4: unconditionally un-idle the controller core on resume On controllers with the LPSS "additional registers" (Skylake and later, IG4_HAS_ADDREGS), ig4iic_suspend() places the controller in the 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 out of the idle state again. ig4iic_set_config(), called from ig4iic_resume(), only performs that un-idle handshake 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). The core is then left gated: set_config()'s register writes have no effect, it nevertheless returns success, and every subsequent transfer fails with IIC_ETIMEOUT, leaving child I2C-HID devices (touchpad, touchscreen) dead after resume. Give ig4iic_set_config() a force_restore argument and pass it from ig4iic_resume() so the un-idle handshake runs unconditionally for IG4_HAS_ADDREGS controllers, regardless of the RESTORE_REQUIRED status. This keeps the handshake and its reset/restore sequence in one place instead of duplicating it in the resume path. The DesignWare core's register bank stays inaccessible (reads back as zero) until it leaves reset, which happens when ig4iic_set_config() deasserts the core reset. Rather than waiting a fixed, guessed interval, poll the fixed component-type signature (IG4_REG_COMP_TYPE == IG4_COMP_TYPE) immediately after that deassert and continue as soon as the core is ready. On Alder Lake-P the core is ready with no measurable delay; the bounded poll keeps this correct on slower parts, and warns if the core never leaves reset. While integrating these I2C-HID touch devices, also raise hid(4)'s MAXLOCCNT from 2048 to 4096: the report-descriptor parser truncates any variable main item whose usage count exceeds MAXLOCCNT, silently dropping the trailing report fields. Some contemporary touch devices declare variable items with more than 2048 entries, so part of their input reports was being discarded. Reviewed by: adrian MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D57673 --- sys/dev/hid/hid.c | 2 +- sys/dev/ichiic/ig4_iic.c | 52 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/sys/dev/hid/hid.c b/sys/dev/hid/hid.c index 453c37d806fc..c07343fc057f 100644 --- a/sys/dev/hid/hid.c +++ b/sys/dev/hid/hid.c @@ -66,7 +66,7 @@ hid_test_quirk_t *hid_test_quirk_p = &hid_test_quirk_w; #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 index cd88b28a2d52..161a940c5e7a 100644 --- a/sys/dev/ichiic/ig4_iic.c +++ b/sys/dev/ichiic/ig4_iic.c @@ -134,7 +134,7 @@ static const struct ig4_hw ig4iic_hw[] = { }, }; -static int ig4iic_set_config(ig4iic_softc_t *sc, bool reset); +static int ig4iic_set_config(ig4iic_softc_t *sc, bool reset, bool force_restore); static driver_filter_t ig4iic_intr; static void ig4iic_dump(ig4iic_softc_t *sc); @@ -661,7 +661,7 @@ ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) ig4iic_xfer_abort(sc) != 0) { device_printf(sc->dev, "Failed to abort " "transfer. Do the controller reset.\n"); - ig4iic_set_config(sc, true); + ig4iic_set_config(sc, true, false); } else { while (reg_read(sc, IG4_REG_I2C_STA) & IG4_STATUS_RX_NOTEMPTY) @@ -910,12 +910,23 @@ ig4iic_get_config(ig4iic_softc_t *sc) } static int -ig4iic_set_config(ig4iic_softc_t *sc, bool reset) +ig4iic_set_config(ig4iic_softc_t *sc, bool reset, bool force_restore) { uint32_t v; + int i; + /* + * Take the LPSS DesignWare core out of the "device idle" state. While + * idle the core is power-gated: its register bank reads back as zero and + * writes are dropped. Normally we perform this un-idle handshake only + * when IG4_RESTORE_REQUIRED is observed in DEVIDLE_CTRL, but some + * platforms (e.g. Intel Alder Lake-P) do not raise that status across + * suspend-to-idle (S0ix). Callers that know the core was idled (the + * resume path) pass force_restore to perform the handshake regardless. + */ v = reg_read(sc, IG4_REG_DEVIDLE_CTRL); - if (IG4_HAS_ADDREGS(sc->version) && (v & IG4_RESTORE_REQUIRED)) { + if (IG4_HAS_ADDREGS(sc->version) && + (force_restore || (v & IG4_RESTORE_REQUIRED))) { reg_write(sc, IG4_REG_DEVIDLE_CTRL, IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED); reg_write(sc, IG4_REG_DEVIDLE_CTRL, 0); pause("i2crst", 1); @@ -928,6 +939,23 @@ ig4iic_set_config(ig4iic_softc_t *sc, bool reset) } 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 (i == 100) { + device_printf(sc->dev, "WARNING: I2C controller core " + "did not leave reset (COMP_TYPE 0x%08x); device " + "may be unusable\n", + reg_read(sc, IG4_REG_COMP_TYPE)); + } } if (sc->version == IG4_ATOM) @@ -1037,7 +1065,7 @@ ig4iic_attach(ig4iic_softc_t *sc) ig4iic_get_config(sc); - error = ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version)); + error = ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version), false); if (error) goto done; ig4iic_get_fifo(sc); @@ -1130,7 +1158,19 @@ int ig4iic_resume(ig4iic_softc_t *sc) int error; sx_xlock(&sc->call_lock); - if (ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version))) + + /* + * ig4iic_suspend() leaves the controller power-gated in the LPSS + * "device idle" state. Force the un-idle/restore handshake in + * ig4iic_set_config() so the DesignWare core is reliably restored + * before reconfiguration: some platforms (e.g. Intel Alder Lake-P) do + * not raise IG4_RESTORE_REQUIRED across suspend-to-idle (S0ix), and + * without the forced handshake the core stays gated, set_config()'s + * writes are dropped, and every subsequent transfer fails with + * IIC_ETIMEOUT, leaving child I2C-HID devices (touchpad, touchscreen) + * dead after resume. + */ + if (ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version), true)) device_printf(sc->dev, "controller error during resume\n"); sx_xunlock(&sc->call_lock);