ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Tue, 18 Oct 2022 12:40:06 +0000 (15:40 +0300)
committerMark Brown <broonie@kernel.org>
Tue, 18 Oct 2022 18:16:43 +0000 (19:16 +0100)
Read both registers as the first step in the interrupt handler to make
sure that we are handling the event which triggered the interrupt.

The delayed reading of the target request register might reflect incorrect
information about the reason why the interrupt was risen.

Note also that the IPC3 interrupt handler is implemented in this way also.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Link: https://lore.kernel.org/r/20221018124008.6846-3-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda-ipc.c
sound/soc/sof/intel/mtl.c

index 19d0b1909bfd6a3505ae36f7ff6f42e9caf18447..2f2bcde4275906091825af0bff353c952eb27d81 100644 (file)
@@ -41,6 +41,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
        u32 hipcida, hipctdr;
 
        hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA);
+       hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
        if (hipcida & CNL_DSP_REG_HIPCIDA_DONE) {
                /* DSP received the message */
                snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
@@ -51,7 +52,6 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
                ipc_irq = true;
        }
 
-       hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
        if (hipctdr & CNL_DSP_REG_HIPCTDR_BUSY) {
                /* Message from DSP (reply or notification) */
                u32 hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
index 9b3667c705e4728c7d73ee292c86eae44c22979a..4118532faf3f1ed61dec0b54b18a9bd9c2ca5c01 100644 (file)
@@ -126,6 +126,8 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
        u32 hipcie, hipct;
 
        hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE);
+       hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
+
        if (hipcie & HDA_DSP_REG_HIPCIE_DONE) {
                /* DSP received the message */
                snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL,
@@ -135,7 +137,6 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
                ipc_irq = true;
        }
 
-       hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
        if (hipct & HDA_DSP_REG_HIPCT_BUSY) {
                /* Message from DSP (reply or notification) */
                u32 hipcte = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
index 10298532816feaff62f209d70fb916cf6a4a0ab3..a9b31b31a4e4ac7e36509f57fbedb900cb866862 100644 (file)
@@ -497,6 +497,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
        u32 hipctdr;
 
        hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
+       hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
 
        /* reply message from DSP */
        if (hipcida & MTL_DSP_REG_HFIPCXIDA_DONE) {
@@ -509,7 +510,6 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
                ipc_irq = true;
        }
 
-       hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
        if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) {
                /* Message from DSP (reply or notification) */
                u32 extension = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY);