Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Bard Liao <yung-chuan.liao@linux.intel.com>
To: alsa-devel@alsa-project.org, vkoul@kernel.org
Cc: vinod.koul@linaro.org, gregkh@linuxfoundation.org,
	pierre-louis.bossart@linux.intel.com,
	linux-kernel@vger.kernel.org, srinivas.kandagatla@linaro.org,
	sanyog.r.kale@intel.com, bard.liao@intel.com
Subject: [PATCH 16/19] soundwire: stream: separate alloc and config within sdw_stream_add_xxx()
Date: Wed, 26 Jan 2022 09:17:12 +0800	[thread overview]
Message-ID: <20220126011715.28204-17-yung-chuan.liao@linux.intel.com> (raw)
In-Reply-To: <20220126011715.28204-1-yung-chuan.liao@linux.intel.com>

From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Separate alloc and config parts so that follow-up patches can allow
for multiple calls to sdw_stream_add_slave/master. This is a feature
from the ALSA/ASoC frameworks which is not supported today.

This is an invasive patch which modifies the error handling flow, with
cleanups only done when an allocation fails. Configuration failures
only return an error code.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
 drivers/soundwire/stream.c | 81 ++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 33 deletions(-)

diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index 8a76d6605f93..03cfac0129af 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -1811,6 +1811,7 @@ int sdw_stream_add_master(struct sdw_bus *bus,
 			  struct sdw_stream_runtime *stream)
 {
 	struct sdw_master_runtime *m_rt;
+	bool alloc_master_rt = true;
 	int ret;
 
 	mutex_lock(&bus->bus_lock);
@@ -1832,8 +1833,10 @@ int sdw_stream_add_master(struct sdw_bus *bus,
 	 * it first), if so skip allocation and go to configuration
 	 */
 	m_rt = sdw_master_rt_find(bus, stream);
-	if (m_rt)
+	if (m_rt) {
+		alloc_master_rt = false;
 		goto skip_alloc_master_rt;
+	}
 
 	m_rt = sdw_master_rt_alloc(bus, stream);
 	if (!m_rt) {
@@ -1841,30 +1844,32 @@ int sdw_stream_add_master(struct sdw_bus *bus,
 		ret = -ENOMEM;
 		goto unlock;
 	}
+skip_alloc_master_rt:
+
+	ret = sdw_master_port_alloc(m_rt, num_ports);
+	if (ret)
+		goto alloc_error;
+
+	stream->m_rt_count++;
 
 	ret = sdw_master_rt_config(m_rt, stream_config);
 	if (ret < 0)
 		goto unlock;
 
-skip_alloc_master_rt:
 	ret = sdw_config_stream(bus->dev, stream, stream_config, false);
 	if (ret)
-		goto stream_error;
-
-	ret = sdw_master_port_alloc(m_rt, num_ports);
-	if (ret)
-		goto stream_error;
+		goto unlock;
 
 	ret = sdw_master_port_config(m_rt, port_config);
-	if (ret)
-		goto stream_error;
-
-	stream->m_rt_count++;
 
 	goto unlock;
 
-stream_error:
-	sdw_master_rt_free(m_rt, stream);
+alloc_error:
+	/*
+	 * we only cleanup what was allocated in this routine
+	 */
+	if (alloc_master_rt)
+		sdw_master_rt_free(m_rt, stream);
 unlock:
 	mutex_unlock(&bus->bus_lock);
 	return ret;
@@ -1926,6 +1931,9 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
 {
 	struct sdw_slave_runtime *s_rt;
 	struct sdw_master_runtime *m_rt;
+	bool alloc_master_rt = true;
+	bool alloc_slave_rt = true;
+
 	int ret;
 
 	mutex_lock(&slave->bus->bus_lock);
@@ -1935,8 +1943,10 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
 	 * and go to configuration
 	 */
 	m_rt = sdw_master_rt_find(slave->bus, stream);
-	if (m_rt)
+	if (m_rt) {
+		alloc_master_rt = false;
 		goto skip_alloc_master_rt;
+	}
 
 	/*
 	 * If this API is invoked by Slave first then m_rt is not valid.
@@ -1946,35 +1956,37 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
 	if (!m_rt) {
 		dev_err(&slave->dev, "Master runtime alloc failed for stream:%s\n", stream->name);
 		ret = -ENOMEM;
-		goto error;
+		goto unlock;
 	}
-	ret =  sdw_master_rt_config(m_rt, stream_config);
-	if (ret < 0)
-		goto stream_error;
 
 skip_alloc_master_rt:
 	s_rt = sdw_slave_rt_alloc(slave, m_rt);
 	if (!s_rt) {
 		dev_err(&slave->dev, "Slave runtime alloc failed for stream:%s\n", stream->name);
+		alloc_slave_rt = false;
 		ret = -ENOMEM;
-		goto stream_error;
+		goto alloc_error;
 	}
 
+	ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
+	if (ret)
+		goto alloc_error;
+
+	ret =  sdw_master_rt_config(m_rt, stream_config);
+	if (ret)
+		goto unlock;
+
 	ret = sdw_slave_rt_config(s_rt, stream_config);
 	if (ret)
-		goto stream_error;
+		goto unlock;
 
 	ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
 	if (ret)
-		goto stream_error;
-
-	ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
-	if (ret)
-		goto stream_error;
+		goto unlock;
 
 	ret = sdw_slave_port_config(slave, s_rt, port_config);
 	if (ret)
-		goto stream_error;
+		goto unlock;
 
 	/*
 	 * Change stream state to CONFIGURED on first Slave add.
@@ -1983,15 +1995,19 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
 	 * change stream state to CONFIGURED.
 	 */
 	stream->state = SDW_STREAM_CONFIGURED;
-	goto error;
+	goto unlock;
 
-stream_error:
+alloc_error:
 	/*
-	 * we hit error so cleanup the stream, release all Slave(s) and
-	 * Master runtime
+	 * we only cleanup what was allocated in this routine. The 'else if'
+	 * is intentional, the 'master_rt_free' will call sdw_slave_rt_free()
+	 * internally.
 	 */
-	sdw_master_rt_free(m_rt, stream);
-error:
+	if (alloc_master_rt)
+		sdw_master_rt_free(m_rt, stream);
+	else if (alloc_slave_rt)
+		sdw_slave_rt_free(slave, stream);
+unlock:
 	mutex_unlock(&slave->bus->bus_lock);
 	return ret;
 }
@@ -2018,4 +2034,3 @@ int sdw_stream_remove_slave(struct sdw_slave *slave,
 	return 0;
 }
 EXPORT_SYMBOL(sdw_stream_remove_slave);
-
-- 
2.17.1


  parent reply	other threads:[~2022-01-26  1:23 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-26  1:16 [PATCH 00/19] soundwire: stream: cleanup of 'stream' support Bard Liao
2022-01-26  1:16 ` [PATCH 01/19] soundwire: stream: remove unused parameter in sdw_stream_add_slave Bard Liao
2022-01-26  1:16 ` [PATCH 02/19] soundwire: stream: add slave runtime to list earlier Bard Liao
2022-01-26  1:16 ` [PATCH 03/19] soundwire: stream: simplify check on port range Bard Liao
2022-01-26  1:17 ` [PATCH 04/19] soundwire: stream: add alloc/config/free helpers for ports Bard Liao
2022-01-26  1:17 ` [PATCH 05/19] soundwire: stream: split port allocation and configuration loops Bard Liao
2022-01-26  1:17 ` [PATCH 06/19] soundwire: stream: split alloc and config in two functions Bard Liao
2022-01-26  1:17 ` [PATCH 07/19] soundwire: stream: add 'slave' prefix for port range checks Bard Liao
2022-01-26  1:17 ` [PATCH 08/19] soundwire: stream: group sdw_port and sdw_master/slave_port functions Bard Liao
2022-01-26  1:17 ` [PATCH 09/19] soundwire: stream: simplify sdw_alloc_master_rt() Bard Liao
2022-01-26  1:17 ` [PATCH 10/19] soundwire: stream: split sdw_alloc_master_rt() in alloc and config Bard Liao
2022-01-26  1:17 ` [PATCH 11/19] soundwire: stream: move sdw_alloc_slave_rt() before 'master' helpers Bard Liao
2022-01-26  1:17 ` [PATCH 12/19] soundwire: stream: split sdw_alloc_slave_rt() in alloc and config Bard Liao
2022-01-26  1:17 ` [PATCH 13/19] soundwire: stream: group sdw_stream_ functions Bard Liao
2022-01-26  1:17 ` [PATCH 14/19] soundwire: stream: rename and move master/slave_rt_free routines Bard Liao
2022-01-26  1:17 ` [PATCH 15/19] soundwire: stream: move list addition to sdw_slave_alloc_rt() Bard Liao
2022-01-26  1:17 ` Bard Liao [this message]
2022-01-26  1:17 ` [PATCH 17/19] soundwire: stream: introduce sdw_slave_rt_find() helper Bard Liao
2022-01-26  1:17 ` [PATCH 18/19] soundwire: stream: sdw_stream_add_ functions can be called multiple times Bard Liao
2022-01-26  1:17 ` [PATCH 19/19] soundwire: stream: make enable/disable/deprepare idempotent Bard Liao
2022-02-11  6:48 ` [PATCH 00/19] soundwire: stream: cleanup of 'stream' support Vinod Koul

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220126011715.28204-17-yung-chuan.liao@linux.intel.com \
    --to=yung-chuan.liao@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=bard.liao@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=sanyog.r.kale@intel.com \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=vinod.koul@linaro.org \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox