All of lore.kernel.org
 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 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.