kernel_samsung_a53x/drivers/samsung/debug/sec_debug_dprm.c
2024-06-15 16:02:09 -03:00

116 lines
2.5 KiB
C
Executable file

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung TN debugging code
*
*/
#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/string.h>
#include <linux/sec_debug.h>
#include "sec_debug_internal.h"
#define DPRM_MAGIC 0xABC
#define DPRM_MAGIC_SHIFT 16
struct sec_debug_kcnst *kcnst;
static void set_sec_dprm_value(uint64_t value)
{
if (!kcnst) {
pr_crit("%s: No kcnst buffer\n", __func__);
return;
}
kcnst->target_dprm_mask = value;
kcnst->target_dprm_mask |= (DPRM_MAGIC << DPRM_MAGIC_SHIFT);
pr_crit("%s: target_dprm_mask: 0x%llx\n", __func__, kcnst->target_dprm_mask);
}
static int sec_dprm_reboot_handler(struct notifier_block *this,
unsigned long mode, void *cmd)
{
unsigned long value;
if (cmd && !strncmp(cmd, "dprm", 4) && !kstrtoul(cmd + 4, 0, &value))
set_sec_dprm_value((uint64_t) value);
return 0;
}
static int sec_debug_get_clear_target_dprm_mask(char *buffer, const struct kernel_param *kp)
{
return sprintf(buffer, "0x%llx\n", kcnst->target_dprm_mask);
}
static int sec_debug_set_clear_target_dprm_mask(const char *val, const struct kernel_param *kp)
{
int ret;
int argc = 0;
char **argv;
unsigned long mask;
argv = argv_split(GFP_KERNEL, val, &argc);
if (!strcmp(argv[0], "dprm")) {
pr_crit("%s() arg : %s\n", __func__, val);
if (argc > 1) {
ret = kstrtoul(argv[1], 16, &mask);
if (!ret)
set_sec_dprm_value((uint64_t) mask);
}
}
argv_free(argv);
return 0;
}
static const struct kernel_param_ops sec_debug_clear_target_dprm_ops = {
.set = sec_debug_set_clear_target_dprm_mask,
.get = sec_debug_get_clear_target_dprm_mask,
};
module_param_cb(mask, &sec_debug_clear_target_dprm_ops, NULL, 0600);
static struct notifier_block sec_dprm_reboot_notifier = {
.notifier_call = sec_dprm_reboot_handler,
};
static int __init secdbg_dprm_init(void)
{
int ret;
kcnst = secdbg_base_get_kcnst_base();
if (!kcnst) {
pr_crit("%s: No kcnst buffer\n", __func__);
return 0;
}
ret = register_reboot_notifier(&sec_dprm_reboot_notifier);
if (ret)
pr_crit("cannot register reboot handler");
return 0;
}
module_init(secdbg_dprm_init);
static void __exit secdbg_dprm_exit(void)
{
unregister_reboot_notifier(&sec_dprm_reboot_notifier);
}
module_exit(secdbg_dprm_exit);
MODULE_DESCRIPTION("Samsung Debug Dprm driver");
MODULE_LICENSE("GPL v2");