Files
linux-nv-oot/drivers/platform/tegra/nvadsp/adsp_console_dbfs.c
Viswanath L 119c4f87e2 nvadsp: Update license and remove kernel ver check
- Update license of all files in nvadsp that will be used
 - Remove kernel version checks in the code

Bug 4164138
Bug 3682950

Change-Id: Ie1f9ba95c1d46c3dd9bc5614e502b1b444484df6
Signed-off-by: Viswanath L <viswanathl@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2980528
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-09-26 12:09:52 -07:00

433 lines
10 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/**
* Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/tegra_nvadsp.h>
#include <linux/platform_device.h>
#include <uapi/misc/adsp_console_ioctl.h>
#include <linux/uaccess.h>
#include "dev.h"
#include "adsp_console_dbfs.h"
#define USE_RUN_APP_API
static int open_cnt;
#define ADSP_APP_CTX_MAX 32
static uint64_t adsp_app_ctx_vals[ADSP_APP_CTX_MAX];
#define ACCESS_OK(addr, size) access_ok(addr, size)
static int adsp_app_ctx_add(uint64_t ctx)
{
int i;
if (ctx == 0)
return -EINVAL;
for (i = 0; i < ADSP_APP_CTX_MAX; i++) {
if (adsp_app_ctx_vals[i] == 0) {
adsp_app_ctx_vals[i] = ctx;
return 0;
}
}
return -EINVAL;
}
static int adsp_app_ctx_check(uint64_t ctx)
{
int i;
if (ctx == 0)
return -EINVAL;
for (i = 0; i < ADSP_APP_CTX_MAX; i++) {
if (adsp_app_ctx_vals[i] == ctx)
return 0;
}
return -EINVAL;
}
static void adsp_app_ctx_remove(uint64_t ctx)
{
int i;
for (i = 0; i < ADSP_APP_CTX_MAX; i++) {
if (adsp_app_ctx_vals[i] == ctx) {
adsp_app_ctx_vals[i] = 0;
return;
}
}
}
static int adsp_consol_open(struct inode *i, struct file *f)
{
int ret;
uint16_t snd_mbox_id = 30;
struct nvadsp_cnsl *console = i->i_private;
struct device *dev = console->dev;
struct platform_device *pdev = to_platform_device(dev);
struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev);
if (open_cnt)
return -EBUSY;
open_cnt++;
ret = 0;
f->private_data = console;
if (!drv_data->adsp_os_running)
goto exit_open;
ret = nvadsp_mbox_open(&console->shl_snd_mbox, &snd_mbox_id,
"adsp_send_cnsl", NULL, NULL);
if (!ret)
goto exit_open;
pr_err("adsp_consol: Failed to init adsp_consol send mailbox");
memset(&console->shl_snd_mbox, 0, sizeof(struct nvadsp_mbox));
open_cnt--;
exit_open:
return ret;
}
static int adsp_consol_close(struct inode *i, struct file *f)
{
int ret = 0;
struct nvadsp_cnsl *console = i->i_private;
struct nvadsp_mbox *mbox = &console->shl_snd_mbox;
struct device *dev = console->dev;
struct platform_device *pdev = to_platform_device(dev);
struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev);
open_cnt--;
if (!drv_data->adsp_os_running || (0 == mbox->id))
goto exit_close;
ret = nvadsp_mbox_close(mbox);
if (ret)
pr_err("adsp_consol: Failed to close adsp_consol send mailbox)");
memset(mbox, 0, sizeof(struct nvadsp_mbox));
exit_close:
return ret;
}
static long
adsp_consol_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
int ret = 0;
uint16_t *mid;
uint16_t mbxid = 0;
uint32_t data;
uint64_t ctx2;
nvadsp_app_info_t *app_info;
struct adsp_consol_run_app_arg_t app_args;
struct nvadsp_cnsl *console = f->private_data;
struct nvadsp_mbox *mbox;
struct device *dev = console->dev;
struct platform_device *pdev = to_platform_device(dev);
struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev);
void __user *uarg = (void __user *)arg;
if (_IOC_TYPE(cmd) != NV_ADSP_CONSOLE_MAGIC)
return -EFAULT;
if ((_IOC_NR(cmd) != _IOC_NR(ADSP_CNSL_LOAD)) &&
(_IOC_NR(cmd) != _IOC_NR(ADSP_CNSL_RESUME)) &&
(!drv_data->adsp_os_running)) {
dev_info(dev, "adsp_consol: os not running.");
return -EPERM;
}
if ((_IOC_NR(cmd) != _IOC_NR(ADSP_CNSL_LOAD)) &&
(0 == console->shl_snd_mbox.id)) {
dev_info(dev, "adsp_consol: Mailboxes not open.");
return -EPERM;
}
switch (_IOC_NR(cmd)) {
case _IOC_NR(ADSP_CNSL_LOAD):
ret = 0;
if (drv_data->adsp_os_running)
break;
mbxid = 30;
mbox = &console->shl_snd_mbox;
ret = nvadsp_os_load();
if (ret) {
dev_info(dev, "adsp_consol: Load OS Failed.");
break;
}
ret = nvadsp_os_start();
if (ret) {
dev_info(dev, "adsp_consol: Start OS Failed.");
break;
}
ret = nvadsp_mbox_open(mbox, &mbxid,
"adsp_send_cnsl", NULL, NULL);
if (!ret)
break;
pr_err("adsp_consol: Failed to init adsp_consol send mailbox");
memset(mbox, 0, sizeof(struct nvadsp_mbox));
break;
case _IOC_NR(ADSP_CNSL_SUSPEND):
ret = nvadsp_os_suspend();
if (ret)
dev_info(dev, "adsp_consol: OS Suspend Failed.");
break;
case _IOC_NR(ADSP_CNSL_STOP):
nvadsp_os_stop();
break;
case _IOC_NR(ADSP_CNSL_RESUME):
if (!drv_data->adsp_os_suspended) {
dev_info(dev, "adsp_consol: OS is not suspended to perform resume.");
break;
}
ret = nvadsp_os_start();
if (ret)
dev_info(dev, "adsp_consol: OS Resume Failed.");
break;
case _IOC_NR(ADSP_CNSL_RUN_APP):
if (!ACCESS_OK(uarg, sizeof(struct adsp_consol_run_app_arg_t)))
return -EACCES;
ret = copy_from_user(&app_args, uarg,
sizeof(app_args));
if (ret) {
ret = -EACCES;
break;
}
dev_info(dev, "Core ID: %d\n", app_args.core_id);
app_args.app_name[NVADSP_NAME_SZ_MAX] = '\0';
#ifdef USE_RUN_APP_API
app_args.ctx2 = (uint64_t)nvadsp_run_app(NULL,
app_args.app_name,
(nvadsp_app_args_t *)&app_args.args[0],
NULL, 0, app_args.core_id, true);
if (!app_args.ctx2) {
dev_info(dev, "adsp_consol: unable to run %s\n",
app_args.app_name);
return -EINVAL;
}
if (adsp_app_ctx_add(app_args.ctx2)) {
dev_info(dev, "adsp_consol: unable to add %s ctx\n",
app_args.app_name);
return -EINVAL;
}
#else
app_args.ctx1 = (uint64_t)nvadsp_app_load(app_args.app_path,
app_args.app_name);
if (!app_args.ctx1) {
dev_info(dev,
"adsp_consol: dynamic app load failed %s\n",
app_args.app_name);
return -EINVAL;
}
if (adsp_app_ctx_add(app_args.ctx1)) {
dev_info(dev, "adsp_consol: unable to add %s ctx\n",
app_args.app_name);
return -EINVAL;
}
dev_info(dev, "adsp_consol: calling nvadsp_app_init\n");
app_args.ctx2 =
(uint64_t)nvadsp_app_init((void *)app_args.ctx1, NULL);
if (!app_args.ctx2) {
dev_info(dev,
"adsp_consol: unable to initilize the app\n");
return -EINVAL;
}
if (adsp_app_ctx_add(app_args.ctx2)) {
dev_info(dev, "adsp_consol: unable to add %s ctx\n",
app_args.app_name);
return -EINVAL;
}
dev_info(dev, "adsp_consol: calling nvadsp_app_start\n");
ret = nvadsp_app_start((void *)app_args.ctx2);
if (ret) {
dev_info(dev, "adsp_consol: unable to start the app\n");
break;
}
#endif
ret = copy_to_user((void __user *) arg, &app_args,
sizeof(struct adsp_consol_run_app_arg_t));
if (ret)
ret = -EACCES;
break;
case _IOC_NR(ADSP_CNSL_STOP_APP):
if (!ACCESS_OK(uarg, sizeof(struct adsp_consol_run_app_arg_t)))
return -EACCES;
ret = copy_from_user(&app_args, uarg,
sizeof(app_args));
if (ret) {
ret = -EACCES;
break;
}
#ifdef USE_RUN_APP_API
if (!app_args.ctx2) {
ret = -EACCES;
break;
}
if (adsp_app_ctx_check(app_args.ctx2)) {
dev_info(dev, "adsp_consol: unable to check %s ctx\n",
app_args.app_name);
return -EINVAL;
}
app_args.ctx1 = (uint64_t)
((nvadsp_app_info_t *)app_args.ctx2)->handle;
nvadsp_exit_app((nvadsp_app_info_t *)app_args.ctx2, false);
nvadsp_app_unload((const void *)app_args.ctx1);
adsp_app_ctx_remove(app_args.ctx2);
#else
if ((!app_args.ctx2) || (!app_args.ctx1)) {
ret = -EACCES;
break;
}
if (adsp_app_ctx_check(app_args.ctx2) ||
adsp_app_ctx_check(app_args.ctx1)) {
dev_info(dev, "adsp_consol: unable to check %s ctx\n",
app_args.app_name);
return -EINVAL;
}
nvadsp_app_deinit((void *)app_args.ctx2);
nvadsp_app_unload((void *)app_args.ctx1);
adsp_app_ctx_remove(app_args.ctx2);
adsp_app_ctx_remove(app_args.ctx1);
#endif
break;
case _IOC_NR(ADSP_CNSL_CLR_BUFFER):
break;
case _IOC_NR(ADSP_CNSL_OPN_MBX):
if (!ACCESS_OK(uarg, sizeof(ctx2)))
return -EACCES;
ret = copy_from_user(&ctx2, uarg, sizeof(ctx2));
if (ret) {
ret = -EACCES;
break;
}
if (adsp_app_ctx_check(ctx2)) {
dev_info(dev, "adsp_consol: unable to check ctx\n");
return -EINVAL;
}
app_info = (nvadsp_app_info_t *)ctx2;
if (app_info && app_info->mem.shared) {
mid = (short *)(app_info->mem.shared);
dev_info(dev, "adsp_consol: open %x\n", *mid);
mbxid = *mid;
}
ret = nvadsp_mbox_open(&console->app_mbox, &mbxid,
"app_mbox", NULL, NULL);
if (ret) {
pr_err("adsp_consol: Failed to open app mailbox");
ret = -EACCES;
}
break;
case _IOC_NR(ADSP_CNSL_CLOSE_MBX):
mbox = &console->app_mbox;
while (!nvadsp_mbox_recv(mbox, &data, 0, 0))
;
ret = nvadsp_mbox_close(mbox);
if (ret)
break;
memset(mbox, 0, sizeof(struct nvadsp_mbox));
break;
case _IOC_NR(ADSP_CNSL_PUT_MBX):
if (!ACCESS_OK(uarg, sizeof(uint32_t)))
return -EACCES;
ret = copy_from_user(&data, uarg,
sizeof(uint32_t));
if (ret) {
ret = -EACCES;
break;
}
ret = nvadsp_mbox_send(&console->app_mbox, data,
NVADSP_MBOX_SMSG, 0, 0);
break;
case _IOC_NR(ADSP_CNSL_GET_MBX):
if (!ACCESS_OK(uarg, sizeof(uint32_t)))
return -EACCES;
ret = nvadsp_mbox_recv(&console->app_mbox, &data, 0, 0);
if (ret)
break;
ret = copy_to_user(uarg, &data,
sizeof(uint32_t));
if (ret)
ret = -EACCES;
break;
case _IOC_NR(ADSP_CNSL_PUT_DATA):
if (!ACCESS_OK(uarg, sizeof(struct adsp_consol_run_app_arg_t)))
return -EACCES;
ret = copy_from_user(&data, uarg, sizeof(uint32_t));
if (ret) {
ret = -EACCES;
break;
}
return nvadsp_mbox_send(&console->shl_snd_mbox, data,
NVADSP_MBOX_SMSG, 0, 0);
break;
default:
dev_info(dev, "adsp_consol: invalid command\n");
return -EINVAL;
}
return ret;
}
static const struct file_operations adsp_console_operations = {
.open = adsp_consol_open,
.release = adsp_consol_close,
#ifdef CONFIG_COMPAT
.compat_ioctl = adsp_consol_ioctl,
#endif
.unlocked_ioctl = adsp_consol_ioctl
};
int
adsp_create_cnsl(struct dentry *adsp_debugfs_root, struct nvadsp_cnsl *cnsl)
{
int ret = 0;
struct device *dev = cnsl->dev;
if (IS_ERR_OR_NULL(adsp_debugfs_root)) {
ret = -ENOENT;
goto err_out;
}
if (!debugfs_create_file("adsp_console", S_IRUSR,
adsp_debugfs_root, cnsl,
&adsp_console_operations)) {
dev_err(dev,
"unable to create adsp console debug fs file\n");
ret = -ENOENT;
goto err_out;
}
memset(&cnsl->app_mbox, 0, sizeof(cnsl->app_mbox));
err_out:
return ret;
}