Files
threeeye bc1d038eac REVVL 6 Pro kernel bring-up: full working tree snapshot (2026-09-12)
Squashed backup commit (no shallow-clone history issues) of
xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream
commit 9eece662e) plus all fixes applied to get everpal_defconfig building
clean against a modern (GCC 15.2.0) toolchain -- see the previous commit
message on the lineage-23.2 branch (also in this repo history is not
available here since this is a squashed snapshot; full incremental history
lives in the local DL380 checkout and the upstream GitHub remote).

Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
2026-09-12 13:36:46 +00:00

363 lines
8.8 KiB
C

/*
* Copyright (C) 2015 MediaTek Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License 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 <linux/bug.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mt-plat/aee.h>
#include <linux/kgdb.h>
#include <linux/kdb.h>
#include <linux/utsname.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/clock.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#ifdef CONFIG_MTK_WATCHDOG
#include <mtk_wd_api.h>
#endif
#include "aee-common.h"
#include "aed.h"
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <mt-plat/mrdump.h>
#include <mrdump_private.h>
static struct aee_kernel_api *g_aee_api;
#define KERNEL_REPORT_LENGTH 344
struct aee_oops *aee_oops_create(enum AE_DEFECT_ATTR attr,
enum AE_EXP_CLASS clazz, const char *module)
{
struct aee_oops *oops = kzalloc(sizeof(struct aee_oops), GFP_ATOMIC);
if (oops == NULL)
return NULL;
oops->attr = attr;
oops->clazz = clazz;
if (module != NULL)
strlcpy(oops->module, module, sizeof(oops->module));
else
strlcpy(oops->module, "N/A", sizeof(oops->module));
strlcpy(oops->backtrace, "N/A", sizeof(oops->backtrace));
strlcpy(oops->process_path, "N/A", sizeof(oops->process_path));
return oops;
}
EXPORT_SYMBOL(aee_oops_create);
void aee_oops_free(struct aee_oops *oops)
{
kfree(oops->console);
kfree(oops->android_main);
kfree(oops->android_radio);
kfree(oops->android_system);
kfree(oops->userspace_info);
kfree(oops->mmprofile);
kfree(oops->mini_rdump);
vfree(oops->userthread_stack.Userthread_Stack);
vfree(oops->userthread_maps.Userthread_maps);
kfree(oops);
pr_notice("%s\n", __func__);
}
EXPORT_SYMBOL(aee_oops_free);
void aee_register_api(struct aee_kernel_api *aee_api)
{
g_aee_api = aee_api;
}
EXPORT_SYMBOL(aee_register_api);
void aee_disable_api(void)
{
if (g_aee_api) {
pr_info("disable aee kernel api");
g_aee_api = NULL;
}
}
EXPORT_SYMBOL(aee_disable_api);
void aee_kernel_exception_api_func(const char *file, const int line,
const int db_opt, const char *module, const char *msg, ...)
{
char msgbuf[KERNEL_REPORT_LENGTH];
int offset = 0;
va_list args;
va_start(args, msg);
offset += snprintf(msgbuf, KERNEL_REPORT_LENGTH, "<%s:%d> ", file,
line);
offset += vsnprintf(msgbuf + offset, KERNEL_REPORT_LENGTH - offset, msg,
args);
if (g_aee_api && g_aee_api->kernel_reportAPI)
g_aee_api->kernel_reportAPI(AE_DEFECT_EXCEPTION, db_opt, module,
msgbuf);
else
pr_notice("AEE kernel exception: %s", msgbuf);
va_end(args);
}
EXPORT_SYMBOL(aee_kernel_exception_api_func);
void aee_kernel_warning_api_func(const char *file, const int line,
const int db_opt, const char *module, const char *msg, ...)
{
char msgbuf[KERNEL_REPORT_LENGTH];
int offset = 0;
va_list args;
va_start(args, msg);
offset += snprintf(msgbuf, KERNEL_REPORT_LENGTH, "<%s:%d> ", file,
line);
offset += vsnprintf(msgbuf + offset, KERNEL_REPORT_LENGTH - offset,
msg, args);
if (g_aee_api && g_aee_api->kernel_reportAPI) {
if (module && strstr(module,
"maybe have other hang_detect KE DB"))
g_aee_api->kernel_reportAPI(AE_DEFECT_FATAL, db_opt,
module, msgbuf);
else
g_aee_api->kernel_reportAPI(AE_DEFECT_WARNING, db_opt,
module, msgbuf);
} else {
pr_notice("AEE kernel warning: %s", msgbuf);
}
va_end(args);
}
EXPORT_SYMBOL(aee_kernel_warning_api_func);
void aee_kernel_reminding_api(const char *file, const int line,
const int db_opt, const char *module, const char *msg, ...)
{
char msgbuf[KERNEL_REPORT_LENGTH];
int offset = 0;
va_list args;
va_start(args, msg);
offset += snprintf(msgbuf, KERNEL_REPORT_LENGTH, "<%s:%d> ",
file, line);
offset += vsnprintf(msgbuf + offset, KERNEL_REPORT_LENGTH - offset,
msg, args);
if (g_aee_api && g_aee_api->kernel_reportAPI)
g_aee_api->kernel_reportAPI(AE_DEFECT_REMINDING, db_opt,
module, msgbuf);
else
pr_notice("AEE kernel reminding: %s", msgbuf);
va_end(args);
}
EXPORT_SYMBOL(aee_kernel_reminding_api);
void aed_md_exception_api(const int *log, int log_size, const int *phy,
int phy_size, const char *detail, const int db_opt)
{
#ifdef CONFIG_MTK_AEE_AED
pr_debug("%s\n", __func__);
if (g_aee_api) {
if (g_aee_api->md_exception) {
g_aee_api->md_exception("modem", log, log_size, phy,
phy_size, detail, db_opt);
} else {
pr_debug("g_aee_api->md_exception = 0x%p\n",
g_aee_api->md_exception);
}
} else {
pr_debug("g_aee_api is null\n");
}
pr_debug("%s out\n", __func__);
#endif
}
EXPORT_SYMBOL(aed_md_exception_api);
void aed_md32_exception_api(const int *log, int log_size, const int *phy,
int phy_size, const char *detail, const int db_opt)
{
#ifdef CONFIG_MTK_AEE_AED
pr_debug("%s\n", __func__);
if (g_aee_api) {
if (g_aee_api->md_exception) {
g_aee_api->md_exception("md32", log, log_size, phy,
phy_size, detail, db_opt);
} else {
pr_debug("g_aee_api->md32_exception = 0x%p\n",
g_aee_api->md32_exception);
}
} else {
pr_debug("g_aee_api is null\n");
}
pr_debug("%s out\n", __func__);
#endif
}
EXPORT_SYMBOL(aed_md32_exception_api);
void aed_scp_exception_api(const int *log, int log_size, const int *phy,
int phy_size, const char *detail, const int db_opt)
{
#ifdef CONFIG_MTK_AEE_AED
pr_debug("%s\n", __func__);
if (g_aee_api) {
if (g_aee_api->md_exception) {
g_aee_api->md_exception("scp", log, log_size, phy,
phy_size, detail, db_opt);
} else {
pr_debug("g_aee_api->scp_exception = 0x%p\n",
g_aee_api->scp_exception);
}
} else {
pr_debug("g_aee_api is null\n");
}
pr_debug("%s out\n", __func__);
#endif
}
EXPORT_SYMBOL(aed_scp_exception_api);
void aed_combo_exception_api(const int *log, int log_size, const int *phy,
int phy_size, const char *detail, const int db_opt)
{
#ifdef CONFIG_MTK_AEE_AED
pr_debug("aed_combo_exception\n");
if (g_aee_api) {
if (g_aee_api->combo_exception) {
g_aee_api->combo_exception("combo", log, log_size, phy,
phy_size, detail, db_opt);
} else {
pr_debug("g_aee_api->combo_exception = 0x%p\n",
g_aee_api->combo_exception);
}
} else {
pr_debug("g_aee_api is null\n");
}
pr_debug("aed_combo_exception out\n");
#endif
}
EXPORT_SYMBOL(aed_combo_exception_api);
void aed_common_exception_api(const char *assert_type, const int *log,
int log_size, const int *phy, int phy_size,
const char *detail, const int db_opt)
{
#ifdef CONFIG_MTK_AEE_AED
pr_debug("%s\n", __func__);
if (g_aee_api) {
if (g_aee_api->common_exception) {
g_aee_api->common_exception(assert_type, log, log_size,
phy, phy_size, detail, db_opt);
} else {
pr_debug("g_aee_api->common_exception = 0x%p\n",
g_aee_api->common_exception);
}
} else {
pr_debug("g_aee_api is null\n");
}
pr_debug("%s out\n", __func__);
#endif
}
EXPORT_SYMBOL(aed_common_exception_api);
int aee_is_printk_too_much(const char *module)
{
#ifdef CONFIG_MTK_AEE_AED
if (strstr(module, "intk too much"))
return 1;
#endif
return 0;
}
EXPORT_SYMBOL(aee_is_printk_too_much);
char sram_printk_buf[256];
void aee_sram_printk(const char *fmt, ...)
{
#ifdef CONFIG_MTK_RAM_CONSOLE
unsigned long long t;
unsigned long nanosec_rem;
va_list args;
int r, tlen;
va_start(args, fmt);
preempt_disable();
t = cpu_clock(get_HW_cpuid());
nanosec_rem = do_div(t, 1000000000);
tlen = sprintf(sram_printk_buf, ">%5lu.%06lu< ", (unsigned long)t,
nanosec_rem / 1000);
if (tlen < 0) {
preempt_enable();
return;
}
r = vscnprintf(sram_printk_buf + tlen, sizeof(sram_printk_buf) - tlen,
fmt, args);
ram_console_write(NULL, sram_printk_buf, r + tlen);
preempt_enable();
va_end(args);
#endif
}
EXPORT_SYMBOL(aee_sram_printk);
int aee_is_enable(void)
{
struct device_node *node;
const char *aee_enable;
int ret = 0;
node = of_find_node_by_path("/chosen");
if (node) {
if (of_property_read_string(node, "aee,enable", &aee_enable) == 0) {
if (strnstr(aee_enable, "mini", 4))
ret = 1;
else if (strnstr(aee_enable, "full", 4))
ret = 2;
}
of_node_put(node);
} else {
pr_notice("%s: Can't find chosen node\n", __func__);
}
return ret;
}
EXPORT_SYMBOL(aee_is_enable);
int aed_get_status(void)
{
int mode;
mode = aee_get_mode();
if ((mode >= AEE_MODE_MTK_ENG) && (mode <= AEE_MODE_CUSTOMER_USER))
return 1;
return 0;
}
EXPORT_SYMBOL(aed_get_status);
static int __init aee_common_init(void)
{
int ret = 0;
return ret;
}
static void __exit aee_common_exit(void)
{
}
module_init(aee_common_init);
module_exit(aee_common_exit);