summaryrefslogtreecommitdiff
path: root/sound/soc/sof/amd/acp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/amd/acp.c')
-rw-r--r--sound/soc/sof/amd/acp.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index f24cd6b7490f..7a34faae9889 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -375,10 +375,13 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
static irqreturn_t acp_irq_handler(int irq, void *dev_id)
{
+ struct amd_sdw_manager *amd_manager;
struct snd_sof_dev *sdev = dev_id;
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
+ struct acp_dev_data *adata = sdev->pdata->hw_pdata;
unsigned int base = desc->dsp_intr_base;
unsigned int val;
+ 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) {
@@ -387,7 +390,38 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
return IRQ_WAKE_THREAD;
}
- return IRQ_NONE;
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat);
+ if (val & ACP_SDW0_IRQ_MASK) {
+ amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_SDW0_IRQ_MASK);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ irq_flag = 1;
+ }
+
+ if (val & 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, base + ACP_SW0_I2S_ERROR_REASON, 0);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_SW1_I2S_ERROR_REASON, 0);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + ACP_ERROR_STATUS, 0);
+ irq_flag = 1;
+ }
+
+ if (desc->ext_intr_stat1) {
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat1);
+ if (val & ACP_SDW1_IRQ_MASK) {
+ amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1,
+ ACP_SDW1_IRQ_MASK);
+ if (amd_manager)
+ schedule_work(&amd_manager->amd_sdw_irq_thread);
+ irq_flag = 1;
+ }
+ }
+ if (irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
}
static int acp_power_on(struct snd_sof_dev *sdev)
@@ -443,6 +477,8 @@ static int acp_reset(struct snd_sof_dev *sdev)
if (desc->ext_intr_enb)
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_enb, 0x01);
+ if (desc->ext_intr_cntl)
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_cntl, ACP_ERROR_IRQ_MASK);
return ret;
}