Skip to content

Commit 5a0be1b

Browse files
authored
Fix restore_params to restore all buses in multi-link streams
The restore_params block in _sdw_prepare_stream() was restoring only the last bus iterated when an error occurred. For multi-link streams with multiple buses, this left other buses in a partially reconfigured state. Fix this by: 1. Adding bpt_hstop to sdw_bus to track the BPT stream hstop value. 2. Adding saved_params and saved_bpt_hstop to sdw_master_runtime to store per-bus backup state. 3. Pre-saving all buses' params and bpt_hstop before the modify loop. 4. Restoring all buses from their per-bus saved state in restore_params. Addresses review comment: #5604 (comment)
1 parent 4a65266 commit 5a0be1b

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

drivers/soundwire/bus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ struct sdw_master_runtime {
172172
struct list_head port_list;
173173
struct list_head stream_node;
174174
struct list_head bus_node;
175+
struct sdw_bus_params saved_params;
176+
int saved_bpt_hstop;
175177
};
176178

177179
struct sdw_transport_data {

drivers/soundwire/stream.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,14 +1479,19 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
14791479
struct sdw_master_runtime *m_rt;
14801480
struct sdw_bus *bus;
14811481
struct sdw_master_prop *prop;
1482-
struct sdw_bus_params params;
14831482
int ret;
14841483

1484+
/* Pre-save all buses' params before making any changes, for error recovery */
1485+
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
1486+
bus = m_rt->bus;
1487+
memcpy(&m_rt->saved_params, &bus->params, sizeof(bus->params));
1488+
m_rt->saved_bpt_hstop = bus->bpt_hstop;
1489+
}
1490+
14851491
/* Prepare Master(s) and Slave(s) port(s) associated with stream */
14861492
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
14871493
bus = m_rt->bus;
14881494
prop = &bus->prop;
1489-
memcpy(&params, &bus->params, sizeof(params));
14901495

14911496
/* TODO: Support Asynchronous mode */
14921497
if ((prop->max_clk_freq % stream->params.rate) != 0) {
@@ -1542,7 +1547,11 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
15421547
return ret;
15431548

15441549
restore_params:
1545-
memcpy(&bus->params, &params, sizeof(params));
1550+
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
1551+
bus = m_rt->bus;
1552+
memcpy(&bus->params, &m_rt->saved_params, sizeof(bus->params));
1553+
bus->bpt_hstop = m_rt->saved_bpt_hstop;
1554+
}
15461555
return ret;
15471556
}
15481557

include/linux/soundwire/sdw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ struct sdw_stream_runtime {
10031003
* @stream_refcount: number of streams currently using this bus
10041004
* @bpt_stream_refcount: number of BTP streams currently using this bus (should
10051005
* be zero or one, multiple streams per link is not supported).
1006+
* @bpt_hstop: The hstop of the BPT stream.
10061007
* @bpt_stream: pointer stored to handle BTP streams.
10071008
* @ops: Master callback ops
10081009
* @port_ops: Master port callback ops
@@ -1043,6 +1044,7 @@ struct sdw_bus {
10431044
struct sdw_bus_params params;
10441045
int stream_refcount;
10451046
int bpt_stream_refcount;
1047+
int bpt_hstop;
10461048
struct sdw_stream_runtime *bpt_stream;
10471049
const struct sdw_master_ops *ops;
10481050
const struct sdw_master_port_ops *port_ops;

0 commit comments

Comments
 (0)