Skip to content

Commit ead1b8b

Browse files
committed
ipc4: replace fw_reg spinlock with mutex
Replace the spinlock-based synchronization mechanism for firmware register access with a mutex-based approach. This change removes the fw_reg_lock spinlock field from the sof structure (both POSIX and Zephyr variants), eliminates the spinlock initialization in primary_core_init(), and updates the dai_dma_release(), dai_release_llp_slot(), and dai_get_unused_llp_slot() functions to use sys_mutex_lock/unlock instead of k_spin_lock/unlock. All SOF IPC and audio pipeline code is run in threads, so using spinlocks is no longer necessary. Using mutex is a best fit and allows the audio pipeline code to be used also in user-space threads. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent cfb488d commit ead1b8b

File tree

4 files changed

+22
-23
lines changed

4 files changed

+22
-23
lines changed

posix/include/rtos/sof.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ struct sof {
110110
struct ext_library *ext_library;
111111
#endif
112112

113-
#if CONFIG_IPC_MAJOR_4
114-
/* lock for fw_reg access */
115-
struct k_spinlock fw_reg_lock;
116-
#endif
117-
118113
__aligned(PLATFORM_DCACHE_ALIGN) int alignment[0];
119114
} __aligned(PLATFORM_DCACHE_ALIGN);
120115

src/init/init.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,6 @@ __cold static int primary_core_init(int argc, char *argv[], struct sof *sof)
236236
size_t ipc4_abi_ver_offset = offsetof(struct ipc4_fw_registers, abi_ver);
237237

238238
mailbox_sw_reg_write(ipc4_abi_ver_offset, IPC4_FW_REGS_ABI_VER);
239-
240-
k_spinlock_init(&sof->fw_reg_lock);
241239
#endif
242240

243241
trace_point(TRACE_BOOT_PLATFORM);

src/ipc/ipc4/dai.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <sof/common.h>
1212
#include <rtos/idc.h>
1313
#include <rtos/alloc.h>
14+
#include <rtos/mutex.h>
1415
#include <sof/lib/dai.h>
1516
#include <sof/lib/memory.h>
1617
#include <sof/lib/notifier.h>
@@ -33,6 +34,9 @@
3334

3435
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
3536

37+
/* Protects IPC4 LLP reading-slot firmware registers used by DAI code. */
38+
static SYS_MUTEX_DEFINE(llp_reading_slots_lock);
39+
3640
void dai_set_link_hda_config(uint16_t *link_config,
3741
struct ipc_config_dai *common_config,
3842
const void *spec_config)
@@ -210,6 +214,8 @@ int ipc_comp_dai_config(struct ipc *ipc, struct ipc_config_dai *common_config,
210214

211215
void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
212216
{
217+
int ret;
218+
213219
/* cannot configure DAI while active */
214220
if (dev->state == COMP_STATE_ACTIVE) {
215221
comp_info(dev, "Component is in active state. Ignore resetting");
@@ -221,15 +227,15 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
221227
struct ipc4_llp_reading_slot slot;
222228

223229
if (dd->slot_info.node_id) {
224-
k_spinlock_key_t key;
225-
226230
/* reset llp position to 0 in memory window for reset state. */
227231
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
228232
slot.node_id = dd->slot_info.node_id;
229233

230-
key = k_spin_lock(&sof_get()->fw_reg_lock);
234+
ret = sys_mutex_lock(&llp_reading_slots_lock, K_FOREVER);
235+
assert(!ret);
231236
mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
232-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
237+
ret = sys_mutex_unlock(&llp_reading_slots_lock);
238+
assert(!ret);
233239
}
234240

235241
/* The stop sequnece of host driver is first pause and then reset
@@ -254,17 +260,19 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
254260
void dai_release_llp_slot(struct dai_data *dd)
255261
{
256262
struct ipc4_llp_reading_slot slot;
257-
k_spinlock_key_t key;
263+
int ret;
258264

259265
if (!dd->slot_info.node_id)
260266
return;
261267

262268
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
263269

264270
/* clear node id for released llp slot */
265-
key = k_spin_lock(&sof_get()->fw_reg_lock);
271+
ret = sys_mutex_lock(&llp_reading_slots_lock, K_FOREVER);
272+
assert(!ret);
266273
mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
267-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
274+
ret = sys_mutex_unlock(&llp_reading_slots_lock);
275+
assert(!ret);
268276

269277
dd->slot_info.reg_offset = 0;
270278
dd->slot_info.node_id = 0;
@@ -274,9 +282,9 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
274282
union ipc4_connector_node_id *node)
275283
{
276284
struct ipc4_llp_reading_slot slot;
277-
k_spinlock_key_t key;
278285
uint32_t max_slot;
279286
uint32_t offset;
287+
int ret;
280288
int i;
281289

282290
/* sdw with multiple gateways uses sndw_reading_slots */
@@ -288,7 +296,8 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
288296
max_slot = IPC4_MAX_LLP_GPDMA_READING_SLOTS;
289297
}
290298

291-
key = k_spin_lock(&sof_get()->fw_reg_lock);
299+
ret = sys_mutex_lock(&llp_reading_slots_lock, K_FOREVER);
300+
assert(!ret);
292301

293302
/* find unused llp slot offset with node_id of zero */
294303
for (i = 0; i < max_slot; i++, offset += sizeof(slot)) {
@@ -301,15 +310,17 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
301310

302311
if (i >= max_slot) {
303312
comp_err(dev, "can't find free slot");
304-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
313+
ret = sys_mutex_unlock(&llp_reading_slots_lock);
314+
assert(!ret);
305315
return -EINVAL;
306316
}
307317

308318
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
309319
slot.node_id = node->dw & IPC4_NODE_ID_MASK;
310320
mailbox_sw_regs_write(offset, &slot, sizeof(slot));
311321

312-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
322+
ret = sys_mutex_unlock(&llp_reading_slots_lock);
323+
assert(!ret);
313324

314325
return offset;
315326
}

zephyr/include/rtos/sof.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ struct sof {
111111
struct ext_library *ext_library;
112112
#endif
113113

114-
#if CONFIG_IPC_MAJOR_4
115-
/* lock for fw_reg access */
116-
struct k_spinlock fw_reg_lock;
117-
#endif
118-
119114
__aligned(PLATFORM_DCACHE_ALIGN) int alignment[0];
120115
} __aligned(PLATFORM_DCACHE_ALIGN);
121116

0 commit comments

Comments
 (0)