All of lore.kernel.org
 help / color / mirror / Atom feed
From: Victor Carreras <vicajilau@gmail.com>
To: rafael@kernel.org, hdegoede@redhat.com, bhelgaas@google.com,
	lukas@wunner.de
Cc: mika.westerberg@linux.intel.com, lenb@kernel.org,
	linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH v3] ACPI: x86: Disable wakeup on MSI MS-1592 and MS-1594 dGPU root port
Date: Wed, 11 Nov 2026 07:32:21 +0100	[thread overview]
Message-ID: <20261111063221.14478-1-vicajilau@gmail.com> (raw)
In-Reply-To: <20261024054711.21587-1-vicajilau@gmail.com>

On MSI Summit E16 Flip A12UCT (motherboard MS-1592, BIOS E1592IMS.111)
and MSI Prestige 16 Studio A13VE / Summit E16 Flip A13VET (motherboard
MS-1594, BIOS E1594IMS.115), the I2C touchpad (ELAN0305:00, 04F3:31FD)
permanently stops generating interrupts as soon as the discrete NVIDIA
GPU (0000:01:00.0) and its parent PCIe Root Port (0000:00:06.0,
\_SB.PC00.PEG0) enter D3cold.

In the platform's SSDT (MSI_NB / AdlP_Rvp), \_SB.PC00.PEG0 sets its wake
GPIO (WAKG) from the BIOS NVS variable P1WP, which erroneously points to
GPP_A20 (INTC1055:00 pin 62) -- the GPIO interrupt line wired to the
touchpad.

During boot, \_SB.PC00.PEG0.PON() calls \_SB.SHPO(WAKG, One), setting
PAD_CFG0_GPP_A20.GPIROUTSCI = 0 and HostSwOwn = 1 so the OS GPIO driver
owns the pin. However, when the root port runtime-suspends to D3cold,
Linux enables ACPI wakeup via \_SB.PC00.PEG0._DSW(1, 0, 3), which sets
WKEN = 1. Subsequent evaluation of \_SB.PC00.PEG0.PXP._OFF -> POFF()
executes:

  If (CondRefOf (WAKG))
  {
      If (((WAKG != Zero) && WKEN))
      {
          \_SB.SHPO (WAKG, Zero)
      }
  }

This switches GPP_A20 ownership to ACPI GPE mode (HostSwOwn = 0,
GPIROUTSCI = 1), silencing the touchpad interrupt until the dGPU wakes
back up to D0. Under Windows, _DSW is not armed for S0 D3cold on this
root port, leaving WKEN = 0 so POFF() powers off the dGPU (\PIN.OFF(PWRG))
without touching GPP_A20.

_DSW on the root port is reached through two paths: acpi_pci_wakeup()
on the root port itself, and acpi_pci_propagate_wakeup() when the dGPU
below it runtime-suspends. Both only check acpi_pm_device_can_wakeup(),
i.e. adev->wakeup.flags.valid, so clearing the device's wakeup
capability is not enough (the PCIe PME service sets it again anyway).

Add an early PCI fixup in drivers/acpi/x86/utils.c for boards MS-1592
and MS-1594 on root port 0000:00:06.0 (8086:464d on 12th Gen Alder
Lake-P and 8086:a74d on 13th Gen Raptor Lake-P/H) that clears
adev->wakeup.flags.valid on its ACPI companion. Early fixups run from
pci_setup_device() after pci_set_acpi_fwnode() and before
pci_device_add() calls device_add(), so pci_acpi_setup() never sees the
port as ACPI wakeup capable and stays balanced with pci_acpi_cleanup().
The root port and dGPU still reach D3cold normally, while GPP_A20 stays
owned by the GPIO driver.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220725
Cc: stable@vger.kernel.org
Signed-off-by: Victor Carreras <vicajilau@gmail.com>
---
Changes in v3:
- Clear adev->wakeup.flags.valid from a DECLARE_PCI_FIXUP_EARLY quirk
  instead of clearing the device wakeup flags in a final fixup. In v2,
  pcie_pme_mark_devices() set can_wakeup back to true, and
  acpi_pci_wakeup() / acpi_pci_propagate_wakeup() only check
  adev->wakeup.flags.valid, so _DSW was still evaluated (sashiko-bot).
  Running before pci_acpi_setup() keeps setup and cleanup balanced.
