From 3d3d1fb9ce34bc045b9d140a5f2ec531eff6a0fe Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 26 May 2020 15:36:39 -0500 Subject: ASoC: SOF: Intel: BYT: mask BUSY or DONE interrupts in handler The DSP may send the same interrupt multiple times before it's handled in the interrupt thread. Rather than masking it in the thread, mask it in the handler directly. This patch also removes useless checks that cannot happen, and masks that are set don't need to be re-tested. Suggested-by: Keyon Jie Signed-off-by: Pierre-Louis Bossart Tested-by: Enric Balletbo i Serra Reviewed-by: Ranjani Sridharan BugLink: https://github.com/thesofproject/linux/issues/1492 Link: https://lore.kernel.org/r/20200526203640.25980-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/byt.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'sound') diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 8784c7319098..c6ac914ee56c 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -160,13 +160,31 @@ static void byt_dump(struct snd_sof_dev *sdev, u32 flags) static irqreturn_t byt_irq_handler(int irq, void *context) { struct snd_sof_dev *sdev = context; - u64 isr; + u64 ipcx, ipcd; int ret = IRQ_NONE; - /* Interrupt arrived, check src */ - isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX); - if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY)) + ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); + ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); + + if (ipcx & SHIM_BYT_IPCX_DONE) { + + /* reply message from DSP, Mask Done interrupt first */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, + SHIM_IMRX, + SHIM_IMRX_DONE, + SHIM_IMRX_DONE); ret = IRQ_WAKE_THREAD; + } + + if (ipcd & SHIM_BYT_IPCD_BUSY) { + + /* new message from DSP, Mask Busy interrupt first */ + snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, + SHIM_IMRX, + SHIM_IMRX_BUSY, + SHIM_IMRX_BUSY); + ret = IRQ_WAKE_THREAD; + } return ret; } @@ -175,19 +193,12 @@ static irqreturn_t byt_irq_thread(int irq, void *context) { struct snd_sof_dev *sdev = context; u64 ipcx, ipcd; - u64 imrx; - imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); + ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); /* reply message from DSP */ - if (ipcx & SHIM_BYT_IPCX_DONE && - !(imrx & SHIM_IMRX_DONE)) { - /* Mask Done interrupt before first */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, - SHIM_IMRX, - SHIM_IMRX_DONE, - SHIM_IMRX_DONE); + if (ipcx & SHIM_BYT_IPCX_DONE) { spin_lock_irq(&sdev->ipc_lock); @@ -207,14 +218,7 @@ static irqreturn_t byt_irq_thread(int irq, void *context) } /* new message from DSP */ - ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); - if (ipcd & SHIM_BYT_IPCD_BUSY && - !(imrx & SHIM_IMRX_BUSY)) { - /* Mask Busy interrupt before return */ - snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, - SHIM_IMRX, - SHIM_IMRX_BUSY, - SHIM_IMRX_BUSY); + if (ipcd & SHIM_BYT_IPCD_BUSY) { /* Handle messages from DSP Core */ if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { -- cgit v1.2.3