diff options
author | Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> | 2021-11-17 11:37:17 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-11-17 17:35:47 +0000 |
commit | 738a2b5e2cc9fd63d48faac11c8d60a5a2313a9d (patch) | |
tree | f1c6973638386a49d9098d1744298ee326c841fe /sound/soc/sof/amd/acp.c | |
parent | 7e51a9e38ab204eba2844b8773486392d7444435 (diff) | |
download | linux-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.c | 44 |
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); |