struct sdw_stream_runtime *stream)
{
struct sdw_master_runtime *m_rt;
+ bool alloc_master_rt = true;
int ret;
mutex_lock(&bus->bus_lock);
* 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) {
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;
{
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);
* 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.
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_rt_config(s_rt, stream_config);
+ ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
if (ret)
- goto stream_error;
+ goto alloc_error;
- ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
+ ret = sdw_master_rt_config(m_rt, stream_config);
if (ret)
- goto stream_error;
+ goto unlock;
- ret = sdw_slave_port_alloc(slave, s_rt, num_ports);
+ 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 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.
* 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;
}