[PATCH 06/16] ASoC: SOF: amd: add ACP7x IRQ handler for DSP IPC
From: Vijendar Mukunda
Date: Wed Jul 01 2026 - 06:01:08 EST
Add acp7x_irq_handler() and register it from amd_sof_acp7x_probe() for
DSP doorbell IPC interrupts on ACP7.B/7.F.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx>
Reviewed-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx>
---
sound/soc/sof/amd/acp.c | 49 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index b2c319857ad8..5df984b93dec 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -580,6 +580,35 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
return IRQ_NONE;
}
+static irqreturn_t acp7x_irq_handler(int irq, void *dev_id)
+{
+ struct snd_sof_dev *sdev = dev_id;
+ const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
+ unsigned int base = desc->dsp_intr_base;
+ unsigned int val;
+ unsigned int ext_intr_stat;
+ int irq_flag = 0;
+
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
+ if (val & ACP_DSP_TO_HOST_IRQ) {
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET,
+ ACP_DSP_TO_HOST_IRQ);
+ return IRQ_WAKE_THREAD;
+ }
+
+ ext_intr_stat = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat);
+ if (ext_intr_stat & ACP_ERROR_IRQ_MASK) {
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_ERROR_IRQ_MASK);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_error_stat, 0);
+ irq_flag = 1;
+ }
+
+ if (irq_flag)
+ return IRQ_HANDLED;
+
+ return IRQ_NONE;
+}
+
static int acp_power_on(struct snd_sof_dev *sdev)
{
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
@@ -1039,6 +1068,7 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
const union acpi_object *obj;
struct acpi_device *adev;
unsigned int addr;
+ unsigned int irqflags;
int ret;
chip = get_chip_info(sdev->pdata);
@@ -1079,6 +1109,16 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
adev = ACPI_COMPANION(&pci->dev);
+ sdev->ipc_irq = pci->irq;
+ irqflags = IRQF_SHARED;
+
+ ret = request_threaded_irq(pci->irq, acp7x_irq_handler, acp_irq_thread,
+ irqflags, "AudioDSP", sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to register IRQ %d\n", sdev->ipc_irq);
+ goto unregister_dev;
+ }
+
if (adev) {
if (!acpi_dev_get_property(adev, "acp-sof-signed-firmware-image",
ACPI_TYPE_INTEGER, &obj))
@@ -1099,13 +1139,13 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
"sof-%s-code.bin", chip->name);
if (!adata->fw_code_bin) {
ret = -ENOMEM;
- goto unregister_dev;
+ goto free_ipc_irq;
}
adata->fw_data_bin = devm_kasprintf(sdev->dev, GFP_KERNEL,
"sof-%s-data.bin", chip->name);
if (!adata->fw_data_bin) {
ret = -ENOMEM;
- goto unregister_dev;
+ goto free_ipc_irq;
}
}
@@ -1115,6 +1155,8 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
return 0;
+free_ipc_irq:
+ free_irq(sdev->ipc_irq, sdev);
unregister_dev:
platform_device_unregister(adata->dmic_dev);
return ret;
@@ -1125,6 +1167,9 @@ void amd_sof_acp7x_remove(struct snd_sof_dev *sdev)
{
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
+ if (sdev->ipc_irq)
+ free_irq(sdev->ipc_irq, sdev);
+
if (adata->dmic_dev)
platform_device_unregister(adata->dmic_dev);
--
2.45.2