- Tested on MS-1594 without the SSDT override: PEG0 no longer shows up
  in /proc/acpi/wakeup, the root port and dGPU reach D3cold and the
  touchpad keeps generating interrupts across repeated D3cold cycles.
- Link to v2: https://lore.kernel.org/r/20261024054711.21587-1-vicajilau@gmail.com

Changes in v2:
- Move the quirk from drivers/pci/quirks.c to drivers/acpi/x86/utils.c
  as it is x86-specific (Lukas Wunner).
- Link to v1: https://lore.kernel.org/r/179272791966.20251.3697951431087014523@gmail.com

 drivers/acpi/x86/utils.c | 53 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
index 418951639..11a5d51be 100644
--- a/drivers/acpi/x86/utils.c
+++ b/drivers/acpi/x86/utils.c
@@ -665,3 +665,56 @@ void __init acpi_proc_quirk_mwait_check(void)
 	 */
 	dmi_check_system(acpi_proc_quirk_mwait_dmi_table);
 }
+
+/*
+ * On MSI Summit E16 Flip A12UCT (board MS-1592) and MSI Prestige 16 Studio
+ * A13VE / Summit E16 Flip A13VET (board MS-1594), the BIOS SSDT (MSI_NB /
+ * AdlP_Rvp) assigns the touchpad's GPIO interrupt pin (GPP_A20) as the PCIe
+ * wake GPIO (WAKG / P1WP) for the dGPU root port (\_SB.PC00.PEG0, 0000:00:06.0).
+ *
+ * When ACPI wakeup is armed on this root port via _DSW (setting WKEN = 1),
+ * subsequent D3cold transitions (\_SB.PC00.PEG0.PXP._OFF -> POFF) call
+ * \_SB.SHPO(WAKG, Zero), switching GPP_A20 ownership from GPIO driver mode
+ * to ACPI GPE mode and freezing the I2C touchpad (ELAN0305:00).
+ *
+ * Mark the root port's ACPI wakeup as invalid so that _DSW is never evaluated
+ * for it, neither directly nor when wakeup is propagated from the dGPU below
+ * it. This has to happen before pci_acpi_setup() runs from device_add(), so
+ * that pci_acpi_setup() and pci_acpi_cleanup() see the same state.
+ */
+static const struct dmi_system_id msi_peg0_no_wakeup_dmi_table[] = {
+	{
+		.ident = "MSI MS-1592",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
+			DMI_MATCH(DMI_BOARD_NAME, "MS-1592"),
+		},
+	},
+	{
+		.ident = "MSI MS-1594",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
+			DMI_MATCH(DMI_BOARD_NAME, "MS-1594"),
+		},
+	},
+	{}
+};
+
+static void quirk_msi_peg0_no_wakeup(struct pci_dev *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+
+	if (!adev || !adev->wakeup.flags.valid)
+		return;
+
+	if (pci_dev_id(dev) != PCI_DEVID(0, PCI_DEVFN(6, 0)))
+		return;
+
+	if (!dmi_check_system(msi_peg0_no_wakeup_dmi_table))
+		return;
+
+	pci_info(dev, FW_BUG "Disabling ACPI wakeup to avoid touchpad GPIO (GPP_A20) takeover in D3cold\n");
+	adev->wakeup.flags.valid = 0;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x464d, quirk_msi_peg0_no_wakeup);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa74d, quirk_msi_peg0_no_wakeup);
-- 
2.55.0


  parent reply	other threads:[~2026-11-11  6:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-23  3:58 [PATCH] PCI: Disable ACPI wakeup on MSI MS-1592 and MS-1594 dGPU root port Victor Carreras
2026-10-23  4:19 ` sashiko-bot
2026-10-23  8:11 ` Lukas Wunner
2026-10-24  5:48   ` Victor Carreras
2026-10-24  5:47 ` [PATCH v2] ACPI: x86: Disable " Victor Carreras
2026-10-24  6:00   ` sashiko-bot
2026-11-09 19:32   ` Rafael J. Wysocki (Intel)
2026-11-11  6:32     ` Victor Carreras
2026-11-11  6:32   ` Victor Carreras [this message]
2026-11-11  6:48     ` [PATCH v3] " sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111063221.14478-1-vicajilau@gmail.com \
    --to=vicajilau@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=hdegoede@redhat.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=mika.westerberg@linux.intel.com \
    --cc=rafael@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.