From 0aebe40bae6cf5652fdc3d05ecee15fbf5748194 Mon Sep 17 00:00:00 2001 From: Shreyas NC Date: Fri, 27 Jul 2018 14:44:08 +0530 Subject: [PATCH 1/3] soundwire: Fix duplicate stream state assignment For a SoundWire stream it is expected that a Slave is added to the stream before Master is added. So, move the stream state to CONFIGURED after the first Slave is added and remove the stream state assignment for Master add. Along with these changes, add additional comments to explain the same. Signed-off-by: Shreyas NC Acked-by: Pierre-Louis Bossart Signed-off-by: Vinod Koul --- drivers/soundwire/stream.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 4b5e250e8615..7ba6d4d8cd03 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1123,8 +1123,6 @@ int sdw_stream_add_master(struct sdw_bus *bus, if (ret) goto stream_error; - stream->state = SDW_STREAM_CONFIGURED; - stream_error: sdw_release_master_stream(stream); error: @@ -1141,6 +1139,10 @@ EXPORT_SYMBOL(sdw_stream_add_master); * @stream: SoundWire stream * @port_config: Port configuration for audio stream * @num_ports: Number of ports + * + * It is expected that Slave is added before adding Master + * to the Stream. + * */ int sdw_stream_add_slave(struct sdw_slave *slave, struct sdw_stream_config *stream_config, @@ -1186,6 +1188,12 @@ int sdw_stream_add_slave(struct sdw_slave *slave, if (ret) goto stream_error; + /* + * Change stream state to CONFIGURED on first Slave add. + * Bus is not aware of number of Slave(s) in a stream at this + * point so cannot depend on all Slave(s) to be added in order to + * change stream state to CONFIGURED. + */ stream->state = SDW_STREAM_CONFIGURED; goto error; From 3fef1a2259c556cce34df2791688cb3001f81c92 Mon Sep 17 00:00:00 2001 From: Shreyas NC Date: Fri, 27 Jul 2018 14:44:09 +0530 Subject: [PATCH 2/3] soundwire: Fix incorrect exit after configuring stream In sdw_stream_add_master() after the Master ports are configured, the stream is released incorrectly. So, fix it by avoiding stream release after configuring the Master for the stream. While at it, rename the label appropriately. Signed-off-by: Shreyas NC Acked-by: Pierre-Louis Bossart Signed-off-by: Vinod Koul --- drivers/soundwire/stream.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 7ba6d4d8cd03..b2682272503e 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1112,7 +1112,7 @@ int sdw_stream_add_master(struct sdw_bus *bus, "Master runtime config failed for stream:%s", stream->name); ret = -ENOMEM; - goto error; + goto unlock; } ret = sdw_config_stream(bus->dev, stream, stream_config, false); @@ -1123,9 +1123,11 @@ int sdw_stream_add_master(struct sdw_bus *bus, if (ret) goto stream_error; + goto unlock; + stream_error: sdw_release_master_stream(stream); -error: +unlock: mutex_unlock(&bus->bus_lock); return ret; } From 8d6ccf5cebbc7ed1dee9986e36853a78dfb64084 Mon Sep 17 00:00:00 2001 From: Sanyog Kale Date: Fri, 27 Jul 2018 14:44:10 +0530 Subject: [PATCH 3/3] soundwire: Fix acquiring bus lock twice during master release As part of sdw_stream_remove_master(), sdw_stream_remove_slave() is called which results in bus lock being acquired twice. So, fix it by performing specific Slave remove operations in sdw_release_master_stream() instead of calling sdw_stream_remove_slave(). Signed-off-by: Sanyog Kale Signed-off-by: Shreyas NC Acked-by: Pierre-Louis Bossart Signed-off-by: Vinod Koul --- drivers/soundwire/stream.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index b2682272503e..e5c7e1ef6318 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -899,9 +899,10 @@ static void sdw_release_master_stream(struct sdw_stream_runtime *stream) struct sdw_master_runtime *m_rt = stream->m_rt; struct sdw_slave_runtime *s_rt, *_s_rt; - list_for_each_entry_safe(s_rt, _s_rt, - &m_rt->slave_rt_list, m_rt_node) - sdw_stream_remove_slave(s_rt->slave, stream); + list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) { + sdw_slave_port_release(s_rt->slave->bus, s_rt->slave, stream); + sdw_release_slave_stream(s_rt->slave, stream); + } list_del(&m_rt->bus_node); }