diff options
Diffstat (limited to 'sound/soc/sof/amd/acp.c')
-rw-r--r-- | sound/soc/sof/amd/acp.c | 38 |
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; } |