1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2025-07-14 08:44:45 +00:00
Files
a155-U-u1/kernel-5.10/drivers/misc/mediatek/adsp/adsp_semaphore.c
physwizz 99537be4e2 first
2024-03-11 06:53:12 +11:00

102 lines
2.1 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/io.h>
#include "adsp_core.h"
#include "adsp_platform.h"
#include "adsp_semaphore.h"
struct adsp_sem_info {
unsigned int way_bits;
unsigned int ctrl_bit;
unsigned int timeout;
spinlock_t lock;
};
struct adsp_sem_info sem_info;
int adsp_semaphore_init(unsigned int way_bits,
unsigned int ctrl_bit,
unsigned int timeout)
{
if (ctrl_bit >= way_bits)
return ADSP_ERROR;
sem_info.way_bits = way_bits;
sem_info.ctrl_bit = ctrl_bit;
if (!timeout)
timeout = 1;
sem_info.timeout = timeout;
spin_lock_init(&sem_info.lock);
return ADSP_OK;
}
/*
* acquire a hardware semaphore
* @param flag: semaphore id
* return ADSP_OK: get sema success
* ADSP_ERROR: get sema fail
*/
int get_adsp_semaphore(unsigned int sem_id)
{
enum adsp_status ret = ADSP_OK;
unsigned long spin_flags;
u32 sem_bit = sem_id * sem_info.way_bits + sem_info.ctrl_bit;
int retry = sem_info.timeout;
/* return ADSP_ERROR to prevent from access when adsp not ready.
* Both adsp enter suspend/resume at the same time.
*/
if (!is_adsp_system_running()) {
pr_notice("%s: adsp not enabled.", __func__);
return ADSP_ERROR;
}
spin_lock_irqsave(&sem_info.lock, spin_flags);
while (!adsp_mt_get_semaphore(sem_bit)) {
adsp_mt_toggle_semaphore(sem_bit);
if (retry-- <= 0) {
ret = ADSP_SEMAPHORE_BUSY;
break;
}
}
spin_unlock_irqrestore(&sem_info.lock, spin_flags);
return ret;
}
EXPORT_SYMBOL_GPL(get_adsp_semaphore);
/*
* release a hardware semaphore
* @param flag: semaphore id
* return ADSP_OK: release sema success
* ADSP_ERROR: release sema fail
*/
int release_adsp_semaphore(unsigned int sem_id)
{
enum adsp_status ret = ADSP_OK;
unsigned long spin_flags;
u32 sem_bit = sem_id * sem_info.way_bits + sem_info.ctrl_bit;
if (!is_adsp_system_running()) {
pr_notice("%s: adsp not enabled.", __func__);
return ADSP_ERROR;
}
spin_lock_irqsave(&sem_info.lock, spin_flags);
if (adsp_mt_get_semaphore(sem_bit))
adsp_mt_toggle_semaphore(sem_bit);
spin_unlock_irqrestore(&sem_info.lock, spin_flags);
return ret;
}
EXPORT_SYMBOL_GPL(release_adsp_semaphore);