Skip to content

Commit c40d6b3

Browse files
jhovoldvinodkoul
authored andcommitted
soundwire: fix enumeration completion
The soundwire subsystem uses two completion structures that allow drivers to wait for soundwire device to become enumerated on the bus and initialised by their drivers, respectively. The code implementing the signalling is currently broken as it does not signal all current and future waiters and also uses the wrong reinitialisation function, which can potentially lead to memory corruption if there are still waiters on the queue. Not signalling future waiters specifically breaks sound card probe deferrals as codec drivers can not tell that the soundwire device is already attached when being reprobed. Some codec runtime PM implementations suffer from similar problems as waiting for enumeration during resume can also timeout despite the device already having been enumerated. Fixes: fb9469e ("soundwire: bus: fix race condition with enumeration_complete signaling") Fixes: a90def0 ("soundwire: bus: fix race condition with initialization_complete signaling") Cc: [email protected] # 5.7 Cc: Pierre-Louis Bossart <[email protected]> Cc: Rander Wang <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Reviewed-by: Pierre-Louis Bossart <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 06c2afb commit c40d6b3

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

drivers/soundwire/bus.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -922,16 +922,16 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
922922
"initializing enumeration and init completion for Slave %d\n",
923923
slave->dev_num);
924924

925-
init_completion(&slave->enumeration_complete);
926-
init_completion(&slave->initialization_complete);
925+
reinit_completion(&slave->enumeration_complete);
926+
reinit_completion(&slave->initialization_complete);
927927

928928
} else if ((status == SDW_SLAVE_ATTACHED) &&
929929
(slave->status == SDW_SLAVE_UNATTACHED)) {
930930
dev_dbg(&slave->dev,
931931
"signaling enumeration completion for Slave %d\n",
932932
slave->dev_num);
933933

934-
complete(&slave->enumeration_complete);
934+
complete_all(&slave->enumeration_complete);
935935
}
936936
slave->status = status;
937937
mutex_unlock(&bus->bus_lock);
@@ -1951,7 +1951,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
19511951
"signaling initialization completion for Slave %d\n",
19521952
slave->dev_num);
19531953

1954-
complete(&slave->initialization_complete);
1954+
complete_all(&slave->initialization_complete);
19551955

19561956
/*
19571957
* If the manager became pm_runtime active, the peripherals will be

0 commit comments

Comments
 (0)