From: Mario Limonciello <superm1@kernel.org>
To: Diogo Sousa <diogogsousa@gmail.com>,
Bjorn Helgaas <bhelgaas@google.com>,
linux-pci@vger.kernel.org
Cc: Vijendar Mukunda <Vijendar.Mukunda@amd.com>,
David Glushkov <david.glushkov@sntiq.com>,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] PCI: Disable async suspend for AMD rev 0x62 ACP and HD Audio
Date: Fri, 16 Oct 2026 16:43:26 -0500 [thread overview]
Message-ID: <d8a95ffc-d4ab-4c45-9d6d-53c49e3137aa@kernel.org> (raw)
In-Reply-To: <20261016135042.44914-1-diogogsousa@gmail.com>
On 10/16/26 08:50, Diogo Sousa wrote:
> On AMD platforms with a revision 0x62 ACP, such as Dragon Range and Fire
> Range laptops, the HD Audio controller usually stops responding after
> resume from suspend:
>
> snd_hda_intel 0000:69:00.6: CORB reset timeout#2, CORBRP = 65535
>
> Audio playback then stalls.
>
> The ACP (function 5) and the HD Audio controller (function 6) share an
> audio block whose power is gated by the firmware. In the AMD CPMACPV4
> SSDT, the _PS0 method of each function marks the function as present
> and then calls a common method that powers the block up only if exactly
> one function is present:
>
> Method (_PS0, 0, NotSerialized) // ACP; AZAL sets M279 instead
> {
> M278 = One
> M276 ()
> }
>
> Method (M276, 0, Serialized)
> {
> Acquire (M27E, 0xFFFF)
> If (!(M278 ^ M279))
> {
> Release (M27E)
> Return (Zero)
> }
>
> // Power up the audio block.
> ...
> }
>
> The presence flags are set outside the lock, and M276 calls a debug
> print method before the check, during which the AML interpreter can run
> other threads. So when the PM core resumes both functions in parallel,
> both flags can be set before either _PS0 reaches the check. Both _PS0
> methods then skip the power up, each assuming that the other function
> did it. An ACPICA trace of a failing resume shows exactly that: the
> M276 call of the ACP sees both flags set and returns early.
>
> Disable async suspend for both functions, so that the PM core never
> suspends or resumes them at the same time.
>
> This started with v7.1, which moved these ACPs from the RPL driver to
> the YC driver. With the ACP bound to the RPL driver, test resumes
> worked, but it isn't clear why the YC driver makes the race so much
> more likely.
>
> Fixes: df4148a5a3cf ("ASoC: Add DMIC support for the AMD RPL platform")
> Link: https://github.com/CachyOS/linux-cachyos/issues/950
> Assisted-by: LLM
> Signed-off-by: Diogo Sousa <diogogsousa@gmail.com>
> ---
> Tested on an ASUS ROG Strix G16 G614FR (Ryzen 9 9955HX3D, BIOS G614FR.317):
> without this patch (v7.2.9), every resume from s2idle broke audio; with it,
> on top of v7.3-rc7, three resumes in a row worked.
>
> This also covers the MSI Raider A18 HX A9WJG, for which a quirk matching its
> subsystem ID was posted:
> https://lore.kernel.org/r/20260606204547.11945-1-david.glushkov@sntiq.com
>
Before you go down this direction, can you please check for a BIOS update.
There was another issue very similar to this which was fixed by a BIOS
update.
https://gitlab.freedesktop.org/drm/amd/-/work_items/5529
> drivers/pci/quirks.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index de9bbccda21f..d4e4ab3c332e 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -1901,12 +1901,44 @@ static void quirk_jmicron_async_suspend(struct pci_dev *dev)
> }
> DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend);
> DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0, quirk_jmicron_async_suspend);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x2362, quirk_jmicron_async_suspend);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x236f, quirk_jmicron_async_suspend);
>
> +/*
> + * On AMD platforms with the revision 0x62 ACP (e.g. Dragon Range and Fire
> + * Range), the firmware power gates the ACP (function 5) and HD Audio
> + * (function 6) together. The _PS0 method of each function marks it as
> + * present and then powers up the shared audio hardware only if the other
> + * function isn't present yet. The marking isn't done under the lock that
> + * serializes the power up, so if both _PS0 methods run concurrently, they can
> + * both conclude that the hardware is already powered up. The HD Audio
> + * controller is then left unpowered, with all its registers reading ~0.
> + *
> + * Suspend and resume both functions synchronously, so that the PM core never
> + * transitions them at the same time.
> + */
> +static void quirk_amd_acp_hda_async_suspend(struct pci_dev *pdev)
> +{
> + struct pci_dev *acp;
> +
> + acp = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 5));
> + if (!acp)
> + return;
> +
> + if (acp->vendor == PCI_VENDOR_ID_AMD && acp->device == 0x15e2 &&
> + acp->revision == 0x62) {
> + device_disable_async_suspend(&pdev->dev);
> + pci_info(pdev, "async suspend disabled to avoid ACP/HD Audio power up race\n");
> + }
> +
> + pci_dev_put(acp);
> +}
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e2, quirk_amd_acp_hda_async_suspend);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e3, quirk_amd_acp_hda_async_suspend);
> +
> #ifdef CONFIG_X86_IO_APIC
> static void quirk_alder_ioapic(struct pci_dev *pdev)
> {
> int i;
>
> if ((pdev->class >> 8) != 0xff00)
>
> base-commit: 0fcb05b72344f40806cbe810de8872f1698bf053
next prev parent reply other threads:[~2026-10-16 21:43 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 13:50 Diogo Sousa
2026-10-16 21:43 ` Mario Limonciello [this message]
2026-10-17 8:39 ` Diogo Sousa
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=d8a95ffc-d4ab-4c45-9d6d-53c49e3137aa@kernel.org \
--to=superm1@kernel.org \
--cc=Vijendar.Mukunda@amd.com \
--cc=bhelgaas@google.com \
--cc=david.glushkov@sntiq.com \
--cc=diogogsousa@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-sound@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®