Skip to content

Commit 866e4d5

Browse files
keyonjieplbossart
authored andcommitted
ASoC: SOF: Intel: BYT: harden IPC initialization and handling
On probe and reset, we should not touch the SHIM_IMRD register since it is configured by firmware. The driver only configures SHIM_IMRX with the BUSY interrupt enabled by default and DONE interrupt disabled. When sending an IPC message, the DONE interrupt is enabled until the DSP response is provided. This sequence hardens the IPC communication and avoid interrupt-related issues when adding/removing modules or during system suspend-resume transitions. Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Signed-off-by: Keyon Jie <yang.jie@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
1 parent 64b06b0 commit 866e4d5

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

sound/soc/sof/intel/byt.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ static irqreturn_t byt_irq_thread(int irq, void *context)
236236

237237
static int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
238238
{
239+
/* unmask and prepare to receive Done interrupt */
240+
snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
241+
SHIM_IMRX_DONE, 0);
242+
239243
/* send the message */
240244
sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
241245
msg->msg_size);
@@ -301,7 +305,7 @@ static void byt_host_done(struct snd_sof_dev *sdev)
301305
SHIM_BYT_IPCD_DONE,
302306
SHIM_BYT_IPCD_DONE);
303307

304-
/* unmask busy interrupt */
308+
/* unmask and prepare to receive next new message */
305309
snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
306310
SHIM_IMRX_BUSY, 0);
307311
}
@@ -311,10 +315,6 @@ static void byt_dsp_done(struct snd_sof_dev *sdev)
311315
/* clear DONE bit - tell DSP we have completed */
312316
snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX,
313317
SHIM_BYT_IPCX_DONE, 0);
314-
315-
/* unmask Done interrupt */
316-
snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
317-
SHIM_IMRX_DONE, 0);
318318
}
319319

320320
/*
@@ -453,9 +453,10 @@ static int byt_suspend(struct snd_sof_dev *sdev, u32 target_state)
453453

454454
static int byt_resume(struct snd_sof_dev *sdev)
455455
{
456-
/* Enable Interrupt from both sides */
457-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
458-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
456+
/* enable BUSY and disable DONE Interrupt by default */
457+
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
458+
SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
459+
SHIM_IMRX_DONE);
459460

460461
return 0;
461462
}
@@ -606,9 +607,10 @@ static int tangier_pci_probe(struct snd_sof_dev *sdev)
606607
return ret;
607608
}
608609

609-
/* enable Interrupt from both sides */
610-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
611-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
610+
/* enable BUSY and disable DONE Interrupt by default */
611+
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
612+
SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
613+
SHIM_IMRX_DONE);
612614

613615
/* set default mailbox offset for FW ready message */
614616
sdev->dsp_box.offset = MBOX_OFFSET;
@@ -808,9 +810,10 @@ static int byt_acpi_probe(struct snd_sof_dev *sdev)
808810
return ret;
809811
}
810812

811-
/* enable Interrupt from both sides */
812-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
813-
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
813+
/* enable BUSY and disable DONE Interrupt by default */
814+
snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
815+
SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
816+
SHIM_IMRX_DONE);
814817

815818
/* set default mailbox offset for FW ready message */
816819
sdev->dsp_box.offset = MBOX_OFFSET;

0 commit comments

Comments
 (0)