summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/amd/acp.c
diff options
context:
space:
mode:
authorAjit Kumar Pandey <AjitKumar.Pandey@amd.com>2021-11-17 11:37:17 +0200
committerMark Brown <broonie@kernel.org>2021-11-17 17:35:47 +0000
commit738a2b5e2cc9fd63d48faac11c8d60a5a2313a9d (patch)
treef1c6973638386a49d9098d1744298ee326c841fe /sound/soc/sof/amd/acp.c
parent7e51a9e38ab204eba2844b8773486392d7444435 (diff)
downloadlinux-738a2b5e2cc9fd63d48faac11c8d60a5a2313a9d.tar.bz2
ASoC: SOF: amd: Add IPC support for ACP IP block
Add IPC module for generic ACP block and exposed ops callback for to synchronize SOF IPC message between host and DSP Signed-off-by: Balakishore Pati <Balakishore.pati@amd.com> Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> Reviewed-by: Bard Liao <bard.liao@intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Link: https://lore.kernel.org/r/20211117093734.17407-5-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/amd/acp.c')
-rw-r--r--sound/soc/sof/amd/acp.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 3778f781f16a..43a57d15e3ca 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -233,6 +233,34 @@ static int acp_memory_init(struct snd_sof_dev *sdev)
return 0;
}
+static irqreturn_t acp_irq_thread(int irq, void *context)
+{
+ struct snd_sof_dev *sdev = context;
+ unsigned int val;
+
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
+ if (val & ACP_DSP_TO_HOST_IRQ) {
+ sof_ops(sdev)->irq_thread(irq, sdev);
+ val |= ACP_DSP_TO_HOST_IRQ;
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT, val);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+};
+
+static irqreturn_t acp_irq_handler(int irq, void *dev_id)
+{
+ struct snd_sof_dev *sdev = dev_id;
+ unsigned int val;
+
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
+ if (val)
+ return IRQ_WAKE_THREAD;
+
+ return IRQ_NONE;
+}
+
static int acp_power_on(struct snd_sof_dev *sdev)
{
unsigned int val;
@@ -318,9 +346,20 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
sdev->pdata->hw_pdata = adata;
+ sdev->ipc_irq = pci->irq;
+ ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
+ IRQF_SHARED, "AudioDSP", sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to register IRQ %d\n",
+ sdev->ipc_irq);
+ return ret;
+ }
+
ret = acp_init(sdev);
- if (ret < 0)
+ if (ret < 0) {
+ free_irq(sdev->ipc_irq, sdev);
return ret;
+ }
acp_memory_init(sdev);
@@ -330,6 +369,9 @@ EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
int amd_sof_acp_remove(struct snd_sof_dev *sdev)
{
+ if (sdev->ipc_irq)
+ free_irq(sdev->ipc_irq, sdev);
+
return acp_reset(sdev);
}
EXPORT_SYMBOL_NS(amd_sof_acp_remove, SND_SOC_SOF_AMD_COMMON);