* [PATCH] acpi: pci_root: Add quirks table for _OSC support
@ 2026-08-03 20:34 Derek J. Clark
2026-08-04 12:46 ` Rafael J. Wysocki (Intel)
0 siblings, 1 reply; 4+ messages in thread
From: Derek J. Clark @ 2026-08-03 20:34 UTC (permalink / raw)
To: Rafael J . Wysocki
Cc: Bjorn Helgaas, Len Brown, linux-pci, linux-acpi, linux-kernel,
Derek J . Clark, Pierre-Loup A . Griffais
The MSI Claw A8 hard-locks on resume from s2idle whenever an SD/MMC
card is present in the RTS525A card reader (10ec:525a, PCI ID). This
issue is not present on the Lenovo Legion Go with the same card reader.
The primary difference is that the Claw A8 withholds LTR and DPC while
granting ASPM control to the OS, leading to a split ownership. The issue
can be mitigated by passing pcie_asmp=off, but quirking on the pci_dev
in pci/quirks has no effect.
Attempted quirks included use of pci_disable_link_state(),
dev->link_state = NULL, manually zeroing aspm_l0s_support/aspm_l1_support
via DECLARE_PCI_FIXUP_FINAL, and pcie_aspm_remove_cap() on
DECLARE_PCI_FIXUP_HEADER. Only by disabling ASPM on the root hub is the
system able to resume successfully. This strongly suggests a race between
the OS resuming the link under its own ASPM assumptions and firmware
independently acting on the same link based on state it never
relinquished.
As an attempt to localize the workaround to as low level as possible
while also being effective, introduce a quirk system to the existing
acpi pci_root calculate_support() mechanism.
Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
---
drivers/acpi/pci_root.c | 68 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 6f78f96332ea..abd436a10438 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -422,7 +422,69 @@ static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask,
return AE_OK;
}
-static u32 calculate_support(void)
+/*
+ * Some platforms advertise ASPM support in _OSC but withhold related
+ * control (e.g. LTR, DPC) from the OS on a specific root complex. The
+ * resulting split ownership between OS-managed ASPM and firmware-owned
+ * LTR/DPC can cause resume failures on s2idle. Rather than disabling
+ * ASPM system-wide, strip the offending support bits only on the
+ * affected root bridge so the OS abstains from requesting _OSC control
+ * there, leaving every other root complex on the system unaffected.
+ */
+struct osc_support_quirk {
+ const struct dmi_system_id dmi_match[2];
+ u16 segment;
+ u8 bus;
+ u32 strip_support;
+};
+
+static const struct osc_support_quirk osc_support_quirks[] = {
+ /*
+ * MSI Claw A8 (MS-1T8K): firmware withholds LTR/DPC control on
+ * the primary root complex despite advertising ASPM support,
+ * causing a hard lock on s2idle resume when the onboard RTS525A
+ * SD card reader is populated.
+ */
+ {
+ .dmi_match = {
+ {
+ .ident = "MSI Claw A8 BZ2EM",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "Micro-Star International Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "MS-1T8K"),
+ },
+ },
+ {}
+ },
+ .segment = 0,
+ .bus = 0,
+ .strip_support = OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT,
+ },
+};
+
+static u32 pci_osc_support_quirk_mask(struct acpi_pci_root *root)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(osc_support_quirks); i++) {
+ const struct osc_support_quirk *q = &osc_support_quirks[i];
+
+ if (dmi_first_match(q->dmi_match) &&
+ root->segment == q->segment &&
+ root->secondary.start == q->bus) {
+ dev_info(&root->device->dev,
+ "PCI Root Bridge [%04x:%02x] _OSC quirk: stripping support 0x%08x (%s)\n",
+ root->segment, (unsigned int)root->secondary.start,
+ q->strip_support, q->dmi_match[0].ident);
+ return ~q->strip_support;
+ }
+ }
+
+ return ~0;
+}
+
+static u32 calculate_support(struct acpi_pci_root *root)
{
u32 support;
@@ -441,6 +503,8 @@ static u32 calculate_support(void)
if (IS_ENABLED(CONFIG_PCIE_EDR))
support |= OSC_PCI_EDR_SUPPORT;
+ support &= pci_osc_support_quirk_mask(root);
+
return support;
}
@@ -571,7 +635,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
return;
}
- support = calculate_support();
+ support = calculate_support(root);
decode_osc_support(root, "OS supports", support);
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] acpi: pci_root: Add quirks table for _OSC support
2026-08-03 20:34 [PATCH] acpi: pci_root: Add quirks table for _OSC support Derek J. Clark
@ 2026-08-04 12:46 ` Rafael J. Wysocki (Intel)
2026-08-04 13:08 ` Rafael J. Wysocki (Intel)
0 siblings, 1 reply; 4+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-08-04 12:46 UTC (permalink / raw)
To: Derek J. Clark
Cc: Bjorn Helgaas, linux-pci, linux-acpi, linux-kernel,
Pierre-Loup A . Griffais, David Box
On Mon, Aug 3, 2026 at 10:35 PM Derek J. Clark
<derekjohn.clark@gmail.com> wrote:
>
> The MSI Claw A8 hard-locks on resume from s2idle whenever an SD/MMC
> card is present in the RTS525A card reader (10ec:525a, PCI ID). This
> issue is not present on the Lenovo Legion Go with the same card reader.
> The primary difference is that the Claw A8 withholds LTR and DPC while
> granting ASPM control to the OS, leading to a split ownership. The issue
> can be mitigated by passing pcie_asmp=off, but quirking on the pci_dev
You mean pcie_aspm=off I suppose.
> in pci/quirks has no effect.
>
> Attempted quirks included use of pci_disable_link_state(),
> dev->link_state = NULL, manually zeroing aspm_l0s_support/aspm_l1_support
> via DECLARE_PCI_FIXUP_FINAL, and pcie_aspm_remove_cap() on
> DECLARE_PCI_FIXUP_HEADER. Only by disabling ASPM on the root hub is the
> system able to resume successfully.
So if there is a clash between the firmware and the OS, the question
is why it only happens during system resume and only for this specific
device in this specific configuration.
If disabling ASPM globally makes the symptom go away, it certainly is
related to ASPM, but it is kind of hard to say what exactly the
relationship is at this point.
> This strongly suggests a race between
> the OS resuming the link under its own ASPM assumptions and firmware
> independently acting on the same link based on state it never
> relinquished.
I'd like to see a boot log from the affected platform including the
entire PCI _OSC negotiation.
There actually is no way for the firmware to grant or refuse the ASPM
control to the OS separately. It is part of the PCI Express
Capability Structure covered by OSC_PCI_EXPRESS_CAPABILITY_CONTROL, so
if that control bit is acknowledged via _OSC, the OS is supposed to
control ASPM (among other things).
The LTR and DPC are extended capabilities, so in principle they may be
controlled separately, if the OS controls the PCI Express Capability
structure, and there is no formal requirement to grant control of any
of them for ASPM to work.
> As an attempt to localize the workaround to as low level as possible
> while also being effective, introduce a quirk system to the existing
> acpi pci_root calculate_support() mechanism.
I'm not sure if there is a need to tell the firmware that ASPM is not
supported. You may as well avoid asking for
OSC_PCI_EXPRESS_CAPABILITY_CONTROL on the affected platform.
> Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
> ---
> drivers/acpi/pci_root.c | 68 +++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 66 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 6f78f96332ea..abd436a10438 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -422,7 +422,69 @@ static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask,
> return AE_OK;
> }
>
> -static u32 calculate_support(void)
> +/*
> + * Some platforms advertise ASPM support in _OSC but withhold related
> + * control (e.g. LTR, DPC) from the OS on a specific root complex. The
> + * resulting split ownership between OS-managed ASPM and firmware-owned
> + * LTR/DPC can cause resume failures on s2idle. Rather than disabling
> + * ASPM system-wide, strip the offending support bits only on the
> + * affected root bridge so the OS abstains from requesting _OSC control
> + * there, leaving every other root complex on the system unaffected.
> + */
> +struct osc_support_quirk {
> + const struct dmi_system_id dmi_match[2];
> + u16 segment;
> + u8 bus;
> + u32 strip_support;
> +};
> +
> +static const struct osc_support_quirk osc_support_quirks[] = {
> + /*
> + * MSI Claw A8 (MS-1T8K): firmware withholds LTR/DPC control on
> + * the primary root complex despite advertising ASPM support,
> + * causing a hard lock on s2idle resume when the onboard RTS525A
> + * SD card reader is populated.
> + */
> + {
> + .dmi_match = {
> + {
> + .ident = "MSI Claw A8 BZ2EM",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR,
> + "Micro-Star International Co., Ltd."),
> + DMI_MATCH(DMI_BOARD_NAME, "MS-1T8K"),
> + },
> + },
> + {}
> + },
> + .segment = 0,
> + .bus = 0,
> + .strip_support = OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT,
> + },
> +};
> +
> +static u32 pci_osc_support_quirk_mask(struct acpi_pci_root *root)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(osc_support_quirks); i++) {
> + const struct osc_support_quirk *q = &osc_support_quirks[i];
> +
> + if (dmi_first_match(q->dmi_match) &&
> + root->segment == q->segment &&
> + root->secondary.start == q->bus) {
> + dev_info(&root->device->dev,
> + "PCI Root Bridge [%04x:%02x] _OSC quirk: stripping support 0x%08x (%s)\n",
> + root->segment, (unsigned int)root->secondary.start,
> + q->strip_support, q->dmi_match[0].ident);
> + return ~q->strip_support;
> + }
> + }
> +
> + return ~0;
> +}
> +
> +static u32 calculate_support(struct acpi_pci_root *root)
> {
> u32 support;
>
> @@ -441,6 +503,8 @@ static u32 calculate_support(void)
> if (IS_ENABLED(CONFIG_PCIE_EDR))
> support |= OSC_PCI_EDR_SUPPORT;
>
> + support &= pci_osc_support_quirk_mask(root);
> +
> return support;
> }
>
> @@ -571,7 +635,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
> return;
> }
>
> - support = calculate_support();
> + support = calculate_support(root);
This will delay the initialization of any system, not just the quirky
one. Is there any way to avoid that?
> decode_osc_support(root, "OS supports", support);
>
> --
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] acpi: pci_root: Add quirks table for _OSC support
2026-08-04 12:46 ` Rafael J. Wysocki (Intel)
@ 2026-08-04 13:08 ` Rafael J. Wysocki (Intel)
2026-08-05 0:42 ` Derek John Clark
0 siblings, 1 reply; 4+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-08-04 13:08 UTC (permalink / raw)
To: Derek J. Clark
Cc: Bjorn Helgaas, linux-pci, linux-acpi, linux-kernel,
Pierre-Loup A . Griffais, David Box
On Tue, Aug 4, 2026 at 2:46 PM Rafael J. Wysocki (Intel)
<rafael@kernel.org> wrote:
>
> On Mon, Aug 3, 2026 at 10:35 PM Derek J. Clark
> <derekjohn.clark@gmail.com> wrote:
> >
> > The MSI Claw A8 hard-locks on resume from s2idle whenever an SD/MMC
> > card is present in the RTS525A card reader (10ec:525a, PCI ID). This
> > issue is not present on the Lenovo Legion Go with the same card reader.
> > The primary difference is that the Claw A8 withholds LTR and DPC while
> > granting ASPM control to the OS, leading to a split ownership. The issue
> > can be mitigated by passing pcie_asmp=off, but quirking on the pci_dev
>
> You mean pcie_aspm=off I suppose.
>
> > in pci/quirks has no effect.
> >
> > Attempted quirks included use of pci_disable_link_state(),
> > dev->link_state = NULL, manually zeroing aspm_l0s_support/aspm_l1_support
> > via DECLARE_PCI_FIXUP_FINAL, and pcie_aspm_remove_cap() on
> > DECLARE_PCI_FIXUP_HEADER. Only by disabling ASPM on the root hub is the
> > system able to resume successfully.
>
> So if there is a clash between the firmware and the OS, the question
> is why it only happens during system resume and only for this specific
> device in this specific configuration.
>
> If disabling ASPM globally makes the symptom go away, it certainly is
> related to ASPM, but it is kind of hard to say what exactly the
> relationship is at this point.
Besides, does disabling ASPM globally affect what happens to LTR and
DPC? I think so.
If that is the case, maybe the suspend-resume code paths skip LTR and
DPC if ASPM is disabled and they do something to those capabilities
otherwise? LTR and DPC generally should not be touched by the system
suspend-resume paths if native_ltr and native_dpc are zero,
respectively.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] acpi: pci_root: Add quirks table for _OSC support
2026-08-04 13:08 ` Rafael J. Wysocki (Intel)
@ 2026-08-05 0:42 ` Derek John Clark
0 siblings, 0 replies; 4+ messages in thread
From: Derek John Clark @ 2026-08-05 0:42 UTC (permalink / raw)
To: Rafael J. Wysocki (Intel)
Cc: Bjorn Helgaas, linux-pci, linux-acpi, linux-kernel,
Pierre-Loup A . Griffais, David Box
On Tue, Aug 4, 2026 at 6:08 AM Rafael J. Wysocki (Intel)
<rafael@kernel.org> wrote:
>
> On Tue, Aug 4, 2026 at 2:46 PM Rafael J. Wysocki (Intel)
> <rafael@kernel.org> wrote:
> >
> > On Mon, Aug 3, 2026 at 10:35 PM Derek J. Clark
> > <derekjohn.clark@gmail.com> wrote:
> > >
> > > The MSI Claw A8 hard-locks on resume from s2idle whenever an SD/MMC
> > > card is present in the RTS525A card reader (10ec:525a, PCI ID). This
> > > issue is not present on the Lenovo Legion Go with the same card reader.
> > > The primary difference is that the Claw A8 withholds LTR and DPC while
> > > granting ASPM control to the OS, leading to a split ownership. The issue
> > > can be mitigated by passing pcie_asmp=off, but quirking on the pci_dev
> >
> > You mean pcie_aspm=off I suppose.
> >
Hi Rafael,
Indeed, that was a typo.
> > > in pci/quirks has no effect.
> > >
> > > Attempted quirks included use of pci_disable_link_state(),
> > > dev->link_state = NULL, manually zeroing aspm_l0s_support/aspm_l1_support
> > > via DECLARE_PCI_FIXUP_FINAL, and pcie_aspm_remove_cap() on
> > > DECLARE_PCI_FIXUP_HEADER. Only by disabling ASPM on the root hub is the
> > > system able to resume successfully.
> >
> > So if there is a clash between the firmware and the OS, the question
> > is why it only happens during system resume and only for this specific
> > device in this specific configuration.
> >
> > If disabling ASPM globally makes the symptom go away, it certainly is
> > related to ASPM, but it is kind of hard to say what exactly the
> > relationship is at this point.
>
> Besides, does disabling ASPM globally affect what happens to LTR and
> DPC? I think so.
>
> If that is the case, maybe the suspend-resume code paths skip LTR and
> DPC if ASPM is disabled and they do something to those capabilities
> otherwise? LTR and DPC generally should not be touched by the system
> suspend-resume paths if native_ltr and native_dpc are zero,
> respectively.
I'll be up-front that _OSC handling isn't in my wheelhouse of things I
have troubleshot before. After reviewing your feedback I
re-investigated my assumptions to get a better handle on exactly what
the mechanism was that was resolved by the quirk and found some
interesting results. The LTR/DPC asymmetry and ASPM disablement were
masking the real root cause of the failure. Upon looking at my dmesg
again I noted that the quirk caused _OSC negotiation to alter the
PCIeHotPlug control state.
Normal boot:
Aug 04 14:33:12 clawa8 kernel: acpi PNP0A08:00: _OSC: OS supports
[ExtendedConfig ASPM ClockPM Segments MSI EDR HPX-Type3]
Aug 04 14:33:12 clawa8 kernel: acpi PNP0A08:00: _OSC: platform does
not support [SHPCHotplug AER LTR DPC]
Aug 04 14:33:12 clawa8 kernel: acpi PNP0A08:00: _OSC: OS now controls
[PCIeHotplug PME PCIeCapability]
Quirked boot:
Aug 04 14:37:48 clawa8 kernel: acpi PNP0A08:00: PCI Root Bridge
[0000:00] _OSC quirk: stripping support 0x00000006 (MSI Claw A8 BZ2EM)
Aug 04 14:37:48 clawa8 kernel: acpi PNP0A08:00: _OSC: OS supports
[ExtendedConfig Segments MSI EDR HPX-Type3]
Aug 04 14:37:48 clawa8 kernel: acpi PNP0A08:00: _OSC: not requesting
OS control; OS requires [ExtendedConfig ASPM ClockPM MSI]
I then tested pcie_ports=compat and also was able to resume. After a
bit of back and forth I found that using pci/quirks.c and setting
native_pcie_hotplug = false on the root bridge in a HEADER quirk, I
was able to resolve this issue more cleanlyl. Given that, I'll be
sending a different patch to resolve this once I've more thoroughly
tested it to see if I can isolate it to the device itself and/or root
hub. Considering the possible performance hit you described, I think
that is a better path.
Thanks,
Derek
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-05 0:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 20:34 [PATCH] acpi: pci_root: Add quirks table for _OSC support Derek J. Clark
2026-08-04 12:46 ` Rafael J. Wysocki (Intel)
2026-08-04 13:08 ` Rafael J. Wysocki (Intel)
2026-08-05 0:42 ` Derek John Clark
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox