kernel-brax3-ubuntu-touch/drivers/misc/mediatek/apusys/midware/2.0/mdw_dev.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

153 lines
3.2 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#include <linux/slab.h>
#include "mdw_cmn.h"
static void mdw_dev_clear_cmd_func(struct work_struct *wk)
{
struct mdw_device *mdev =
container_of(wk, struct mdw_device, c_wk);
struct mdw_cmd *c = NULL, *tmp = NULL;
struct mdw_fpriv *mpriv = NULL;
mutex_lock(&mdev->c_mtx);
list_for_each_entry_safe(c, tmp, &mdev->d_cmds, d_node) {
list_del(&c->d_node);
mpriv = c->mpriv;
mdw_cmd_delete(c);
}
mutex_unlock(&mdev->c_mtx);
}
int mdw_dev_init(struct mdw_device *mdev)
{
int ret = -ENODEV;
mdw_drv_info("mdw dev init type(%d-%u)\n",
mdev->driver_type, mdev->mdw_ver);
INIT_LIST_HEAD(&mdev->d_cmds);
mutex_init(&mdev->c_mtx);
INIT_WORK(&mdev->c_wk, &mdw_dev_clear_cmd_func);
mdev->base_fence_ctx = dma_fence_context_alloc(MDW_FENCE_MAX_RINGS);
mdev->num_fence_ctx = MDW_FENCE_MAX_RINGS;
mutex_init(&mdev->f_mtx);
switch (mdev->driver_type) {
case MDW_DRIVER_TYPE_PLATFORM:
mdw_drv_err("not support platform probe\n");
break;
case MDW_DRIVER_TYPE_RPMSG:
mdw_rv_set_func(mdev);
break;
default:
ret = -EINVAL;
break;
}
if (mdev->dev_funcs)
ret = mdev->dev_funcs->late_init(mdev);
return ret;
}
void mdw_dev_deinit(struct mdw_device *mdev)
{
if (mdev->dev_funcs) {
mdev->dev_funcs->late_deinit(mdev);
mdev->dev_funcs = NULL;
}
}
void mdw_dev_session_create(struct mdw_fpriv *mpriv)
{
struct mdw_device *mdev = mpriv->mdev;
uint32_t i = 0;
for (i = 0; i < MDW_DEV_MAX; i++) {
if (mdev->adevs[i])
mdev->adevs[i]->send_cmd(APUSYS_CMD_SESSION_CREATE, mpriv, mdev->adevs[i]);
}
}
void mdw_dev_session_delete(struct mdw_fpriv *mpriv)
{
struct mdw_device *mdev = mpriv->mdev;
uint32_t i = 0;
for (i = 0; i < MDW_DEV_MAX; i++) {
if (mdev->adevs[i])
mdev->adevs[i]->send_cmd(APUSYS_CMD_SESSION_DELETE, mpriv, mdev->adevs[i]);
}
}
int mdw_dev_validation(struct mdw_fpriv *mpriv, uint32_t dtype,
struct mdw_cmd *cmd, struct apusys_cmdbuf *cbs, uint32_t num)
{
struct apusys_device *adev = NULL;
struct apusys_cmd_valid_handle v_hnd;
int ret = 0;
if (dtype >= MDW_DEV_MAX)
return -ENODEV;
memset(&v_hnd, 0, sizeof(v_hnd));
v_hnd.cmdbufs = cbs;
v_hnd.num_cmdbufs = num;
v_hnd.session = mpriv;
v_hnd.cmd = cmd;
adev = mpriv->mdev->adevs[dtype];
if (adev) {
mutex_lock(&mpriv->mdev->mctl_mtx);
ret = adev->send_cmd(APUSYS_CMD_VALIDATE, &v_hnd, adev);
mutex_unlock(&mpriv->mdev->mctl_mtx);
}
return ret;
}
int apusys_register_device(struct apusys_device *adev)
{
uint32_t type = 0;
if (!mdw_dev) {
pr_info("[apusys] apu mdw not ready\n");
return -ENODEV;
}
if (!mdw_dev->dev_funcs) {
pr_info("[apusys] apu mdw not inited\n");
return -ENODEV;
}
type = adev->dev_type;
if (type >= MDW_DEV_MAX) {
pr_info("[apusys] invalid dev(%u)\n", type);
return -EINVAL;
}
if (!mdw_dev->adevs[type])
mdw_dev->adevs[type] = adev;
return mdw_dev->dev_funcs->register_device(adev);
}
int apusys_unregister_device(struct apusys_device *adev)
{
if (!mdw_dev) {
pr_info("[apusys] apu mdw not ready\n");
return -ENODEV;
}
if (!mdw_dev->dev_funcs) {
pr_info("[apusys] apu mdw not inited\n");
return -ENODEV;
}
return mdw_dev->dev_funcs->unregister_device(adev);
}