Skip to content

Commit de175eb

Browse files
committed
audio: dai-zephyr: migrate to use dai_get_properties_copy()
Modify code to allocate DAI properties object on stack and use dai_get_properties_copy() whenever available. Add a static helper function to share the implementation. This change is required to enable DAI code to run in user-space. In this scenario, it's not possible to directly use an object returned by driver, but instead data needs to be copied to user-space. As a side benefit, the need to use locking to protect the properties data is limited the fallback case when a driver does not implement the get_properties_copy() method and SOF is built with LL code running in kernel space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent dc2c3c7 commit de175eb

1 file changed

Lines changed: 64 additions & 32 deletions

File tree

src/audio/dai-zephyr.c

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -235,58 +235,90 @@ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config,
235235
return dai_config_set(dev, &cfg, cfg_params, dai_cfg_size);
236236
}
237237

238+
static int dai_get_properties_safe(struct dai *dai, int direction,
239+
int stream_id, struct dai_properties *props)
240+
{
241+
const struct dai_properties *props_p;
242+
int ret;
243+
244+
ret = dai_get_properties_copy(dai->dev, direction, stream_id, props);
245+
246+
/*
247+
* User LL builds require DAI drivers to implement the copy method.
248+
* Allow fallback to dai_get_properties() in kernel LL builds.
249+
*/
250+
if (ret == -ENOSYS && !IS_ENABLED(CONFIG_SOF_USERSPACE_LL)) {
251+
k_spinlock_key_t key = k_spin_lock(&dai->lock);
252+
253+
/* legacy support for drivers that do not implement copy */
254+
props_p = dai_get_properties(dai->dev, direction, stream_id);
255+
if (props_p) {
256+
*props = *props_p;
257+
ret = 0;
258+
} else {
259+
ret = -ENOENT;
260+
}
261+
262+
k_spin_unlock(&dai->lock, key);
263+
}
264+
265+
return ret;
266+
}
267+
238268
/* called from ipc/ipc3/dai.c */
239269
int dai_get_handshake(struct dai *dai, int direction, int stream_id)
240270
{
241-
k_spinlock_key_t key = k_spin_lock(&dai->lock);
242-
const struct dai_properties *props = dai_get_properties(dai->dev, direction,
243-
stream_id);
244-
int hs_id = props->dma_hs_id;
271+
struct dai_properties props;
272+
int ret;
245273

246-
k_spin_unlock(&dai->lock, key);
274+
ret = dai_get_properties_safe(dai, direction, stream_id, &props);
275+
if (ret < 0)
276+
return ret;
247277

248-
return hs_id;
278+
return props.dma_hs_id;
249279
}
250280

251281
/* called from ipc/ipc3/dai.c and ipc/ipc4/dai.c */
252282
int dai_get_fifo_depth(struct dai *dai, int direction)
253283
{
254-
const struct dai_properties *props;
255-
k_spinlock_key_t key;
256-
int fifo_depth;
284+
struct dai_properties props;
285+
int ret;
257286

258287
if (!dai)
259288
return 0;
260289

261-
key = k_spin_lock(&dai->lock);
262-
props = dai_get_properties(dai->dev, direction, 0);
263-
fifo_depth = props->fifo_depth;
264-
k_spin_unlock(&dai->lock, key);
290+
ret = dai_get_properties_safe(dai, direction, 0, &props);
265291

266-
return fifo_depth;
292+
if (ret < 0)
293+
return 0;
294+
295+
return props.fifo_depth;
267296
}
268297

269298
int dai_get_stream_id(struct dai *dai, int direction)
270299
{
271-
k_spinlock_key_t key = k_spin_lock(&dai->lock);
272-
const struct dai_properties *props = dai_get_properties(dai->dev, direction, 0);
273-
int stream_id = props->stream_id;
300+
struct dai_properties props;
301+
int ret;
274302

275-
k_spin_unlock(&dai->lock, key);
303+
ret = dai_get_properties_safe(dai, direction, 0, &props);
276304

277-
return stream_id;
305+
if (ret < 0)
306+
return ret;
307+
308+
return props.stream_id;
278309
}
279310

280311
static int dai_get_fifo(struct dai *dai, int direction, int stream_id)
281312
{
282-
k_spinlock_key_t key = k_spin_lock(&dai->lock);
283-
const struct dai_properties *props = dai_get_properties(dai->dev, direction,
284-
stream_id);
285-
int fifo_address = props->fifo_address;
313+
struct dai_properties props;
314+
int ret;
286315

287-
k_spin_unlock(&dai->lock, key);
316+
ret = dai_get_properties_safe(dai, direction, stream_id, &props);
317+
318+
if (ret < 0)
319+
return ret;
288320

289-
return fifo_address;
321+
return props.fifo_address;
290322
}
291323

292324
/* this is called by DMA driver every time descriptor has completed */
@@ -1982,17 +2014,17 @@ static int dai_ts_stop_op(struct comp_dev *dev)
19822014

19832015
uint32_t dai_get_init_delay_ms(struct dai *dai)
19842016
{
1985-
const struct dai_properties *props;
1986-
k_spinlock_key_t key;
1987-
uint32_t init_delay;
2017+
struct dai_properties props;
2018+
uint32_t init_delay = 0;
2019+
int ret;
19882020

19892021
if (!dai)
19902022
return 0;
19912023

1992-
key = k_spin_lock(&dai->lock);
1993-
props = dai_get_properties(dai->dev, 0, 0);
1994-
init_delay = props->reg_init_delay;
1995-
k_spin_unlock(&dai->lock, key);
2024+
ret = dai_get_properties_safe(dai, 0, 0, &props);
2025+
2026+
if (!ret)
2027+
init_delay = props.reg_init_delay;
19962028

19972029
return init_delay;
19982030
}

0 commit comments

Comments
 (0)