199 lines
3.9 KiB
C
199 lines
3.9 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 "apusys_power.h"
|
|
#include "apusys_core.h"
|
|
|
|
enum {
|
|
MNOC_LOG_WARN,
|
|
MNOC_LOG_INFO,
|
|
MNOC_LOG_DEBUG,
|
|
};
|
|
|
|
u8 g_mnocRV_log_lv = MNOC_LOG_DEBUG;
|
|
|
|
#define MNOC_TAG "[mnoc]"
|
|
|
|
#define LOG_RV_DBG(x, args...) \
|
|
{ \
|
|
if (g_mnocRV_log_lv >= MNOC_LOG_DEBUG) \
|
|
pr_info(MNOC_TAG "[debug] %s/%d "\
|
|
x, __func__, __LINE__, ##args); \
|
|
}
|
|
|
|
#define LOG_INF(format, args...) pr_info(MNOC_TAG " " format, ##args)
|
|
#define LOG_WRN(format, args...) pr_info(MNOC_TAG "[warn] " format, ##args)
|
|
#define LOG_ERR(format, args...) pr_info(MNOC_TAG "[error] " format, ##args)
|
|
|
|
/* ipi type */
|
|
enum MNOC_IPI_TYPE {
|
|
MNOC_IPI_NONE,
|
|
MNOC_IPI_SET_LOG_LV,
|
|
MNOC_IPI_UPDATE_TIMER,
|
|
};
|
|
|
|
/*
|
|
* type: command type
|
|
* data : command data
|
|
*/
|
|
struct mnoc_ipi_data {
|
|
uint32_t type;
|
|
uint32_t data;
|
|
};
|
|
|
|
struct mnoc_rv_dev {
|
|
struct rpmsg_device *rpdev;
|
|
struct rpmsg_endpoint *ept;
|
|
struct kobject *mnocRV_root;
|
|
|
|
};
|
|
|
|
static struct mnoc_rv_dev eRdev;
|
|
|
|
|
|
static int mnoc_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);
|
|
//ret = reviser_remote_rx_cb(data, len);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int mnoc_rpmsg_probe(struct rpmsg_device *rpdev)
|
|
{
|
|
int ret = 0;
|
|
struct rpmsg_channel_info chinfo = {};
|
|
|
|
LOG_RV_DBG("%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,
|
|
mnoc_rpmsg_cb, &eRdev, chinfo);
|
|
|
|
|
|
LOG_INF("Done, eRdev.ept = 0x%x\n", eRdev.ept);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void mnoc_rpmsg_remove(struct rpmsg_device *rpdev)
|
|
{
|
|
LOG_RV_DBG("%s +\n", __func__);
|
|
}
|
|
|
|
static const struct of_device_id mnoc_rpmsg_of_match[] = {
|
|
{ .compatible = "mediatek,apu-mnoc-rpmsg", },
|
|
{ },
|
|
};
|
|
|
|
static struct rpmsg_driver mnoc_rpmsg_driver = {
|
|
.drv = {
|
|
.name = "apu-mnoc-rpmsg",
|
|
.of_match_table = mnoc_rpmsg_of_match,
|
|
},
|
|
.probe = mnoc_rpmsg_probe,
|
|
.remove = mnoc_rpmsg_remove,
|
|
.callback = mnoc_rpmsg_cb,
|
|
};
|
|
|
|
|
|
static ssize_t mnoc_rvlog_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
char *buf)
|
|
{
|
|
ssize_t count = 0;
|
|
|
|
count += scnprintf(buf + count, PAGE_SIZE - count,
|
|
"g_mnocRV_log_lv = %d\n", g_mnocRV_log_lv);
|
|
|
|
return count;
|
|
}
|
|
|
|
static ssize_t mnoc_rvlog_store(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
unsigned int val = 0;
|
|
int ret;
|
|
struct mnoc_ipi_data mData;
|
|
|
|
ret = kstrtouint(buf, 10, &val);
|
|
|
|
LOG_RV_DBG("set debug lv = %d\n", val);
|
|
|
|
g_mnocRV_log_lv = val;
|
|
|
|
mData.type = MNOC_IPI_SET_LOG_LV;
|
|
mData.data = g_mnocRV_log_lv;
|
|
|
|
ret = rpmsg_send(eRdev.ept, &mData, sizeof(mData));
|
|
if (ret)
|
|
LOG_ERR("send msg fail\n");
|
|
|
|
|
|
return count;
|
|
|
|
|
|
}
|
|
static const struct kobj_attribute mnoc_log_lv_attr =
|
|
__ATTR(mnoc_rv_log_lv, 0660, mnoc_rvlog_show,
|
|
mnoc_rvlog_store);
|
|
|
|
|
|
int mnoc_rv_setup(struct apusys_core_info *info)
|
|
{
|
|
int ret = 0;
|
|
|
|
LOG_RV_DBG("%s +\n", __func__);
|
|
|
|
memset(&eRdev, 0, sizeof(eRdev));
|
|
|
|
eRdev.mnocRV_root = kobject_create_and_add("mnoc_rv", kernel_kobj);
|
|
|
|
if (!eRdev.mnocRV_root)
|
|
return -ENOMEM;
|
|
|
|
ret = sysfs_create_file(eRdev.mnocRV_root, &mnoc_log_lv_attr.attr);
|
|
if (ret)
|
|
LOG_ERR("%s create mnoc_log_lv_attr attribute fail, ret %d\n", __func__, ret);
|
|
|
|
|
|
|
|
if (register_rpmsg_driver(&mnoc_rpmsg_driver)) {
|
|
LOG_ERR("failed to register RMPSG driver");
|
|
return -ENODEV;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void mnoc_rv_clear(void)
|
|
{
|
|
unregister_rpmsg_driver(&mnoc_rpmsg_driver);
|
|
kobject_del(eRdev.mnocRV_root);
|
|
}
|