Commit 3d3d1fb9 authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown

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: default avatarKeyon Jie <yang.jie@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tested-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
BugLink: https://github.com/thesofproject/linux/issues/1492
Link: https://lore.kernel.org/r/20200526203640.25980-8-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent c691f0c6
...@@ -160,13 +160,31 @@ static void byt_dump(struct snd_sof_dev *sdev, u32 flags) ...@@ -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) static irqreturn_t byt_irq_handler(int irq, void *context)
{ {
struct snd_sof_dev *sdev = context; struct snd_sof_dev *sdev = context;
u64 isr; u64 ipcx, ipcd;
int ret = IRQ_NONE; int ret = IRQ_NONE;
/* Interrupt arrived, check src */ ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX); ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
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; 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; return ret;
} }
...@@ -175,19 +193,12 @@ static irqreturn_t byt_irq_thread(int irq, void *context) ...@@ -175,19 +193,12 @@ static irqreturn_t byt_irq_thread(int irq, void *context)
{ {
struct snd_sof_dev *sdev = context; struct snd_sof_dev *sdev = context;
u64 ipcx, ipcd; 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); 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 */ /* reply message from DSP */
if (ipcx & SHIM_BYT_IPCX_DONE && 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);
spin_lock_irq(&sdev->ipc_lock); spin_lock_irq(&sdev->ipc_lock);
...@@ -207,14 +218,7 @@ static irqreturn_t byt_irq_thread(int irq, void *context) ...@@ -207,14 +218,7 @@ static irqreturn_t byt_irq_thread(int irq, void *context)
} }
/* new message from DSP */ /* new message from DSP */
ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); if (ipcd & SHIM_BYT_IPCD_BUSY) {
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);
/* Handle messages from DSP Core */ /* Handle messages from DSP Core */
if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment