Commit 010c050f authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown

ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately

By acking a received message we tell the DSP that we have processed the
message (reply or notification) and we are open to receive a new one.

The original implementation did this in a common code after the received
message got handled as reply or notification.

With right timing this opens up a small window when we have processed the
reply and let the other thread proceed to send a new message to the DSP,
which is allowed as the DSP is free to receive message.
But when the message is received and processed by the DSP and it wants to
send a reply it will still see that the previous message has not been
acked, so it fails to send a reply. Later the first reply got acked by the
kernel, but it is too late and the in-flight message got a timeout due to
firmware not responding (which it tried, but could not).
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Link: https://lore.kernel.org/r/20221018124008.6846-5-peter.ujfalusi@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 483e4cdf
...@@ -72,6 +72,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context) ...@@ -72,6 +72,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
spin_lock_irq(&sdev->ipc_lock); spin_lock_irq(&sdev->ipc_lock);
snd_sof_ipc_get_reply(sdev); snd_sof_ipc_get_reply(sdev);
cnl_ipc_host_done(sdev);
snd_sof_ipc_reply(sdev, data->primary); snd_sof_ipc_reply(sdev, data->primary);
spin_unlock_irq(&sdev->ipc_lock); spin_unlock_irq(&sdev->ipc_lock);
...@@ -88,10 +89,10 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context) ...@@ -88,10 +89,10 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
sdev->ipc->msg.rx_data = &notification_data; sdev->ipc->msg.rx_data = &notification_data;
snd_sof_ipc_msgs_rx(sdev); snd_sof_ipc_msgs_rx(sdev);
sdev->ipc->msg.rx_data = NULL; sdev->ipc->msg.rx_data = NULL;
}
/* Let DSP know that we have finished processing the message */ /* Let DSP know that we have finished processing the message */
cnl_ipc_host_done(sdev); cnl_ipc_host_done(sdev);
}
ipc_irq = true; ipc_irq = true;
} }
......
...@@ -169,6 +169,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) ...@@ -169,6 +169,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
spin_lock_irq(&sdev->ipc_lock); spin_lock_irq(&sdev->ipc_lock);
snd_sof_ipc_get_reply(sdev); snd_sof_ipc_get_reply(sdev);
hda_dsp_ipc_host_done(sdev);
snd_sof_ipc_reply(sdev, data->primary); snd_sof_ipc_reply(sdev, data->primary);
spin_unlock_irq(&sdev->ipc_lock); spin_unlock_irq(&sdev->ipc_lock);
...@@ -185,10 +186,10 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) ...@@ -185,10 +186,10 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
sdev->ipc->msg.rx_data = &notification_data; sdev->ipc->msg.rx_data = &notification_data;
snd_sof_ipc_msgs_rx(sdev); snd_sof_ipc_msgs_rx(sdev);
sdev->ipc->msg.rx_data = NULL; sdev->ipc->msg.rx_data = NULL;
}
/* Let DSP know that we have finished processing the message */ /* Let DSP know that we have finished processing the message */
hda_dsp_ipc_host_done(sdev); hda_dsp_ipc_host_done(sdev);
}
ipc_irq = true; ipc_irq = true;
} }
......
...@@ -540,6 +540,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) ...@@ -540,6 +540,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
spin_lock_irq(&sdev->ipc_lock); spin_lock_irq(&sdev->ipc_lock);
snd_sof_ipc_get_reply(sdev); snd_sof_ipc_get_reply(sdev);
mtl_ipc_host_done(sdev);
snd_sof_ipc_reply(sdev, data->primary); snd_sof_ipc_reply(sdev, data->primary);
spin_unlock_irq(&sdev->ipc_lock); spin_unlock_irq(&sdev->ipc_lock);
...@@ -556,9 +557,9 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) ...@@ -556,9 +557,9 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
sdev->ipc->msg.rx_data = &notification_data; sdev->ipc->msg.rx_data = &notification_data;
snd_sof_ipc_msgs_rx(sdev); snd_sof_ipc_msgs_rx(sdev);
sdev->ipc->msg.rx_data = NULL; sdev->ipc->msg.rx_data = NULL;
}
mtl_ipc_host_done(sdev); mtl_ipc_host_done(sdev);
}
ipc_irq = true; ipc_irq = true;
} }
......
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