Skip to content

Commit 30adad5

Browse files
committed
soundwire: cadence: Clear message complete before signalling waiting thread
Clear the CDNS_MCP_INT_RX_WL interrupt before signalling completion. This is to prevent the potential race where: - the main thread is scheduled immediately the completion is signalled, and starts a new message - The RX_WL IRQ for this new message happens before sdw_cdns_irq() has been re-scheduled. - When sdw_cdns_irq() is re-scheduled it clears the new RX_WL interrupt. MAIN THREAD | IRQ THREAD | _cdns_xfer_msg() | { | write data to FIFO | wait_for_completion_timeout() | <BLOCKED> | <---- RX_WL IRQ | sdw_cdns_irq() | { | signal completion <== RESCHEDULE <== Handle message completion | } | | Start new message | _cdns_xfer_msg() | { | write data to FIFO | wait_for_completion_timeout() | <BLOCKED> | <---- RX_WL IRQ ==> RESCHEDULE ==> | // New RX_WL IRQ is cleared before | // it has been handled. | clear CDNS_MCP_INTSTAT | return IRQ_HANDLED; | } Before this change, this error message was sometimes seen on kernels that have large amounts of debugging enabled: SCP Msg trf timed out This error indicates that the completion has not been signalled after 500ms. Change-Id: Ia079e8956351d184631876bdde5904c1f6717b42 Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Fixes: 956baa1 ("soundwire: cdns: Add sdw_master_ops and IO transfer support")
1 parent 86b5062 commit 30adad5

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

drivers/soundwire/cadence_master.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,14 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
933933

934934
cdns_read_response(cdns);
935935

936+
/*
937+
* Clear interrupt before signalling the completion to avoid
938+
* a race between this thread and the main thread starting
939+
* another TX.
940+
*/
941+
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_RX_WL);
942+
int_status &= ~CDNS_MCP_INT_RX_WL;
943+
936944
if (defer && defer->msg) {
937945
cdns_fill_msg_resp(cdns, defer->msg,
938946
defer->length, 0);

0 commit comments

Comments
 (0)