]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
soundwire: bus: fix race condition with enumeration_complete signaling
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Wed, 15 Jan 2020 00:08:36 +0000 (18:08 -0600)
committerVinod Koul <vkoul@kernel.org>
Tue, 25 Feb 2020 10:27:02 +0000 (15:57 +0530)
This patch adds the signaling needed for Slave drivers to wait until
the enumeration completes so that race conditions when issuing
read/write commands are avoided. The calls for wait_for_completion()
will be added in codec drivers in follow-up patches.

The order between init_completion() and complete() is deterministic,
the Slave is marked as UNATTACHED either during a Master-initiated
HardReset, or when the hardware detects the Slave no longer reports as
ATTACHED.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200115000844.14695-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/bus.c
drivers/soundwire/slave.c

index 4980dfd6f3a37dc974702390169f2b48701c18b3..a2267c3a1d2d61e2da094a01a87104b28735c776 100644 (file)
@@ -610,6 +610,26 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
                                    enum sdw_slave_status status)
 {
        mutex_lock(&slave->bus->bus_lock);
+
+       dev_vdbg(&slave->dev,
+                "%s: changing status slave %d status %d new status %d\n",
+                __func__, slave->dev_num, slave->status, status);
+
+       if (status == SDW_SLAVE_UNATTACHED) {
+               dev_dbg(&slave->dev,
+                       "%s: initializing completion for Slave %d\n",
+                       __func__, slave->dev_num);
+
+               init_completion(&slave->enumeration_complete);
+
+       } else if ((status == SDW_SLAVE_ATTACHED) &&
+                  (slave->status == SDW_SLAVE_UNATTACHED)) {
+               dev_dbg(&slave->dev,
+                       "%s: signaling completion for Slave %d\n",
+                       __func__, slave->dev_num);
+
+               complete(&slave->enumeration_complete);
+       }
        slave->status = status;
        mutex_unlock(&slave->bus->bus_lock);
 }
index 08db0488e02d5842b09e732e3cafb7e633665ea7..e767a78066ee1e8452d1ad0834c347288bff68a4 100644 (file)
@@ -46,6 +46,7 @@ static int sdw_slave_add(struct sdw_bus *bus,
        slave->dev.of_node = of_node_get(to_of_node(fwnode));
        slave->bus = bus;
        slave->status = SDW_SLAVE_UNATTACHED;
+       init_completion(&slave->enumeration_complete);
        slave->dev_num = 0;
        init_completion(&slave->probe_complete);
        slave->probed = false;