mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2024-11-19 13:27:49 +00:00
109 lines
1.9 KiB
C
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);
|
|
|