Skip to content

Commit ac3bc88

Browse files
plbossartvinodkoul
authored andcommitted
soundwire: stream: separate alloc and config within sdw_stream_add_xxx()
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> Link: https://lore.kernel.org/r/20220126011715.28204-17-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 42aad41 commit ac3bc88

1 file changed

Lines changed: 48 additions & 32 deletions

File tree

drivers/soundwire/stream.c

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,7 @@ int sdw_stream_add_master(struct sdw_bus *bus,
18111811
struct sdw_stream_runtime *stream)
18121812
{
18131813
struct sdw_master_runtime *m_rt;
1814+
bool alloc_master_rt = true;
18141815
int ret;
18151816

18161817
mutex_lock(&bus->bus_lock);
@@ -1832,39 +1833,43 @@ int sdw_stream_add_master(struct sdw_bus *bus,
18321833
* it first), if so skip allocation and go to configuration
18331834
*/
18341835
m_rt = sdw_master_rt_find(bus, stream);
1835-
if (m_rt)
1836+
if (m_rt) {
1837+
alloc_master_rt = false;
18361838
goto skip_alloc_master_rt;
1839+
}
18371840

18381841
m_rt = sdw_master_rt_alloc(bus, stream);
18391842
if (!m_rt) {
18401843
dev_err(bus->dev, "Master runtime alloc failed for stream:%s\n", stream->name);
18411844
ret = -ENOMEM;
18421845
goto unlock;
18431846
}
1847+
skip_alloc_master_rt:
1848+
1849+
ret = sdw_master_port_alloc(m_rt, num_ports);
1850+
if (ret)
1851+
goto alloc_error;
1852+
1853+
stream->m_rt_count++;
18441854

18451855
ret = sdw_master_rt_config(m_rt, stream_config);
18461856
if (ret < 0)
18471857
goto unlock;
18481858

1849-
skip_alloc_master_rt:
18501859
ret = sdw_config_stream(bus->dev, stream, stream_config, false);
18511860
if (ret)
1852-
goto stream_error;
1853-
1854-
ret = sdw_master_port_alloc(m_rt, num_ports);
1855-
if (ret)
1856-
goto stream_error;
1861+
goto unlock;
18571862

18581863
ret = sdw_master_port_config(m_rt, port_config);
1859-
if (ret)
1860-
goto stream_error;
1861-
1862-
stream->m_rt_count++;
18631864

18641865
goto unlock;
18651866

1866-
stream_error:
1867-
sdw_master_rt_free(m_rt, stream);
1867+
alloc_error:
1868+
/*
1869+
* we only cleanup what was allocated in this routine
1870+
*/
1871+
if (alloc_master_rt)
1872+
sdw_master_rt_free(m_rt, stream);
18681873
unlock:
18691874
mutex_unlock(&bus->bus_lock);
18701875
return ret;
@@ -1926,6 +1931,9 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
19261931
{
19271932
struct sdw_slave_runtime *s_rt;
19281933
struct sdw_master_runtime *m_rt;
1934+
bool alloc_master_rt = true;
1935+
bool alloc_slave_rt = true;
1936+
19291937
int ret;
19301938

19311939
mutex_lock(&slave->bus->bus_lock);
@@ -1935,8 +1943,10 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
19351943
* and go to configuration
19361944
*/
19371945
m_rt = sdw_master_rt_find(slave->bus, stream);
1938-
if (m_rt)
1946+
if (m_rt) {
1947+
alloc_master_rt = false;
19391948
goto skip_alloc_master_rt;
1949+
}
19401950

19411951
/*
19421952
* 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,
19461956
if (!m_rt) {
19471957
dev_err(&slave->dev, "Master runtime alloc failed for stream:%s\n", stream->name);
19481958
ret = -ENOMEM;
1949-
goto error;
1959+
goto unlock;
19501960
}
1951-
ret = sdw_master_rt_config(m_rt, stream_config);
1952-
if (ret < 0)
1953-
goto stream_error;
19541961

19551962
skip_alloc_master_rt:
19561963
s_rt = sdw_slave_rt_alloc(slave, m_rt);
19571964
if (!s_rt) {
19581965
dev_err(&slave->dev, "Slave runtime alloc failed for stream:%s\n", stream->name);
1966+
alloc_slave_rt = false;
19591967
ret = -ENOMEM;
1960-
goto stream_error;
1968+
goto alloc_error;
19611969
}
19621970

1963-
ret = sdw_slave_rt_config(s_rt, stream_config);
1971+
ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
19641972
if (ret)
1965-
goto stream_error;
1973+
goto alloc_error;
19661974

1967-
ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
1975+
ret = sdw_master_rt_config(m_rt, stream_config);
19681976
if (ret)
1969-
goto stream_error;
1977+
goto unlock;
19701978

1971-
ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
1979+
ret = sdw_slave_rt_config(s_rt, stream_config);
19721980
if (ret)
1973-
goto stream_error;
1981+
goto unlock;
1982+
1983+
ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
1984+
if (ret)
1985+
goto unlock;
19741986

19751987
ret = sdw_slave_port_config(slave, s_rt, port_config);
19761988
if (ret)
1977-
goto stream_error;
1989+
goto unlock;
19781990

19791991
/*
19801992
* Change stream state to CONFIGURED on first Slave add.
@@ -1983,15 +1995,19 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
19831995
* change stream state to CONFIGURED.
19841996
*/
19851997
stream->state = SDW_STREAM_CONFIGURED;
1986-
goto error;
1998+
goto unlock;
19871999

1988-
stream_error:
2000+
alloc_error:
19892001
/*
1990-
* we hit error so cleanup the stream, release all Slave(s) and
1991-
* Master runtime
2002+
* we only cleanup what was allocated in this routine. The 'else if'
2003+
* is intentional, the 'master_rt_free' will call sdw_slave_rt_free()
2004+
* internally.
19922005
*/
1993-
sdw_master_rt_free(m_rt, stream);
1994-
error:
2006+
if (alloc_master_rt)
2007+
sdw_master_rt_free(m_rt, stream);
2008+
else if (alloc_slave_rt)
2009+
sdw_slave_rt_free(slave, stream);
2010+
unlock:
19952011
mutex_unlock(&slave->bus->bus_lock);
19962012
return ret;
19972013
}

0 commit comments

Comments
 (0)