Skip to content

Commit

Permalink
ASoC: SOF: Intel: BYT: mask BUSY or DONE interrupts in handler
Browse files Browse the repository at this point in the history
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.

BugLink: #1492
Suggested-by: Keyon Jie <yang.jie@linux.intel.com>
Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
  • Loading branch information
plbossart committed May 26, 2020
1 parent 8352018 commit 64b06b0
Showing 1 changed file with 25 additions and 21 deletions.
46 changes: 25 additions & 21 deletions sound/soc/sof/intel/byt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);

Expand All @@ -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) {
Expand Down

0 comments on commit 64b06b0

Please sign in to comment.