Linux Sound subsystem development
 help / color / mirror / Atom feed
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


  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