Skip to content

Commit 47deec9

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 47deec9

4 files changed

Lines changed: 10 additions & 23 deletions

File tree

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: 10 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,8 @@
3334

3435
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
3536

37+
static SYS_MUTEX_DEFINE(fw_reg_lock);
38+
3639
void dai_set_link_hda_config(uint16_t *link_config,
3740
struct ipc_config_dai *common_config,
3841
const void *spec_config)
@@ -221,15 +224,13 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
221224
struct ipc4_llp_reading_slot slot;
222225

223226
if (dd->slot_info.node_id) {
224-
k_spinlock_key_t key;
225-
226227
/* reset llp position to 0 in memory window for reset state. */
227228
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
228229
slot.node_id = dd->slot_info.node_id;
229230

230-
key = k_spin_lock(&sof_get()->fw_reg_lock);
231+
sys_mutex_lock(&fw_reg_lock, K_FOREVER);
231232
mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
232-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
233+
sys_mutex_unlock(&fw_reg_lock);
233234
}
234235

235236
/* The stop sequnece of host driver is first pause and then reset
@@ -254,17 +255,16 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
254255
void dai_release_llp_slot(struct dai_data *dd)
255256
{
256257
struct ipc4_llp_reading_slot slot;
257-
k_spinlock_key_t key;
258258

259259
if (!dd->slot_info.node_id)
260260
return;
261261

262262
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
263263

264264
/* clear node id for released llp slot */
265-
key = k_spin_lock(&sof_get()->fw_reg_lock);
265+
sys_mutex_lock(&fw_reg_lock, K_FOREVER);
266266
mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
267-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
267+
sys_mutex_unlock(&fw_reg_lock);
268268

269269
dd->slot_info.reg_offset = 0;
270270
dd->slot_info.node_id = 0;
@@ -274,7 +274,6 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
274274
union ipc4_connector_node_id *node)
275275
{
276276
struct ipc4_llp_reading_slot slot;
277-
k_spinlock_key_t key;
278277
uint32_t max_slot;
279278
uint32_t offset;
280279
int i;
@@ -288,7 +287,7 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
288287
max_slot = IPC4_MAX_LLP_GPDMA_READING_SLOTS;
289288
}
290289

291-
key = k_spin_lock(&sof_get()->fw_reg_lock);
290+
sys_mutex_lock(&fw_reg_lock, K_FOREVER);
292291

293292
/* find unused llp slot offset with node_id of zero */
294293
for (i = 0; i < max_slot; i++, offset += sizeof(slot)) {
@@ -301,15 +300,15 @@ static int dai_get_unused_llp_slot(struct comp_dev *dev,
301300

302301
if (i >= max_slot) {
303302
comp_err(dev, "can't find free slot");
304-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
303+
sys_mutex_unlock(&fw_reg_lock);
305304
return -EINVAL;
306305
}
307306

308307
memset_s(&slot, sizeof(slot), 0, sizeof(slot));
309308
slot.node_id = node->dw & IPC4_NODE_ID_MASK;
310309
mailbox_sw_regs_write(offset, &slot, sizeof(slot));
311310

312-
k_spin_unlock(&sof_get()->fw_reg_lock, key);
311+
sys_mutex_unlock(&fw_reg_lock);
313312

314313
return offset;
315314
}

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)