1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2024-11-19 13:27:49 +00:00
a155-U-u1/kernel-5.10/drivers/misc/mediatek/lpm/lpm_call.c
2024-03-11 06:53:12 +11:00

109 lines
1.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <lpm_call.h>
static DEFINE_SPINLOCK(lpm_plat_call_locker);
static LIST_HEAD(lpm_callees);
int lpm_callee_registry(struct lpm_callee *callee)
{
struct lpm_callee *pos;
if (!callee)
return -EINVAL;
spin_lock(&lpm_plat_call_locker);
list_for_each_entry(pos, &lpm_callees, list) {
if (pos && (pos != callee) &&
(pos->uid == callee->uid)) {
pos = NULL;
break;
}
}
if (pos) {
callee->ref = 0;
list_add(&callee->list, &lpm_callees);
}
spin_unlock(&lpm_plat_call_locker);
return 0;
}
EXPORT_SYMBOL(lpm_callee_registry);
int lpm_callee_unregistry(struct lpm_callee *callee)
{
int bRet = 0;
struct lpm_callee *pos;
if (!callee)
return -EINVAL;
spin_lock(&lpm_plat_call_locker);
list_for_each_entry(pos, &lpm_callees, list) {
if (pos && (pos->uid == callee->uid)) {
if (!pos->ref)
list_del(&pos->list);
else
bRet = -EPERM;
break;
}
}
spin_unlock(&lpm_plat_call_locker);
return bRet;
}
EXPORT_SYMBOL(lpm_callee_unregistry);
int lpm_callee_get_impl(int uid, const struct lpm_callee **callee)
{
struct lpm_callee *pos;
if (!callee)
return -EINVAL;
*callee = NULL;
spin_lock(&lpm_plat_call_locker);
list_for_each_entry(pos, &lpm_callees, list) {
if (pos && pos->uid == uid) {
pos->ref++;
*callee = pos;
break;
}
}
spin_unlock(&lpm_plat_call_locker);
return *callee ? 0 : -EINVAL;
}
EXPORT_SYMBOL(lpm_callee_get_impl);
int lpm_callee_put_impl(struct lpm_callee const *callee)
{
struct lpm_callee *pos;
int ret = -EPERM;
if (!callee)
return -EINVAL;
spin_lock(&lpm_plat_call_locker);
list_for_each_entry(pos, &lpm_callees, list) {
if (pos && (pos->uid == callee->uid)) {
pos->ref--;
ret = 0;
break;
}
}
spin_unlock(&lpm_plat_call_locker);
return ret;
}
EXPORT_SYMBOL(lpm_callee_put_impl);