kernel-brax3-ubuntu-touch/drivers/misc/mediatek/apusys/edma/edma_rv.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

212 lines
4.3 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/interrupt.h>
#include <linux/syscalls.h>
#include <linux/cdev.h>
#include <linux/kthread.h>
#include <linux/timer.h>
#include <linux/rpmsg.h>
#include "edma_dbgfs.h"
#include "edma_driver.h"
#include "edma_cmd_hnd.h"
#include "apusys_power.h"
#include "apusys_core.h"
#include "edma_plat_internal.h"
u8 g_edmaRV_log_lv = EDMA_LOG_DEBUG;
#define LOG_RV_DBG(x, args...) \
{ \
if (g_edmaRV_log_lv >= EDMA_LOG_DEBUG) \
pr_info(EDMA_TAG "[debug] %s/%d "\
x, __func__, __LINE__, ##args); \
}
#define LOG_INF(format, args...) pr_info(EDMA_TAG " " format, ##args)
#define LOG_WRN(format, args...) pr_info(EDMA_TAG "[warn] " format, ##args)
#define LOG_ERR(format, args...) pr_info(EDMA_TAG "[error] " format, ##args)
/* ipi type */
enum EDMA_IPI_TYPE {
EDMA_IPI_NONE,
EDMA_IPI_SET_LOG_LV,
};
/*
* type: command type
* data : command data
*/
struct edma_ipi_data {
uint32_t type;
uint32_t data;
};
struct edma_rv_dev {
struct rpmsg_device *rpdev;
struct rpmsg_endpoint *ept;
struct completion ack;
struct kobject *edmaRV_root;
};
static struct edma_rv_dev eRdev;
static struct mutex edma_ipi_mtx;
static int edma_rpmsg_cb(struct rpmsg_device *rpdev, void *data,
int len, void *priv, u32 src)
{
int ret = 0;
LOG_INF("%s len=%d, priv=%p, src=%d\n", __func__, len, priv, src);
complete(&eRdev.ack);
//ret = reviser_remote_rx_cb(data, len);
return ret;
}
static int edma_rpmsg_probe(struct rpmsg_device *rpdev)
{
int ret = 0;
struct rpmsg_channel_info chinfo = {};
LOG_INF("%s +\n", __func__);
eRdev.rpdev = rpdev;
strscpy(chinfo.name, eRdev.rpdev->id.name, RPMSG_NAME_SIZE);
chinfo.src = eRdev.rpdev->src;
chinfo.dst = RPMSG_ADDR_ANY;
eRdev.ept = rpmsg_create_ept(eRdev.rpdev,
edma_rpmsg_cb, &eRdev, chinfo);
LOG_INF("Done, eRdev.ept = %p\n", eRdev.ept);
return ret;
}
static void edma_rpmsg_remove(struct rpmsg_device *rpdev)
{
LOG_DBG("%s +\n", __func__);
}
static const struct of_device_id edma_rpmsg_of_match[] = {
{ .compatible = "mediatek,apu-edma-rpmsg", },
{ },
};
static struct rpmsg_driver edma_rpmsg_driver = {
.drv = {
.name = "apu-edma-rpmsg",
.of_match_table = edma_rpmsg_of_match,
},
.probe = edma_rpmsg_probe,
.remove = edma_rpmsg_remove,
.callback = edma_rpmsg_cb,
};
static ssize_t edma_rvlog_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
ssize_t count = 0;
count += scnprintf(buf + count, PAGE_SIZE - count,
"g_edmaRV_log_lv = %d\n", g_edmaRV_log_lv);
return count;
}
static ssize_t edma_rvlog_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned int val = 0;
int ret;
struct edma_ipi_data mData;
if (!eRdev.ept) {
LOG_ERR("%s: eRdev.ept == NULL\n", __func__);
return count;
}
mutex_lock(&edma_ipi_mtx);
ret = kstrtouint(buf, 10, &val);
LOG_RV_DBG("set debug lv = %d\n", val);
g_edmaRV_log_lv = val;
mData.type = EDMA_IPI_SET_LOG_LV;
mData.data = g_edmaRV_log_lv;
ret = rpmsg_send(eRdev.ept, &mData, sizeof(mData));
if (ret) {
LOG_ERR("send msg fail\n");
goto exit;
}
ret = wait_for_completion_timeout(&eRdev.ack, msecs_to_jiffies(100));
if (ret == 0)
LOG_WRN("%s: wait for completion timeout\n", __func__);
exit:
mutex_unlock(&edma_ipi_mtx);
return count;
}
static const struct kobj_attribute edma_log_lv_attr =
__ATTR(edma_rv_log_lv, 0660, edma_rvlog_show,
edma_rvlog_store);
int edma_rv_setup(struct apusys_core_info *info)
{
int ret = 0;
pr_info("%s +\n", __func__);
memset(&eRdev, 0, sizeof(eRdev));
init_completion(&eRdev.ack);
mutex_init(&edma_ipi_mtx);
eRdev.edmaRV_root = kobject_create_and_add("edma_rv", kernel_kobj);
if (!eRdev.edmaRV_root)
return -ENOMEM;
ret = sysfs_create_file(eRdev.edmaRV_root, &edma_log_lv_attr.attr);
if (ret)
LOG_ERR("%s create edma_log_lv_attr attribute fail, ret %d\n", __func__, ret);
if (register_rpmsg_driver(&edma_rpmsg_driver)) {
LOG_ERR("failed to register RMPSG driver");
return -ENODEV;
}
return ret;
}
void edma_rv_shutdown(void)
{
unregister_rpmsg_driver(&edma_rpmsg_driver);
kobject_del(eRdev.edmaRV_root);
}