diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2022-01-26 09:17:14 +0800 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2022-02-11 12:17:55 +0530 |
commit | f3016b891c8c6f11434eab5b92a0bbc21c1dfb6e (patch) | |
tree | 1b027964c30d19ad2e7c88d07c675ef035e1d1c8 /drivers/soundwire | |
parent | 5e1df5431f5b68f178c016e7015fb244e9510370 (diff) |
soundwire: stream: sdw_stream_add_ functions can be called multiple times
The sdw_stream_add_slave/master() functions are called from the
.hw_params stage. We need to make sure the functions can be called
multiple times.
In this version, we assume that only 'audio' parameters provide in the
hw_params() can change. If the number of ports could change
dynamically depending on the stream configuration (number of channels,
etc), we would need to free-up all the stream resources and reallocate
them.
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-19-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/soundwire')
-rw-r--r-- | drivers/soundwire/stream.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index a52a9ab0eea1..ccf3c99dd579 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -898,6 +898,11 @@ static void sdw_port_free(struct sdw_port_runtime *p_rt) kfree(p_rt); } +static bool sdw_slave_port_allocated(struct sdw_slave_runtime *s_rt) +{ + return !list_empty(&s_rt->port_list); +} + static void sdw_slave_port_free(struct sdw_slave *slave, struct sdw_stream_runtime *stream) { @@ -972,6 +977,11 @@ static int sdw_slave_port_config(struct sdw_slave *slave, return 0; } +static bool sdw_master_port_allocated(struct sdw_master_runtime *m_rt) +{ + return !list_empty(&m_rt->port_list); +} + static void sdw_master_port_free(struct sdw_master_runtime *m_rt) { struct sdw_port_runtime *p_rt, *_p_rt; @@ -1856,12 +1866,17 @@ int sdw_stream_add_master(struct sdw_bus *bus, } skip_alloc_master_rt: + if (sdw_master_port_allocated(m_rt)) + goto skip_alloc_master_port; + ret = sdw_master_port_alloc(m_rt, num_ports); if (ret) goto alloc_error; stream->m_rt_count++; +skip_alloc_master_port: + ret = sdw_master_rt_config(m_rt, stream_config); if (ret < 0) goto unlock; @@ -1970,6 +1985,10 @@ int sdw_stream_add_slave(struct sdw_slave *slave, } skip_alloc_master_rt: + s_rt = sdw_slave_rt_find(slave, stream); + if (s_rt) + goto skip_alloc_slave_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); @@ -1978,10 +1997,15 @@ skip_alloc_master_rt: goto alloc_error; } +skip_alloc_slave_rt: + if (sdw_slave_port_allocated(s_rt)) + goto skip_port_alloc; + ret = sdw_slave_port_alloc(slave, s_rt, num_ports); if (ret) goto alloc_error; +skip_port_alloc: ret = sdw_master_rt_config(m_rt, stream_config); if (ret) goto unlock; |