diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h index 8115c64dd48e2f..f065270c614a16 100644 --- a/drivers/soundwire/bus.h +++ b/drivers/soundwire/bus.h @@ -172,6 +172,8 @@ struct sdw_master_runtime { struct list_head port_list; struct list_head stream_node; struct list_head bus_node; + struct sdw_bus_params saved_params; + int saved_bpt_hstop; }; struct sdw_transport_data { diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index cbf7bd3d4e7bac..275600f5ae9660 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1479,14 +1479,19 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream, struct sdw_master_runtime *m_rt; struct sdw_bus *bus; struct sdw_master_prop *prop; - struct sdw_bus_params params; int ret; + /* Pre-save all buses' params before making any changes, for error recovery */ + list_for_each_entry(m_rt, &stream->master_list, stream_node) { + bus = m_rt->bus; + memcpy(&m_rt->saved_params, &bus->params, sizeof(bus->params)); + m_rt->saved_bpt_hstop = bus->bpt_hstop; + } + /* Prepare Master(s) and Slave(s) port(s) associated with stream */ list_for_each_entry(m_rt, &stream->master_list, stream_node) { bus = m_rt->bus; prop = &bus->prop; - memcpy(¶ms, &bus->params, sizeof(params)); /* TODO: Support Asynchronous mode */ if ((prop->max_clk_freq % stream->params.rate) != 0) { @@ -1542,7 +1547,11 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream, return ret; restore_params: - memcpy(&bus->params, ¶ms, sizeof(params)); + list_for_each_entry(m_rt, &stream->master_list, stream_node) { + bus = m_rt->bus; + memcpy(&bus->params, &m_rt->saved_params, sizeof(bus->params)); + bus->bpt_hstop = m_rt->saved_bpt_hstop; + } return ret; } diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 3e0d21132ef2f7..4789747edb1139 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -1003,6 +1003,9 @@ struct sdw_stream_runtime { * @stream_refcount: number of streams currently using this bus * @bpt_stream_refcount: number of BTP streams currently using this bus (should * be zero or one, multiple streams per link is not supported). + * @bpt_hstop: The column stop index (hstop) used by the BPT stream's DP0 port. + * This value determines the last column allocated to the BPT data path on + * lane 0, allowing audio streams to use the remaining columns. * @bpt_stream: pointer stored to handle BTP streams. * @ops: Master callback ops * @port_ops: Master port callback ops @@ -1043,6 +1046,7 @@ struct sdw_bus { struct sdw_bus_params params; int stream_refcount; int bpt_stream_refcount; + int bpt_hstop; struct sdw_stream_runtime *bpt_stream; const struct sdw_master_ops *ops; const struct sdw_master_port_ops *port_ops;