From: Corey Smith <corsmith@gmail.com>
To: corsmith@gmail.com, Vijendar.Mukunda@amd.com,
venkataprasad.potturu@amd.com
Cc: linux-sound@vger.kernel.org
Subject: [PATCH 10/11] ASoC: amd: ps: harden the ACP interrupt path for ACP6x
Date: Tue, 27 Oct 2026 22:05:51 -0400 [thread overview]
Message-ID: <20261028020552.35278-11-corsmith@gmail.com> (raw)
In-Reply-To: <20261028020552.35278-1-corsmith@gmail.com>
The ACP PCI interrupt is requested before create_acp63_platform_devs()
populates adata->sdw, adata->pdm_dev and adata->sdw_dma_dev, while
acp63_irq_handler() unconditionally dereferences those pointers as soon
as the corresponding bit is set in ACP_EXTERNAL_INTR_STAT/_STAT1.
This was harmless on the ACP6.3 boards the driver was written for, but
on ACP6x the interrupt status/control register layout differs, so a
pending interrupt can be served while the device pointers are still
NULL. Because it happens in interrupt context that is a fatal exception
and panics the kernel on boot.
- only walk adata->sdw when it is non-NULL;
- only use adata->pdm_dev when it is non-NULL;
- only dispatch the SoundWire DMA handler once adata->sdw_dma_dev
exists;
- treat ACP6x like ACP6.3 in check_and_handle_sdw_dma_irq() so the DMA
interrupt status is recorded for the Rembrandt link as well.
Assisted-by: LLM
Signed-off-by: Corey Smith <corsmith@gmail.com>
---
sound/soc/amd/ps/pci-ps.c | 44 ++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 12 deletions(-)
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index a8032b5..569af08 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -112,6 +112,8 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32
break;
}
switch (adata->acp_rev) {
+ case ACP6X_PCI_REV:
+ case ACP6XR_PCI_REV:
case ACP63_PCI_REV:
adata->acp63_sdw0_dma_intr_stat[stream_id] = 1;
break;
@@ -126,6 +128,8 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32
}
}
switch (adata->acp_rev) {
+ case ACP6X_PCI_REV:
+ case ACP6XR_PCI_REV:
case ACP63_PCI_REV:
if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) {
writel(ACP63_P1_AUDIO1_RX_THRESHOLD,
@@ -209,18 +213,28 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
if (ext_intr_stat & ACP_SDW0_STAT) {
writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
- amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
- if (amd_manager)
- schedule_work(&amd_manager->amd_sdw_irq_thread);
+ /*
+ * The handler may run before the SoundWire manager devices
+ * have been created (shared IRQ lines can fire as soon as
+ * they are registered, and the ACP interrupts are enabled by
+ * acp_hw_init() before create_acp63_platform_devs() runs).
+ */
+ if (adata->sdw) {
+ amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ }
irq_flag = 1;
}
ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
if (ext_intr_stat1 & ACP_SDW1_STAT) {
writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
- amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
- if (amd_manager)
- schedule_work(&amd_manager->amd_sdw_irq_thread);
+ if (adata->sdw) {
+ amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ }
irq_flag = 1;
}
@@ -237,16 +251,22 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
wake_irq_flag = check_and_handle_acp70_sdw_wake_irq(adata);
if (ext_intr_stat & BIT(PDM_DMA_STAT)) {
- ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev);
writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
- if (ps_pdm_data->capture_stream)
- snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
+ if (adata->pdm_dev) {
+ ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev);
+ if (ps_pdm_data && ps_pdm_data->capture_stream)
+ snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
+ }
irq_flag = 1;
}
- sdw_dma_irq_flag = check_and_handle_sdw_dma_irq(adata, ext_intr_stat, ext_intr_stat1);
- if (sdw_dma_irq_flag)
- return IRQ_WAKE_THREAD;
+ /* The SoundWire DMA device may not exist yet during probe */
+ if (adata->sdw_dma_dev) {
+ sdw_dma_irq_flag = check_and_handle_sdw_dma_irq(adata, ext_intr_stat,
+ ext_intr_stat1);
+ if (sdw_dma_irq_flag)
+ return IRQ_WAKE_THREAD;
+ }
if (irq_flag || wake_irq_flag)
return IRQ_HANDLED;
--
2.56.0
next prev parent reply other threads:[~2026-10-28 2:06 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 2:05 [PATCH 0/11] ASoC/soundwire: AMD ACP6x (Rembrandt) SoundWire speaker support Corey Smith
2026-10-28 2:05 ` [PATCH 1/11] soundwire: amd: add ACP6x PCI revision ids Corey Smith
2026-10-28 2:05 ` [PATCH 2/11] soundwire: amd: support ACP6x SoundWire managers Corey Smith
2026-10-28 2:05 ` [PATCH 3/11] ASoC: amd: ps: add ACP6x PCI revision ids Corey Smith
2026-10-28 2:15 ` sashiko-bot
2026-10-28 2:05 ` [PATCH 4/11] ASoC: amd: ps: support ACP6x in the SoundWire DMA driver Corey Smith
2026-10-28 2:05 ` [PATCH 5/11] ASoC: amd: acp: add ACP6x (Rembrandt) SoundWire machine table Corey Smith
2026-10-28 2:05 ` [PATCH 6/11] ASoC: amd: acp-config: route HP Dragonfly Pro ONE through the ACP6x SDW stack Corey Smith
2026-10-28 2:05 ` [PATCH 7/11] ASoC: amd: ps: probe the ACP6x SoundWire stack Corey Smith
2026-10-28 2:20 ` sashiko-bot
2026-10-28 2:05 ` [PATCH 8/11] ASoC: amd: acp: add ACP6x SoundWire quirks and machine support Corey Smith
2026-10-28 2:22 ` sashiko-bot
2026-10-28 2:05 ` [PATCH 9/11] soundwire: amd: accept the legacy mipi-sdw-master-list property Corey Smith
2026-10-28 2:05 ` Corey Smith [this message]
2026-10-28 2:21 ` [PATCH 10/11] ASoC: amd: ps: harden the ACP interrupt path for ACP6x sashiko-bot
2026-10-28 2:05 ` [PATCH 11/11] soundwire: amd: provide defaults for the bus clock properties Corey Smith
2026-10-29 6:58 ` [PATCH 0/11] ASoC/soundwire: AMD ACP6x (Rembrandt) SoundWire speaker support Mukunda,Vijendar
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=20261028020552.35278-11-corsmith@gmail.com \
--to=corsmith@gmail.com \
--cc=Vijendar.Mukunda@amd.com \
--cc=linux-sound@vger.kernel.org \
--cc=venkataprasad.potturu@amd.com \
/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