summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hovold <johan+linaro@kernel.org>2023-07-05 14:30:11 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-08-11 11:57:55 +0200
commit48d1d0ce0782f995fda678508fdae35c5e9593f0 (patch)
treefe328d5d7a482b510cbb3d5b652fd1d50c77f471
parent7d949774e7c1a93980db4961b898313ec09744c3 (diff)
soundwire: fix enumeration completion
[ Upstream commit c40d6b3249b11d60e09d81530588f56233d9aa44 ] 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: fb9469e54fa7 ("soundwire: bus: fix race condition with enumeration_complete signaling") Fixes: a90def068127 ("soundwire: bus: fix race condition with initialization_complete signaling") Cc: stable@vger.kernel.org # 5.7 Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Cc: Rander Wang <rander.wang@linux.intel.com> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20230705123018.30903-2-johan+linaro@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/soundwire/bus.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 831d2d751d5d..0e0a19030c35 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -800,8 +800,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
"%s: initializing enumeration and init completion for Slave %d\n",
__func__, slave->dev_num);
- init_completion(&slave->enumeration_complete);
- init_completion(&slave->initialization_complete);
+ reinit_completion(&slave->enumeration_complete);
+ reinit_completion(&slave->initialization_complete);
} else if ((status == SDW_SLAVE_ATTACHED) &&
(slave->status == SDW_SLAVE_UNATTACHED)) {
@@ -809,7 +809,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
"%s: signaling enumeration completion for Slave %d\n",
__func__, slave->dev_num);
- complete(&slave->enumeration_complete);
+ complete_all(&slave->enumeration_complete);
}
slave->status = status;
mutex_unlock(&slave->bus->bus_lock);
@@ -1739,7 +1739,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
"%s: signaling initialization completion for Slave %d\n",
__func__, slave->dev_num);
- complete(&slave->initialization_complete);
+ complete_all(&slave->initialization_complete);
/*
* If the manager became pm_runtime active, the peripherals will be