* Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "dvpp_vmng.h"
#include <linux/types.h>
#include "comm_kernel_interface.h"
#include "vmng_kernel_interface.h"
#include "dvpp_vcm_host.h"
#include "dvpp_cmdlist_log.h"
#include "dvpp_mem_allocater_comm.h"
#include "pbl_kernel_interface.h"
#define DVPP_CONTAINER_NOTIFIER "dvpp_container_notifier"
#define DVPP_VIRTUAL_NOTIFIER "dvpp_virtual_notifier"
static int32_t dvpp_vmng_init_instance(uint32_t udevid)
{
uint32_t dev_id = udevid;
uint32_t fid = 0;
int32_t ret;
DVPP_CMDLIST_LOG_INFO("dvpp vmnh vm online dev_id=%u, fid=%u", dev_id, fid);
ret = dvpp_vcm_vpc_register_client(dev_id, fid);
return ret;
}
static int32_t dvpp_vmng_uninit_instance(uint32_t udevid)
{
uint32_t dev_id = udevid;
uint32_t fid = 0;
DVPP_CMDLIST_LOG_INFO("dvpp vmnh vm offline dev_id=%u, fid=%u", dev_id, fid);
(void)dvpp_vcm_vpc_unregister_client(dev_id, fid);
return 0;
}
static int dvpp_virtual_notifier_func(uint32_t udevid, enum uda_notified_action action)
{
int ret = 0;
if (udevid >= DVPP_VMNG_DEVICE_NUM_MAX) {
DVPP_CMDLIST_LOG_ERROR("dvpp vmng check dev_id=%u is invalid\n", udevid);
return -EINVAL;
}
if (action == UDA_INIT) {
ret = dvpp_vmng_init_instance(udevid);
} else if (action == UDA_UNINIT) {
dvpp_vmng_uninit_instance(udevid);
}
DVPP_CMDLIST_LOG_INFO("notifier action. (udevid=%u; action=%d; ret=%d)\n", udevid, action, ret);
return ret;
}
static int32_t dvpp_vmng_init_container_instance(uint32_t dev_id, struct device *dev)
{
UNUSED(dev);
dvpp_create_mem_pools_by_id(dev_id);
return 0;
}
static int32_t dvpp_vmng_uninit_container_instance(uint32_t dev_id)
{
dvpp_destroy_mem_pools_by_id(dev_id);
return 0;
}
static int dvpp_container_notifier_func(uint32_t udevid, enum uda_notified_action action)
{
int ret = 0;
if (udevid >= DVPP_VMNG_DEVICE_NUM_MAX) {
DVPP_CMDLIST_LOG_ERROR("dvpp vmng check dev_id=%u is invalid\n", udevid);
return -EINVAL;
}
if (uda_is_phy_dev(udevid)) {
return 0;
}
if (action == UDA_INIT) {
ret = dvpp_vmng_init_container_instance(udevid, uda_get_device(udevid));
} else if (action == UDA_UNINIT) {
ret = dvpp_vmng_uninit_container_instance(udevid);
}
DVPP_CMDLIST_LOG_INFO("notifier action. (udevid=%u; action=%d; ret=%d)\n", udevid, action, ret);
return ret;
}
int32_t dvpp_vmng_init(void)
{
int32_t ret;
struct uda_dev_type type;
uda_davinci_near_real_entity_type_pack(&type);
ret = uda_notifier_register(DVPP_CONTAINER_NOTIFIER, &type, UDA_PRI1, dvpp_container_notifier_func);
if (ret != 0) {
DVPP_CMDLIST_LOG_ERROR("dvpp register %s failed, ret=%d\n", DVPP_CONTAINER_NOTIFIER, ret);
return ret;
}
uda_dev_type_pack(&type, UDA_DAVINCI, UDA_ENTITY, UDA_NEAR, UDA_REAL_SEC_EH);
ret = uda_notifier_register(DVPP_VIRTUAL_NOTIFIER, &type, UDA_PRI1, dvpp_virtual_notifier_func);
if (ret != 0) {
DVPP_CMDLIST_LOG_ERROR("dvpp register %s failed, ret=%d\n", DVPP_VIRTUAL_NOTIFIER, ret);
uda_davinci_near_real_entity_type_pack(&type);
(void)uda_notifier_unregister(DVPP_CONTAINER_NOTIFIER, &type);
return ret;
}
return 0;
}
int32_t dvpp_vmng_uninit(void)
{
struct uda_dev_type type;
uda_davinci_near_real_entity_type_pack(&type);
(void)uda_notifier_unregister(DVPP_CONTAINER_NOTIFIER, &type);
uda_dev_type_pack(&type, UDA_DAVINCI, UDA_ENTITY, UDA_NEAR, UDA_REAL_SEC_EH);
(void)uda_notifier_unregister(DVPP_VIRTUAL_NOTIFIER, &type);
return 0;
}