summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijendar Mukunda <Vijendar.Mukunda@amd.com>2026-07-01 15:25:07 +0530
committerMark Brown <broonie@kernel.org>2026-07-03 17:30:51 +0100
commita3674345f90226758b1dfd55c594cc3d4cdf80f6 (patch)
tree7e79d8ce47a251691656477240dfb5f5fb45c098
parent78d99c2c5eee0f6cd1adfe33dd0c266baac50fb8 (diff)
ASoC: SOF: amd: add ACP7x IRQ handler for DSP IPC
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@amd.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://patch.msgid.link/20260701095759.1012929-7-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/sof/amd/acp.c49
1 files 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);