treewide: Clean up oplus feedback

We don't need those tracers.

Change-Id: I9539aaceed82a36d6e92faabfaf999caed08e3ed
Signed-off-by: LibXZR <i@xzr.moe>
This commit is contained in:
LibXZR
2023-06-09 12:36:45 +08:00
committed by Michael Bestas
parent 8e83128af3
commit fe99e930db
46 changed files with 5 additions and 3810 deletions

View File

@@ -79,7 +79,6 @@ OPLUS_FEATURE_PROCESS_RECLAIM \
OPLUS_FEATURE_ZRAM_OPT \
OPLUS_FEATURE_AUDIO_FTM \
OPLUS_FEATURE_SPEAKER_MUTE \
OPLUS_FEATURE_MM_FEEDBACK \
OPLUS_FEATURE_MI2S_SLAVE \
OPLUS_FEATURE_KTV \
OPLUS_FEATURE_QCOM_WATCHDOG \

View File

@@ -280,9 +280,6 @@
Hw,sim_det = "modem_det";
};
//#endif /* OPLUS_BUG_DEBUG */
feedback_fb {
compatible = "oplus,haptic-feedback";
};
};
/*&qupv3_se13_i2c {
#address-cells = <1>;

View File

@@ -287,9 +287,6 @@
Hw,sim_det = "modem_det";
};
//#endif /* OPLUS_BUG_DEBUG */
feedback_fb {
compatible = "oplus,haptic-feedback";
};
};
/*&qupv3_se13_i2c {
#address-cells = <1>;

View File

@@ -277,9 +277,6 @@
pinctrl-0 = <&rf_cable0_active>;
};*/
//#endif /* OPLUS_FEATURE_TP_BASIC */
feedback_fb {
compatible = "oplus,haptic-feedback";
};
};
/*&qupv3_se13_i2c {
#address-cells = <1>;

View File

@@ -278,9 +278,6 @@
Hw,sim_det = "modem_det";
};
//#endif /* OPLUS_BUG_DEBUG */
feedback_fb {
compatible = "oplus,haptic-feedback";
};
};
/*&qupv3_se13_i2c {
#address-cells = <1>;

View File

@@ -18,7 +18,6 @@ CONFIG_EMMC_SDCARD_OPTIMIZE=y
CONFIG_EROFS_FS=y
CONFIG_EXFAT_FS=y
CONFIG_FRAME_WARN=4096
CONFIG_HAPTIC_FEEDBACK=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HID_BETOP_FF=y
# CONFIG_HL6111R is not set
@@ -50,11 +49,9 @@ CONFIG_OPLUS_FEATURE_DATA_EVAL=y
CONFIG_OPLUS_FEATURE_DNS_HOOK=y
CONFIG_OPLUS_FEATURE_DUMP_DEVICE_INFO=y
CONFIG_OPLUS_FEATURE_FDLEAK_CHECK=y
CONFIG_OPLUS_FEATURE_FEEDBACK=y
CONFIG_OPLUS_FEATURE_IM=y
CONFIG_OPLUS_FEATURE_MDMFEATURE=y
CONFIG_OPLUS_FEATURE_MIDAS=y
CONFIG_OPLUS_FEATURE_MM_FEEDBACK=y
CONFIG_OPLUS_FEATURE_OLC=y
CONFIG_OPLUS_FEATURE_OPROJECT=y
CONFIG_OPLUS_FEATURE_PMIC_MONITOR=y

View File

@@ -21,10 +21,6 @@
#include "kgsl_sharedmem.h"
#include "kgsl_trace.h"
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif /*OPLUS_BUG_STABILITY*/
#define _IOMMU_PRIV(_mmu) (&((_mmu)->priv.iommu))
#define ADDR_IN_GLOBAL(_mmu, _a) \
@@ -830,13 +826,6 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
if (!no_page_fault_log && __ratelimit(&_rs)) {
#ifdef OPLUS_BUG_STABILITY
mm_fb_kevent(OPLUS_MM_DIRVER_FB_EVENT_DISPLAY,
OPLUS_DISPLAY_EVENTID_GPU_FAULT,
"gpu fault", MM_FB_KEY_RATELIMIT_1H,
"pid=%08lx,comm=%d", ptname, comm);
#endif /*OPLUS_BUG_STABILITY*/
dev_crit(ctx->kgsldev->dev,
"GPU PAGE FAULT: addr = %lX pid= %d name=%s\n", addr,
ptname, comm);

View File

@@ -654,10 +654,6 @@ config SIM_DETECT
default n
help
Say Y here to enable sim detect system support
config HAPTIC_FEEDBACK
tristate "Haptic driver feedback for awinic aw8697 series"
help
This option enables support for aw8697 series Haptic Driver Feedback.
#endif /* OPLUS_FEATURE_SIM_DETECT */
#ifdef OPLUS_FEATURE_SIM_DETECT

View File

@@ -3,8 +3,3 @@ config AW8697_HAPTIC
depends on I2C
help
This option enables support for aw8697 series Haptic Driver.
config HAPTIC_FEEDBACK
tristate "Haptic driver feedback for awinic aw8697 series"
help
This option enables support for aw8697 series Haptic Driver Feedback.

View File

@@ -10,4 +10,3 @@ obj-$(CONFIG_AW8697_HAPTIC) += aw8697.o
obj-$(CONFIG_AW8697_HAPTIC) += haptic.o
haptic-objs := aw8692x.o haptic_hv.o
obj-$(CONFIG_HAPTIC_FEEDBACK) += haptic_feedback.o

View File

@@ -1,658 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2022-2024 Oplus. All rights reserved.
*/
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/iio/consumer.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/power_supply.h>
#include <linux/proc_fs.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/sched/clock.h>
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#include <soc/oplus/system/kernel_fb.h>
#endif
#include "haptic_feedback.h"
static struct oplus_haptic_track *g_haptic_track_chip;
static bool oplus_haptic_event_record_time_need_update(void)
{
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct timespec now = {0};
struct timespec last_record;
long time_step;
if (!chip)
return false;
getnstimeofday(&now);
last_record = chip->lastest_record;
time_step = (now.tv_sec - last_record.tv_sec) / SECSONDS_PER_HOUR;
if (time_step >= UPLOAD_TIME_LIMIT_HOURS) {
chip->lastest_record = now;
return true;
}
return false;
}
static void oplus_haptic_event_queue_update(void) {
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct haptic_dev_track_event *dev_event;
struct haptic_mem_alloc_track_event *mem_event;
bool update_flag = false;
if (!chip)
return;
update_flag = oplus_haptic_event_record_time_need_update();
if (update_flag == false)
return;
/* clear dev_event_que */
dev_event = &chip->dev_track_event;
memset(dev_event->dev_event_que, 0, sizeof(struct haptic_dev_event_info) * MAX_DEV_EVENT_QUEUE_LEN);
dev_event->que_front = 0;
dev_event->que_rear = 0;
/* clear mem_event_que */
mem_event = &chip->mem_alloc_track_event;
memset(mem_event->mem_event_que, 0, sizeof(struct haptic_mem_alloc_event_info) * MAX_MEM_ALLOC_EVENT_QUEUE_LEN);
mem_event->que_front = 0;
mem_event->que_rear = 0;
}
static struct haptic_fb_info g_haptic_fb_table[] = {
{HAPTIC_I2C_READ_TRACK_ERR, "i2c_read_err", HAPTIC_TRACK_EVENT_DEVICE_ERR},
{HAPTIC_I2C_WRITE_TRACK_ERR, "i2c_write_err", HAPTIC_TRACK_EVENT_DEVICE_ERR},
{HAPTIC_F0_CALI_TRACK, "f0_cali_err", HAPTIC_TRACK_EVENT_FRE_CALI_ERR},
{HAPTIC_OSC_CALI_TRACK, "osc_cali_err", HAPTIC_TRACK_EVENT_FRE_CALI_ERR},
{HAPTIC_MEM_ALLOC_TRACK, "mem_alloc_err", HAPTIC_TRACK_EVENT_MEM_ALLOC_ERR},
};
static int oplus_haptic_event_payload_pack(struct haptic_fb_detail *fb_info)
{
int i = 0;
char *fb_event_field = NULL;
char *fb_event_desc = NULL;
struct oplus_haptic_track *chip = g_haptic_track_chip;
char *log_tag = HAPTIC_EVENT_TAG;
char *event_id = HAPTIC_EVENT_ID;
int len;
if ((!chip) || (!chip->dcs_info) || (!fb_info))
return TRACK_CMD_ERROR_CHIP_NULL;
for (i = 0; i < ARRAY_SIZE(g_haptic_fb_table); i++) {
if (g_haptic_fb_table[i].fb_event_type == fb_info->track_type) {
fb_event_desc = g_haptic_fb_table[i].fb_event_desc;
fb_event_field = g_haptic_fb_table[i].fb_event_field;
break;
}
}
if (i == ARRAY_SIZE(g_haptic_fb_table)) {
haptic_fb_err("%s: invalid fb_event_type \n", __func__);
return TRACK_CMD_ERROR_DATA_INVALID;
}
memset(chip->dcs_info, 0x0, OPLUS_HSPTIC_TRIGGER_MSG_LEN);
snprintf(chip->dcs_info->payload, MAX_PAYLOAD_LEN,
"NULL$$EventField@@%s$$FieldData@@%s$$detailData@@%s",
fb_event_field,
fb_event_desc,
fb_info->detailData);
chip->dcs_info->payload[MAX_PAYLOAD_LEN - 1] = '\0';
len = strlen(chip->dcs_info->payload);
chip->dcs_info->type = 1;
strncpy(chip->dcs_info->log_tag, log_tag, MAX_HAPTIC_EVENT_TAG_LEN);
chip->dcs_info->log_tag[MAX_HAPTIC_EVENT_TAG_LEN - 1] = '\0';
strncpy(chip->dcs_info->event_id, event_id, MAX_HAPTIC_EVENT_ID_LEN);
chip->dcs_info->event_id[MAX_HAPTIC_EVENT_ID_LEN - 1] = '\0';
chip->dcs_info->payload_length = len + 1;
return TRACK_CMD_ACK_OK;
}
static int oplus_haptic_track_upload_trigger_data(struct haptic_fb_detail *fb_detail)
{
int rc = 0;
struct oplus_haptic_track *chip = g_haptic_track_chip;
if (!chip)
return TRACK_CMD_ERROR_CHIP_NULL;
if (!fb_detail) {
haptic_fb_err("%s:dev_event is null \n", __func__);
return TRACK_CMD_ERROR_CHIP_NULL;
}
mutex_lock(&chip->trigger_ack_lock);
mutex_lock(&chip->payload_lock);
mutex_lock(&chip->trigger_data_lock);
rc = oplus_haptic_event_payload_pack(fb_detail);
if (rc) {
haptic_fb_err("%s: oplus_payload_pack err \n", __func__);
mutex_unlock(&chip->trigger_data_lock);
mutex_unlock(&chip->payload_lock);
mutex_unlock(&chip->trigger_ack_lock);
return rc;
}
chip->trigger_data_ok = true;
mutex_unlock(&chip->trigger_data_lock);
reinit_completion(&chip->trigger_ack);
wake_up(&chip->upload_wq);
rc = wait_for_completion_timeout(
&chip->trigger_ack,
msecs_to_jiffies(OPLUS_HAPTIC_TRACK_WAIT_TIME_MS));
if (!rc) {
if (delayed_work_pending(&chip->upload_info_dwork))
cancel_delayed_work_sync(&chip->upload_info_dwork);
pr_err("Error, timed_out_upload_trigger_data \r\n");
mutex_unlock(&chip->payload_lock);
mutex_unlock(&chip->trigger_ack_lock);
return TRACK_CMD_ERROR_TIME_OUT;
}
mutex_unlock(&chip->payload_lock);
mutex_unlock(&chip->trigger_ack_lock);
haptic_fb_info("success\n");
return TRACK_CMD_ACK_OK;
}
int oplus_haptic_track_dev_err(uint32_t track_type, uint32_t reg_addr, uint32_t err_code)
{
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct haptic_dev_track_event *track_event;
uint32_t que_rear;
if (!chip)
return TRACK_CMD_ERROR_CHIP_NULL;
oplus_haptic_event_queue_update();
track_event = &chip->dev_track_event;
que_rear = track_event->que_rear;
if (que_rear >= MAX_DEV_EVENT_QUEUE_LEN)
return TRACK_CMD_ERROR_QUEUE_FULL;
track_event->dev_event_que[que_rear].track_type = track_type;
track_event->dev_event_que[que_rear].reg_addr = reg_addr;
track_event->dev_event_que[que_rear].err_code = err_code;
track_event->que_rear++;
schedule_delayed_work(&track_event->track_dev_err_load_trigger_work, 0);
return TRACK_CMD_ACK_OK;
}
EXPORT_SYMBOL(oplus_haptic_track_dev_err);
int oplus_haptic_track_fre_cail(uint32_t track_type, uint32_t cali_data, uint32_t result_flag, char *fail_info)
{
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct haptic_fre_cail_track_event *track_event;
if (!chip)
return TRACK_CMD_ERROR_CHIP_NULL;
track_event = &chip->fre_cail_track_event;
memset(track_event->fre_event.fail_info, 0, sizeof(char) * MAX_FAIL_INFO_LEN);
track_event->fre_event.track_type = track_type;
track_event->fre_event.cali_data = cali_data;
track_event->fre_event.result_flag = result_flag;
strncpy(track_event->fre_event.fail_info, fail_info, MAX_FAIL_INFO_LEN - 1);
track_event->fre_event.fail_info[MAX_FAIL_INFO_LEN - 1] = '\0';
schedule_delayed_work(&track_event->track_fre_cail_load_trigger_work, 0);
return TRACK_CMD_ACK_OK;
}
EXPORT_SYMBOL(oplus_haptic_track_fre_cail);
int oplus_haptic_track_mem_alloc_err(uint32_t track_type, uint32_t alloc_len, const char *fun_name)
{
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct haptic_mem_alloc_track_event *track_event;
uint32_t que_rear;
if (!chip)
return TRACK_CMD_ERROR_CHIP_NULL;
oplus_haptic_event_queue_update();
track_event = &chip->mem_alloc_track_event;
que_rear = track_event->que_rear;
if (que_rear >= MAX_MEM_ALLOC_EVENT_QUEUE_LEN)
return TRACK_CMD_ERROR_QUEUE_FULL;
track_event->mem_event_que[que_rear].track_type = track_type;
track_event->mem_event_que[que_rear].alloc_len = alloc_len;
strncpy(track_event->mem_event_que[que_rear].fun_name, fun_name, MAX_FUN_NAME_LEN - 1);
track_event->mem_event_que[que_rear].fun_name[MAX_FUN_NAME_LEN - 1] = '\0';
track_event->que_rear++;
schedule_delayed_work(&track_event->track_mem_alloc_err_load_trigger_work, 0);
return TRACK_CMD_ACK_OK;
}
EXPORT_SYMBOL(oplus_haptic_track_mem_alloc_err);
static void oplus_haptic_track_dev_err_load_trigger_work(struct work_struct *work)
{
uint32_t que_front;
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct delayed_work *dwork = to_delayed_work(work);
struct haptic_dev_track_event *dev_event =
container_of(dwork, struct haptic_dev_track_event,
track_dev_err_load_trigger_work);
struct haptic_fb_detail *fb_detail;
if ((!chip) || (!dev_event)) {
haptic_fb_err("%s:g_haptic_track_chip is null \n", __func__);
return;
}
que_front = dev_event->que_front;
if (que_front >= dev_event->que_rear)
return;
fb_detail = &dev_event->dev_detail_data;
fb_detail->track_type = dev_event->dev_event_que[que_front].track_type;
memset(fb_detail->detailData, 0, MAX_DETAIL_INFO_LEN);
snprintf(fb_detail->detailData, MAX_DETAIL_INFO_LEN,
"reg_addr:0x%x,err_code:%u", dev_event->dev_event_que[que_front].reg_addr,
dev_event->dev_event_que[que_front].err_code);
dev_event->que_front++;
oplus_haptic_track_upload_trigger_data(fb_detail);
}
static void oplus_haptic_track_fre_cail_load_trigger_work(struct work_struct *work)
{
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct delayed_work *dwork = to_delayed_work(work);
struct haptic_fre_cail_track_event *cail_event =
container_of(dwork, struct haptic_fre_cail_track_event,
track_fre_cail_load_trigger_work);
struct haptic_fb_detail *fb_detail;
if ((!chip) || (!cail_event)) {
haptic_fb_err("%s:g_haptic_track_chip is null \n", __func__);
return;
}
fb_detail = &cail_event->fre_cali_detail;
fb_detail->track_type = cail_event->fre_event.track_type;
memset(fb_detail->detailData, 0, MAX_DETAIL_INFO_LEN);
snprintf(fb_detail->detailData, MAX_DETAIL_INFO_LEN,
"cali_data:%u,cali_ret:0x%x,fail_info:%s", cail_event->fre_event.cali_data,
cail_event->fre_event.result_flag, cail_event->fre_event.fail_info);
oplus_haptic_track_upload_trigger_data(fb_detail);
}
static void oplus_haptic_track_mem_alloc_load_trigger_work(struct work_struct *work)
{
uint32_t que_front;
struct oplus_haptic_track *chip = g_haptic_track_chip;
struct delayed_work *dwork = to_delayed_work(work);
struct haptic_mem_alloc_track_event *mem_event =
container_of(dwork, struct haptic_mem_alloc_track_event,
track_mem_alloc_err_load_trigger_work);
struct haptic_fb_detail *fb_detail;
if ((!chip) || (!mem_event)) {
haptic_fb_err("%s:g_haptic_track_chip is null \n", __func__);
return;
}
que_front = mem_event->que_front;
if (que_front >= mem_event->que_rear)
return;
fb_detail = &mem_event->mem_detail;
fb_detail->track_type = mem_event->mem_event_que[que_front].track_type;
memset(fb_detail->detailData, 0, MAX_DETAIL_INFO_LEN);
snprintf(fb_detail->detailData, MAX_DETAIL_INFO_LEN,
"alloc_len:0x%x,fun_name:%s", mem_event->mem_event_que[que_front].alloc_len,
mem_event->mem_event_que[que_front].fun_name);
(mem_event->que_front)++;
oplus_haptic_track_upload_trigger_data(fb_detail);
}
static void oplus_haptic_track_upload_info_dwork(struct work_struct *work)
{
int ret = 0;
struct delayed_work *dwork = to_delayed_work(work);
struct oplus_haptic_track *chip =
container_of(dwork, struct oplus_haptic_track, upload_info_dwork);
if ((!chip) || (!chip->dcs_info))
return;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
ret = fb_kevent_send_to_user(chip->dcs_info);
#endif
if (!ret) {
complete(&chip->trigger_ack);
} else if (chip->fb_retry_cnt > 0) {
queue_delayed_work(chip->trigger_upload_wq, &chip->upload_info_dwork,
msecs_to_jiffies(OPLUS_HAPTIC_UPDATE_INFO_DELAY_MS));
}
haptic_fb_info("retry_cnt: %d, ret = %d\n", chip->fb_retry_cnt, ret);
chip->fb_retry_cnt--;
}
static int oplus_haptic_track_thread(void *data)
{
int rc = 0;
struct oplus_haptic_track *chip = (struct oplus_haptic_track *)data;
if (!chip)
return -1;
haptic_fb_info("start\n");
while (!kthread_should_stop()) {
mutex_lock(&chip->upload_lock);
rc = wait_event_interruptible(chip->upload_wq,
chip->trigger_data_ok);
mutex_unlock(&chip->upload_lock);
if (rc)
return rc;
if (!chip->trigger_data_ok)
haptic_fb_err("oplus haptic track false wakeup, rc=%d\n", rc);
mutex_lock(&chip->trigger_data_lock);
chip->trigger_data_ok = false;
chip->fb_retry_cnt = OPLUS_HAPTIC_FB_RETRY_TIME;
queue_delayed_work(chip->trigger_upload_wq,
&chip->upload_info_dwork, 0);
mutex_unlock(&chip->trigger_data_lock);
}
return rc;
}
static void oplus_haptic_track_init(struct oplus_haptic_track *track_dev)
{
struct oplus_haptic_track *chip = track_dev;
struct haptic_dev_track_event *dev_event;
struct haptic_fre_cail_track_event *fre_cail_event;
struct haptic_mem_alloc_track_event *mem_alloc_event;
chip->trigger_data_ok = false;
mutex_init(&chip->upload_lock);
mutex_init(&chip->trigger_data_lock);
mutex_init(&chip->trigger_ack_lock);
init_waitqueue_head(&chip->upload_wq);
init_completion(&chip->trigger_ack);
mutex_init(&chip->payload_lock);
/* init timespec */
getnstimeofday(&track_dev->lastest_record);
/* event track init */
dev_event = &(track_dev->dev_track_event);
INIT_DELAYED_WORK(&dev_event->track_dev_err_load_trigger_work,
oplus_haptic_track_dev_err_load_trigger_work);
dev_event->que_front = 0;
dev_event->que_rear = 0;
/* fre cali track init */
fre_cail_event = &(track_dev->fre_cail_track_event);
INIT_DELAYED_WORK(&fre_cail_event->track_fre_cail_load_trigger_work,
oplus_haptic_track_fre_cail_load_trigger_work);
/* mem alloc track init */
mem_alloc_event = &(track_dev->mem_alloc_track_event);
INIT_DELAYED_WORK(&mem_alloc_event->track_mem_alloc_err_load_trigger_work,
oplus_haptic_track_mem_alloc_load_trigger_work);
mem_alloc_event->que_front = 0;
mem_alloc_event->que_rear = 0;
}
/* debug node */
static struct haptic_dev_event_info event_info_node;
static struct haptic_fre_cail_event_info fre_cail_node;
static struct haptic_mem_alloc_event_info mem_alloc_node;
static ssize_t dev_event_track_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return oplus_haptic_track_dev_err(event_info_node.track_type, event_info_node.reg_addr, event_info_node.err_code);
}
static ssize_t dev_event_track_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
uint8_t track_type = 0;
uint8_t reg_addr = 0;
uint32_t err_code = 0;
if (sscanf(buf, "%d %x %d", &track_type, &reg_addr, &err_code) == 3) {
if (track_type >= HAPTIC_TRACK_TYPE_MAX) {
haptic_fb_err("%s: first value out of range!\n", __func__);
return len;
}
event_info_node.track_type = track_type;
event_info_node.reg_addr = reg_addr;
event_info_node.err_code = err_code;
}
return len;
}
static ssize_t dev_fre_cail_track_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return oplus_haptic_track_fre_cail(fre_cail_node.track_type, fre_cail_node.cali_data,
fre_cail_node.result_flag, fre_cail_node.fail_info);
}
static ssize_t dev_fre_cail_track_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
uint8_t track_type = 0;
uint32_t cali_data = 0;
uint32_t result_flag = 0; /* 0 is success, 1 is fail */
char fail_info[MAX_FAIL_INFO_LEN];
if (sscanf(buf, "%d %d %d %127s", &track_type, &cali_data, &result_flag, &fail_info[0]) == 4) {
if (track_type >= HAPTIC_TRACK_TYPE_MAX) {
haptic_fb_err("%s: first value out of range!\n", __func__);
return len;
}
fre_cail_node.track_type = track_type;
fre_cail_node.cali_data = cali_data;
fre_cail_node.result_flag = result_flag;
memset(fre_cail_node.fail_info, 0, MAX_FAIL_INFO_LEN);
strncpy(fre_cail_node.fail_info, fail_info, MAX_FAIL_INFO_LEN - 1);
fre_cail_node.fail_info[MAX_FAIL_INFO_LEN - 1] = '\0';
}
return len;
}
static ssize_t dev_mem_alloc_track_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return oplus_haptic_track_mem_alloc_err(mem_alloc_node.track_type, mem_alloc_node.alloc_len, __func__);
}
static ssize_t dev_mem_alloc_track_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
uint8_t track_type = 0;
uint32_t alloc_len = 0;
if (sscanf(buf, "%d %x", &track_type, &alloc_len) == 2) {
if (track_type >= HAPTIC_TRACK_TYPE_MAX) {
haptic_fb_err("%s: first value out of range!\n", __func__);
return len;
}
mem_alloc_node.track_type = track_type;
mem_alloc_node.alloc_len = alloc_len;
}
return len;
}
static DEVICE_ATTR(event_track, 0664, dev_event_track_show,
dev_event_track_store);
static DEVICE_ATTR(fre_cali_track, 0664, dev_fre_cail_track_show,
dev_fre_cail_track_store);
static DEVICE_ATTR(mem_alloc_track, 0664, dev_mem_alloc_track_show,
dev_mem_alloc_track_store);
static struct attribute *haptic_fb_attributes[] = {
&dev_attr_event_track.attr,
&dev_attr_fre_cali_track.attr,
&dev_attr_mem_alloc_track.attr,
NULL,
};
static struct attribute_group haptic_fb_attributes_group = {
.attrs = haptic_fb_attributes
};
static struct file_operations mytest_ops = {
.owner = THIS_MODULE,
};
static int major;
static struct class *cls;
static int oplus_haptic_feedback_probe(struct platform_device *pdev)
{
int ret;
struct oplus_haptic_track *hapric_track;
/* debug_node */
struct device *mydev;
major = register_chrdev(0, "haptic_fb", &mytest_ops);
cls = class_create(THIS_MODULE, "haptic_fb_class");
mydev = device_create(cls, 0, MKDEV(major, 0), NULL, "haptic_fb_device");
ret = sysfs_create_group(&(mydev->kobj), &haptic_fb_attributes_group);
if (ret < 0) {
haptic_fb_err("%s: error creating sysfs attr files\n", __func__);
return ret;
}
hapric_track = devm_kzalloc(&pdev->dev, sizeof(struct oplus_haptic_track), GFP_KERNEL);
if (!hapric_track) {
pr_err("alloc memory error\n");
return -ENOMEM;
}
hapric_track->dcs_info = (struct kernel_packet_info *)devm_kzalloc(&pdev->dev,
sizeof(char) * OPLUS_HSPTIC_TRIGGER_MSG_LEN, GFP_KERNEL);
if (!hapric_track->dcs_info) {
ret = -ENOMEM;
goto dcs_info_kmalloc_fail;
}
hapric_track->dev = &pdev->dev;
platform_set_drvdata(pdev, hapric_track);
oplus_haptic_track_init(hapric_track);
/* creat feedback monitor thread */
hapric_track->track_upload_kthread = kthread_run(oplus_haptic_track_thread, (void *)hapric_track,
"track_upload_kthread");
if (IS_ERR(hapric_track->track_upload_kthread)) {
pr_err("failed to create oplus_haptic_track_thread\n");
ret = -EINVAL;
goto track_kthread_init_err;
}
INIT_DELAYED_WORK(&hapric_track->upload_info_dwork,
oplus_haptic_track_upload_info_dwork);
hapric_track->trigger_upload_wq = create_workqueue("haptic_chg_trigger_upload_wq");
g_haptic_track_chip = hapric_track;
pr_info("probe done\n");
return 0;
track_kthread_init_err:
devm_kfree(&pdev->dev, hapric_track->dcs_info);
dcs_info_kmalloc_fail:
devm_kfree(&pdev->dev, hapric_track);
return ret;
}
static int oplus_haptic_feedback_remove(struct platform_device *pdev)
{
struct oplus_haptic_track *hapric_track = platform_get_drvdata(pdev);
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "haptic_fb");
mutex_destroy(&hapric_track->upload_lock);
mutex_destroy(&hapric_track->trigger_data_lock);
mutex_destroy(&hapric_track->trigger_ack_lock);
mutex_destroy(&hapric_track->payload_lock);
cancel_delayed_work_sync(&hapric_track->dev_track_event.track_dev_err_load_trigger_work);
cancel_delayed_work_sync(&hapric_track->fre_cail_track_event.track_fre_cail_load_trigger_work);
cancel_delayed_work_sync(&hapric_track->mem_alloc_track_event.track_mem_alloc_err_load_trigger_work);
devm_kfree(&pdev->dev, hapric_track->dcs_info);
devm_kfree(&pdev->dev, hapric_track);
return 0;
}
static const struct of_device_id oplus_haptic_drv_match[] = {
{.compatible = "oplus,haptic-feedback"},
{},
};
static struct platform_driver oplus_haptic_feedback_driver = {
.driver =
{
.name = "haptic_feedback",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(oplus_haptic_drv_match),
},
.probe = oplus_haptic_feedback_probe,
.remove = oplus_haptic_feedback_remove,
};
static int __init haptic_feedback_init(void)
{
pr_info("sensor_feedback_init call\n");
return platform_driver_register(&oplus_haptic_feedback_driver);
}
static void __exit haptic_feedback_exit(void)
{
pr_info("sensor_feedback_exit call\n");
platform_driver_unregister(&oplus_haptic_feedback_driver);
}
module_init(haptic_feedback_init);
module_exit(haptic_feedback_exit);
MODULE_LICENSE("GPL v2");

View File

@@ -1,186 +0,0 @@
#ifndef _HAPTIC_FEEDBACK_H_
#define _HAPTIC_FEEDBACK_H_
#define HAPTIC_EVENT_TAG "fb_vibrator"
#define HAPTIC_EVENT_ID "vibrator_track"
#define MAX_HAPTIC_EVENT_TAG_LEN (32)
#define MAX_HAPTIC_EVENT_ID_LEN (20)
#define OPLUS_HAPTIC_TRACK_WAIT_TIME_MS (3000)
#define MAX_PAYLOAD_LEN (1024)
#define MAX_DETAIL_INFO_LEN (512)
#define MAX_FAIL_INFO_LEN (128)
#define MAX_FUN_NAME_LEN (64)
#define OPLUS_HAPTIC_UPDATE_INFO_DELAY_MS (500)
#define OPLUS_HAPTIC_FB_RETRY_TIME (2)
#define UPLOAD_TIME_LIMIT_HOURS (2)
#define SECSONDS_PER_HOUR (60 * 60)
#define MAX_DEV_EVENT_QUEUE_LEN (10)
#define MAX_MEM_ALLOC_EVENT_QUEUE_LEN (5)
#define OPLUS_HSPTIC_TRIGGER_MSG_LEN (2048)
#define HAPTIC_TRACK_EVENT_DEVICE_ERR "haptic_device_err"
#define HAPTIC_TRACK_EVENT_FRE_CALI_ERR "haptic_fre_cli_err"
#define HAPTIC_TRACK_EVENT_MEM_ALLOC_ERR "haptic_mem_alloc_err"
#ifdef CONFIG_OPLUS_CHARGER_MTK /* mtk platform */
#include <linux/device.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
#ifdef __KERNEL__
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
struct timespec {
__kernel_old_time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
#endif
#if __BITS_PER_LONG == 64
/* timespec64 is defined as timespec here */
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) {
return *(const struct timespec *)&ts64;
}
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) {
return *(const struct timespec64 *)&ts;
}
#else
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) {
struct timespec ret;
ret.tv_sec = (time_t)ts64.tv_sec;
ret.tv_nsec = ts64.tv_nsec;
return ret;
}
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) {
struct timespec64 ret;
ret.tv_sec = ts.tv_sec;
ret.tv_nsec = ts.tv_nsec;
return ret;
}
#endif
static inline void getnstimeofday(struct timespec *ts) {
struct timespec64 ts64;
ktime_get_real_ts64(&ts64);
*ts = timespec64_to_timespec(ts64);
}
#endif
#endif
/*********************************************************
*
* Log Format
*
*********************************************************/
#define haptic_fb_err(format, ...) \
pr_err("[haptic_hv]" format, ##__VA_ARGS__)
#define haptic_fb_info(format, ...) \
pr_info("[haptic_hv]" format, ##__VA_ARGS__)
#define haptic_fb_dbg(format, ...) \
pr_debug("[haptic_hv]" format, ##__VA_ARGS__)
enum oplus_haptic_track_cmd_error {
TRACK_CMD_ACK_OK = 0,
TRACK_CMD_ERROR_CHIP_NULL,
TRACK_CMD_ERROR_DATA_NULL,
TRACK_CMD_ERROR_DATA_INVALID,
TRACK_CMD_ERROR_TIME_OUT,
TRACK_CMD_ERROR_QUEUE_FULL,
};
enum haptic_fb_track_type {
HAPTIC_I2C_READ_TRACK_ERR,
HAPTIC_I2C_WRITE_TRACK_ERR,
HAPTIC_F0_CALI_TRACK,
HAPTIC_OSC_CALI_TRACK,
HAPTIC_MEM_ALLOC_TRACK,
HAPTIC_TRACK_TYPE_MAX,
};
struct haptic_fb_detail {
uint32_t track_type;
char detailData[MAX_DETAIL_INFO_LEN];
};
struct haptic_dev_event_info {
uint32_t track_type;
uint32_t reg_addr;
uint32_t err_code;
};
struct haptic_dev_track_event {
struct haptic_dev_event_info dev_event_que[MAX_DEV_EVENT_QUEUE_LEN];
uint32_t que_front;
uint32_t que_rear;
struct haptic_fb_detail dev_detail_data;
struct delayed_work track_dev_err_load_trigger_work;
};
struct haptic_fre_cail_event_info {
uint32_t track_type;
uint32_t cali_data;
uint32_t result_flag; /* 0 is success, 1 is fail */
char fail_info[MAX_FAIL_INFO_LEN];
};
struct haptic_fre_cail_track_event {
struct haptic_fre_cail_event_info fre_event;
struct haptic_fb_detail fre_cali_detail;
struct delayed_work track_fre_cail_load_trigger_work;
};
struct haptic_mem_alloc_event_info {
uint32_t track_type;
uint32_t alloc_len;
char fun_name[MAX_FUN_NAME_LEN];
};
struct haptic_mem_alloc_track_event {
struct haptic_mem_alloc_event_info mem_event_que[MAX_MEM_ALLOC_EVENT_QUEUE_LEN];
uint32_t que_front;
uint32_t que_rear;
struct haptic_fb_detail mem_detail;
struct delayed_work track_mem_alloc_err_load_trigger_work;
};
struct oplus_haptic_track {
struct device *dev;
struct task_struct *track_upload_kthread;
bool trigger_data_ok;
struct mutex upload_lock;
struct mutex trigger_data_lock;
struct mutex trigger_ack_lock;
struct completion trigger_ack;
wait_queue_head_t upload_wq;
struct workqueue_struct *trigger_upload_wq;
struct delayed_work upload_info_dwork;
struct mutex payload_lock;
int fb_retry_cnt;
struct timespec lastest_record;
struct kernel_packet_info *dcs_info;
struct haptic_dev_track_event dev_track_event;
struct haptic_fre_cail_track_event fre_cail_track_event;
struct haptic_mem_alloc_track_event mem_alloc_track_event;
};
struct haptic_fb_info {
uint32_t fb_event_type;
char *fb_event_desc;
char *fb_event_field;
};
int oplus_haptic_track_dev_err(uint32_t track_type, uint32_t reg_addr, uint32_t err_code);
int oplus_haptic_track_fre_cail(uint32_t track_type, uint32_t cali_data, uint32_t result_flag, char* fail_info);
int oplus_haptic_track_mem_alloc_err(uint32_t track_type, uint32_t alloc_len, const char *fun_name);
#endif

View File

@@ -43,9 +43,6 @@
#include "haptic_hv.h"
#include "haptic_hv_reg.h"
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
#include "haptic_feedback.h"
#endif
#define HAPTIC_HV_DRIVER_VERSION "v0.0.0.9"
static uint8_t AW86927_HAPTIC_HIGH_LEVEL_REG_VAL = 0x5E;//max boost 9.408V
@@ -1840,9 +1837,6 @@ static int container_init(int size)
aw_rtp = vmalloc(size);
if (!aw_rtp) {
aw_dev_err("%s: error allocating memory\n", __func__);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_mem_alloc_err(HAPTIC_MEM_ALLOC_TRACK, size, __func__);
#endif
return -ENOMEM;
}
aw_container_size = size;
@@ -1880,9 +1874,6 @@ int i2c_r_bytes(struct aw_haptic *aw_haptic, uint8_t reg_addr, uint8_t *buf,
ret = i2c_transfer(aw_haptic->i2c->adapter, msg, ARRAY_SIZE(msg));
if (ret < 0) {
aw_dev_err("%s: transfer failed.", __func__);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_dev_err(HAPTIC_I2C_READ_TRACK_ERR, reg_addr, ret);
#endif
return ret;
} else if (ret != 2) {
aw_dev_err("%s: transfer failed(size error).", __func__);
@@ -1908,9 +1899,6 @@ int i2c_w_bytes(struct aw_haptic *aw_haptic, uint8_t reg_addr, uint8_t *buf,
if (ret < 0) {
aw_dev_err("%s: i2c master send 0x%02x error\n",
__func__, reg_addr);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_dev_err(HAPTIC_I2C_WRITE_TRACK_ERR, reg_addr, ret);
#endif
}
kfree(data);
return ret;
@@ -2272,9 +2260,6 @@ static void ram_load(const struct firmware *cont, void *context)
release_firmware(cont);
aw_dev_err("%s: Error allocating memory\n",
__func__);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_mem_alloc_err(HAPTIC_MEM_ALLOC_TRACK, cont->size + sizeof(int), __func__);
#endif
return;
}
awinic_fw->len = cont->size;
@@ -2459,9 +2444,6 @@ static int f0_cali(struct aw_haptic *aw_haptic)
if (aw_haptic->func->get_f0(aw_haptic)) {
aw_dev_err("%s: get f0 error, user defafult f0\n",
__func__);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_fre_cail(HAPTIC_F0_CALI_TRACK, aw_haptic->f0, 0, "aw_haptic->func->get_f0 is null");
#endif
} else {
/* max and min limit */
f0_limit = aw_haptic->f0;
@@ -2474,9 +2456,6 @@ static int f0_cali(struct aw_haptic *aw_haptic)
aw_dev_err("%s: f0 calibration out of range = %d!\n",
__func__, aw_haptic->f0);
f0_limit = aw_haptic->info.f0_pre;
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_fre_cail(HAPTIC_F0_CALI_TRACK, aw_haptic->f0, -ERANGE, "f0 out of range");
#endif
return -ERANGE;
}
aw_dev_info("%s: f0_limit = %d\n", __func__,
@@ -2596,9 +2575,6 @@ static int rtp_osc_cali(struct aw_haptic *aw_haptic)
if (ret < 0) {
aw_dev_err("%s: failed to read %s\n", __func__,
aw_rtp_name[0]);
#ifdef CONFIG_HAPTIC_FEEDBACK_MODULE
(void)oplus_haptic_track_fre_cail(HAPTIC_OSC_CALI_TRACK, aw_haptic->f0, ret, "rtp_osc_cali request_firmware fail");
#endif
return ret;
}
/*aw_haptic add stop,for irq interrupt during calibrate */

View File

@@ -16,10 +16,6 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#include <soc/oplus/system/kernel_fb.h>
#endif
#include "oplus_chg_track.h"
#include "oplus_charger.h"
#include "oplus_gauge.h"
@@ -459,10 +455,6 @@ struct oplus_chg_track {
wait_queue_head_t upload_wq;
struct workqueue_struct *trigger_upload_wq;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
struct kernel_packet_info *dcs_info;
#endif
struct delayed_work upload_info_dwork;
struct mutex dcs_info_lock;
int dwork_retry_cnt;
@@ -522,69 +514,11 @@ static struct dentry *track_debugfs_root;
static DEFINE_MUTEX(debugfs_root_mutex);
static DEFINE_SPINLOCK(adsp_fifo_lock);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_pack_dcs_info(struct oplus_chg_track *chip);
#endif
static int oplus_chg_track_get_charger_type(
struct oplus_chg_chip *chip, struct oplus_chg_track_status *track_status, int type);
static int oplus_chg_track_obtain_wls_break_sub_crux_info(
struct oplus_chg_track *track_chip, char *crux_info);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static struct type_reason_table track_type_reason_table[] = {
{ TRACK_NOTIFY_TYPE_SOC_JUMP, "soc_error" },
{ TRACK_NOTIFY_TYPE_GENERAL_RECORD, "general_record" },
{ TRACK_NOTIFY_TYPE_NO_CHARGING, "no_charging" },
{ TRACK_NOTIFY_TYPE_CHARGING_SLOW, "charge_slow" },
{ TRACK_NOTIFY_TYPE_CHARGING_BREAK, "charge_break" },
{ TRACK_NOTIFY_TYPE_DEVICE_ABNORMAL, "device_abnormal" },
{ TRACK_NOTIFY_TYPE_CHARGING_HOT, "charge_hot" },
};
static struct flag_reason_table track_flag_reason_table[] = {
{ TRACK_NOTIFY_FLAG_UI_SOC_LOAD_JUMP, "UiSoc_LoadSocJump" },
{ TRACK_NOTIFY_FLAG_SOC_JUMP, "SocJump" },
{ TRACK_NOTIFY_FLAG_UI_SOC_JUMP, "UiSocJump" },
{ TRACK_NOTIFY_FLAG_UI_SOC_TO_SOC_JUMP, "UiSoc-SocJump" },
{ TRACK_NOTIFY_FLAG_CHARGER_INFO, "ChargerInfo" },
{ TRACK_NOTIFY_FLAG_UISOC_KEEP_1_T_INFO, "UisocKeep1TInfo" },
{ TRACK_NOTIFY_FLAG_VBATT_TOO_LOW_INFO, "VbattTooLowInfo" },
{ TRACK_NOTIFY_FLAG_USBTEMP_INFO, "UsbTempInfo" },
{ TRACK_NOTIFY_FLAG_VBATT_DIFF_OVER_INFO, "VbattDiffOverInfo" },
{ TRACK_NOTIFY_FLAG_WLS_TRX_INFO, "WlsTrxInfo" },
{ TRACK_NOTIFY_FLAG_NO_CHARGING, "NoCharging" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_TBATT_WARM, "BattTempWarm" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_TBATT_COLD, "BattTempCold" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_NON_STANDARD_PA, "NonStandardAdatpter" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_BATT_CAP_HIGH, "BattCapHighWhenPlugin" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_COOLDOWN, "CoolDownCtlLongTime" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_WLS_SKEW, "WlsSkew" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_VERITY_FAIL, "VerityFail" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_OTHER, "Other" },
{ TRACK_NOTIFY_FLAG_FAST_CHARGING_BREAK, "FastChgBreak" },
{ TRACK_NOTIFY_FLAG_GENERAL_CHARGING_BREAK, "GeneralChgBreak" },
{ TRACK_NOTIFY_FLAG_WLS_CHARGING_BREAK, "WlsChgBreak" },
{ TRACK_NOTIFY_FLAG_WLS_TRX_ABNORMAL, "WlsTrxAbnormal" },
{ TRACK_NOTIFY_FLAG_GPIO_ABNORMAL, "GpioAbnormal"},
{ TRACK_NOTIFY_FLAG_CP_ABNORMAL, "CpAbnormal"},
{ TRACK_NOTIFY_FLAG_PLAT_PMIC_ABNORMAL, "PlatPmicAbnormal"},
{ TRACK_NOTIFY_FLAG_EXTERN_PMIC_ABNORMAL, "ExternPmicAbnormal"},
{ TRACK_NOTIFY_FLAG_GAGUE_ABNORMAL, "GagueAbnormal"},
{ TRACK_NOTIFY_FLAG_DCHG_ABNORMAL, "DchgAbnormal"},
{ TRACK_NOTIFY_FLAG_PARALLEL_UNBALANCE_ABNORMAL, "ParallelUnbalance"},
{ TRACK_NOTIFY_FLAG_MOS_ERROR_ABNORMAL, "MosError"},
{ TRACK_NOTIFY_FLAG_COOL_DOWN_MATCH_ERR, "CooldownMatchErr" },
};
#endif
static struct oplus_chg_track_type base_type_table[] = {
{ POWER_SUPPLY_TYPE_UNKNOWN, TRACK_POWER_MW(2500), "unknow" },
{ POWER_SUPPLY_TYPE_USB, TRACK_POWER_MW(2500), "sdp" },
@@ -2391,39 +2325,6 @@ static int oplus_chg_track_init(struct oplus_chg_track *track_dev)
return ret;
}
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_get_type_tag(int type_reason, char *type_reason_tag)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(track_type_reason_table); i++) {
if (track_type_reason_table[i].type_reason == type_reason) {
strncpy(type_reason_tag,
track_type_reason_table[i].type_reason_tag,
OPLUS_CHG_TRIGGER_REASON_TAG_LEN - 1);
break;
}
}
return i;
}
static int oplus_chg_track_get_flag_tag(int flag_reason, char *flag_reason_tag)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(track_flag_reason_table); i++) {
if (track_flag_reason_table[i].flag_reason == flag_reason) {
strncpy(flag_reason_tag,
track_flag_reason_table[i].flag_reason_tag,
OPLUS_CHG_TRIGGER_REASON_TAG_LEN - 1);
break;
}
}
return i;
}
#endif
static bool oplus_chg_track_trigger_data_is_valid(oplus_chg_track_trigger *pdata)
{
int i;
@@ -2573,10 +2474,6 @@ static int oplus_chg_track_thread(void *data)
pr_err("oplus chg false wakeup, rc=%d\n", rc);
mutex_lock(&chip->trigger_data_lock);
chip->trigger_data_ok = false;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_chg_track_pack_dcs_info(chip);
#endif
chip->dwork_retry_cnt = OPLUS_CHG_TRACK_DWORK_RETRY_CNT;
queue_delayed_work(chip->trigger_upload_wq,
&chip->upload_info_dwork, 0);
@@ -2754,71 +2651,6 @@ static int oplus_chg_track_get_local_time_s(void)
return local_time_s;
}
/*
* track sub version
* 3: default version for chg track
* 3.1: add for solve the problem of incorrect PPS records and power mode record error code
* 3.2: add for solve the problem of adapter_t symbol NULL
* 3.3: break records and mmi_chg and fastchg_to_normal and soc jump optimize
*/
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_pack_dcs_info(struct oplus_chg_track *chip)
{
int ret = 0;
int len;
struct rtc_time tm;
char *log_tag = OPLUS_CHG_TRACK_LOG_TAG;
char *event_id = OPLUS_CHG_TRACK_EVENT_ID;
char *p_data = (char *)(chip->dcs_info);
char type_reason_tag[OPLUS_CHG_TRIGGER_REASON_TAG_LEN] = { 0 };
char flag_reason_tag[OPLUS_CHG_TRIGGER_REASON_TAG_LEN] = { 0 };
memset(p_data, 0x0, sizeof(char) * OPLUS_CHG_TRIGGER_MSG_LEN);
ret += sizeof(struct kernel_packet_info);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
OPLUS_CHG_TRACK_EVENT_ID);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$track_ver@@%s", "3.3");
oplus_chg_track_get_type_tag(chip->trigger_data.type_reason,
type_reason_tag);
oplus_chg_track_get_flag_tag(chip->trigger_data.flag_reason,
flag_reason_tag);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$type_reason@@%s", type_reason_tag);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$flag_reason@@%s", flag_reason_tag);
oplus_chg_track_get_current_time_s(&tm);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$time@@[%04d-%02d-%02d %02d:%02d:%02d]", tm.tm_year,
tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min,
tm.tm_sec);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret, "%s",
chip->trigger_data.crux_info);
len = strlen(&(p_data[sizeof(struct kernel_packet_info)]));
if (len) {
mutex_lock(&chip->dcs_info_lock);
memset(chip->dcs_info, 0x0, sizeof(struct kernel_packet_info));
chip->dcs_info->type = 1;
memcpy(chip->dcs_info->log_tag, log_tag, strlen(log_tag));
memcpy(chip->dcs_info->event_id, event_id, strlen(event_id));
chip->dcs_info->payload_length = len + 1;
mutex_unlock(&chip->dcs_info_lock);
pr_info("%s\n", chip->dcs_info->payload);
return 0;
}
return -EINVAL;
}
#endif
static void oplus_chg_track_upload_info_dwork(struct work_struct *work)
{
int ret = 0;
@@ -2828,13 +2660,6 @@ static void oplus_chg_track_upload_info_dwork(struct work_struct *work)
if (!chip)
return;
mutex_lock(&chip->dcs_info_lock);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
ret = fb_kevent_send_to_user(chip->dcs_info);
#endif
mutex_unlock(&chip->dcs_info_lock);
if (!ret)
complete(&chip->trigger_ack);
else if (chip->dwork_retry_cnt > 0)
@@ -5280,16 +5105,6 @@ static int oplus_chg_track_driver_probe(struct platform_device *pdev)
goto kfifo_err;
}
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
track_dev->dcs_info = (struct kernel_packet_info *)kmalloc(
sizeof(char) * OPLUS_CHG_TRIGGER_MSG_LEN, GFP_KERNEL);
if (!track_dev->dcs_info) {
rc = -ENOMEM;
goto dcs_info_kmalloc_fail;
}
#endif
track_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, track_dev);
@@ -5339,11 +5154,6 @@ adsp_track_kthread_init_err:
track_kthread_init_err:
parse_dt_err:
debugfs_create_fail:
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
kfree(track_dev->dcs_info);
dcs_info_kmalloc_fail:
#endif
kfifo_free(&(track_dev->adsp_fifo));
kfifo_err:
devm_kfree(&pdev->dev, track_dev);
@@ -5358,10 +5168,6 @@ static int oplus_chg_track_driver_remove(struct platform_device *pdev)
if (track_debugfs_root)
debugfs_remove_recursive(track_debugfs_root);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
kfree(track_dev->dcs_info);
#endif
kfifo_free(&(track_dev->adsp_fifo));
devm_kfree(&pdev->dev, track_dev);
return 0;

View File

@@ -16,11 +16,6 @@
#include <linux/fs.h>
#include <linux/module.h>
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#include <soc/oplus/system/kernel_fb.h>
#endif
#include "oplus_vooc.h"
#include "oplus_charger.h"
#include "voocphy/oplus_voocphy.h"
@@ -51,11 +46,6 @@ static int break_flag = -1;
static int mcu_update_flag = -1;
static int gauge_seal_flag = -1;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#define OPLUS_CHG_DEBUG_LOG_TAG "OplusCharger"
#define OPLUS_CHG_DEBUG_EVENT_ID "charge_monitor"
#endif
struct oplus_chg_debug_info oplus_chg_debug_info;
struct oplus_chg_chip *g_debug_oplus_chip = NULL;
@@ -377,106 +367,6 @@ static int oplus_chg_reset_chg_notify_type(void);
static int oplus_chg_chg_batt_capacity_jump_check(struct oplus_chg_chip *chip);
static int oplus_chg_mcu_update_check(struct oplus_chg_chip *chip);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_pack_debug_info(struct oplus_chg_chip *chip)
{
char log_tag[] = OPLUS_CHG_DEBUG_LOG_TAG;
char event_id[] = OPLUS_CHG_DEBUG_EVENT_ID;
int len;
len = strlen(&oplus_chg_debug_msg[sizeof(struct kernel_packet_info)]);
if (len) {
mutex_lock(&oplus_chg_debug_info.dcs_info_lock);
memset(oplus_chg_debug_info.dcs_info, 0x0, sizeof(struct kernel_packet_info));
oplus_chg_debug_info.dcs_info->type = 1;
memcpy(oplus_chg_debug_info.dcs_info->log_tag, log_tag, strlen(log_tag));
memcpy(oplus_chg_debug_info.dcs_info->event_id, event_id, strlen(event_id));
oplus_chg_debug_info.dcs_info->payload_length = len + 1;
if (chg_check_point_debug&OPEN_LOG_BIT) {
chg_err("%s\n", oplus_chg_debug_info.dcs_info->payload);
}
mutex_unlock(&oplus_chg_debug_info.dcs_info_lock);
return 0;
}
return -1;
}
static int oplus_chg_debug_mask_notify_flag(int low, int high)
{
unsigned long long mask = -1;
int bits = sizeof(mask) * 8 - 1;
mask = (mask >> low) << low;
mask = (mask << (bits - high)) >> (bits - high);
mutex_lock(&oplus_chg_debug_info.nflag_lock);
oplus_chg_debug_info.notify_flag &= ~mask;
mutex_unlock(&oplus_chg_debug_info.nflag_lock);
return 0;
}
static void oplus_chg_send_info_dwork(struct work_struct *work)
{
int ret;
mutex_lock(&oplus_chg_debug_info.dcs_info_lock);
ret = fb_kevent_send_to_user(oplus_chg_debug_info.dcs_info);
mutex_unlock(&oplus_chg_debug_info.dcs_info_lock);
if ((ret > 0) && (oplus_chg_debug_info.retry_cnt > 0)) {
queue_delayed_work(oplus_chg_debug_info.oplus_chg_debug_wq,
&oplus_chg_debug_info.send_info_dwork, msecs_to_jiffies(SEND_INFO_DELAY));
}
else {
//soc jump
oplus_chg_debug_mask_notify_flag(0, OPLUS_NOTIFY_CHG_BATT_FULL_NON_100_CAP);
//slow check
if(send_info_flag != SEND_INFO_FLAG_IRQ) {//plug out with mcu error 0x54 do not clear charger slow flag
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_CHG_SLOW_BATT_WARM_TEMP,
OPLUS_NOTIFY_CHG_SLOW_LED_ON_LONG_TIME);
}
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_CHG_SLOW_BATT_NON_AUTH, OPLUS_NOTIFY_SC8571_ERROR);/*ic error*/
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_CHG_SLOW_BATT_NON_AUTH,
OPLUS_NOTIFY_SC85x7_ERROR);/*ic error*/
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_CHG_BATT_RECHG, OPLUS_NOTIFY_CHG_BATT_RECHG);/*add for rechg counts*/
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_WIRELESS_BOOTUP, OPLUS_NOTIFY_WIRELESS_STOP_TX);/*add for wireless chg*/
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_WIRELESS_BOOTUP, OPLUS_NOTIFY_WIRELESS_WIRELESS_CHG_END);/*add for wireless chg*/
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_BCC_ANODE_POTENTIAL_OVER_TIME, OPLUS_NOTIFY_BCC_ANODE_POTENTIAL_OVER_TIME);
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_BCC_CURR_ADJUST_ERR, OPLUS_NOTIFY_BCC_CURR_ADJUST_ERR);
if (oplus_switching_support_parallel_chg() == 1) {
oplus_chg_debug_mask_notify_flag(OPLUS_NOTIFY_PARALLEL_LIMITIC_ERROR, OPLUS_NOTIFY_PARALLEL_FULL_NON_100_ERROR);/*add for parallel chg*/
}
oplus_chg_reset_chg_notify_type();
memset(oplus_chg_debug_info.flag_reason,0,sizeof(oplus_chg_debug_info.flag_reason));
memset(oplus_chg_debug_info.type_reason,0,sizeof(oplus_chg_debug_info.type_reason));
memset(oplus_chg_debug_info.bcc_buf, 0, sizeof(oplus_chg_debug_info.bcc_buf));
memset(oplus_chg_debug_info.sc85x7_error_reason, 0,
sizeof(oplus_chg_debug_info.sc85x7_error_reason));
memset(oplus_chg_debug_info.sc8571_error_reason, 0, sizeof(oplus_chg_debug_info.sc8571_error_reason));
oplus_chg_debug_info.vooc_mcu_error = 0;
if(send_info_flag == SEND_INFO_FLAG_IRQ) {
send_info_flag = 0;
}
break_flag = -1;
mcu_update_flag = -1;
gauge_seal_flag = -1;
if(oplus_chg_get_voocphy_support()) {
oplus_voocphy_clear_dbg_info();
}
oplus_pps_clear_dbg_info();
}
chg_err("retry_cnt: %d\n", oplus_chg_debug_info.retry_cnt);
oplus_chg_debug_info.retry_cnt--;
}
#endif
static int oplus_chg_read_filedata(struct timespec *ts)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
@@ -606,22 +496,11 @@ static void oplus_chg_print_debug_info(struct oplus_chg_chip *chip)
if (oplus_chg_debug_info.notify_type ||
oplus_chg_debug_notify_flag_is_set(OPLUS_NOTIFY_CHARGER_INFO))
{
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
if (delayed_work_pending(&oplus_chg_debug_info.send_info_dwork))
cancel_delayed_work_sync(&oplus_chg_debug_info.send_info_dwork);
mutex_lock(&oplus_chg_debug_info.dcs_info_lock);
#endif
memset(oplus_chg_debug_msg, 0x0, sizeof(oplus_chg_debug_msg));
getnstimeofday(&ts);
rtc_time_to_tm(ts.tv_sec, &tm);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
ret += sizeof(struct kernel_packet_info);
ret += snprintf(&oplus_chg_debug_msg[ret], OPLUS_CHG_DEBUG_MSG_LEN - ret,
OPLUS_CHG_DEBUG_EVENT_ID"$$");
#endif
//add for common
ret += snprintf(&oplus_chg_debug_msg[ret], OPLUS_CHG_DEBUG_MSG_LEN - ret,
"type@@0x%x", oplus_chg_debug_info.notify_type);
@@ -950,26 +829,13 @@ static void oplus_chg_print_debug_info(struct oplus_chg_chip *chip)
ret += snprintf(&oplus_chg_debug_msg[ret], OPLUS_CHG_DEBUG_MSG_LEN - ret, "%s", oplus_chg_debug_info.bcc_buf);
}
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
mutex_unlock(&oplus_chg_debug_info.dcs_info_lock);
chg_err("[feedback] %s\n", &oplus_chg_debug_msg[sizeof(struct kernel_packet_info)]);
if (oplus_chg_debug_info.notify_type ||
oplus_chg_debug_notify_flag_is_set(OPLUS_NOTIFY_CHARGER_INFO)) {
ret = oplus_chg_pack_debug_info(chip);
if (!ret) {
oplus_chg_debug_info.retry_cnt = SEND_INFO_MAX_CNT;
}
}
#else
printk(KERN_ERR "%s\n", oplus_chg_debug_msg);
if (ret > OPLUS_ERROR_LENGTH)
printk(KERN_ERR "debug msg:%s\n", &oplus_chg_debug_msg[ret-OPLUS_ERROR_LENGTH]);
if (chg_check_point_debug&OPEN_LOG_BIT) {
chg_err("[debug test]%s\n", oplus_chg_debug_msg);
}
#endif
oplus_chg_debug_info.real_charger_type = oplus_chg_get_real_charger_type(chip);
}
}
@@ -2883,11 +2749,7 @@ int oplus_chg_debug_info_init(struct oplus_chg_chip *chip)
oplus_chg_debug_info.batt_psy = power_supply_get_by_name("battery");
oplus_chg_debug_info.oplus_chg_debug_wq = create_workqueue("oplus_chg_debug_wq");
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_chg_debug_info.dcs_info = (struct kernel_packet_info *)&oplus_chg_debug_msg[0];
INIT_DELAYED_WORK(&oplus_chg_debug_info.send_info_dwork, oplus_chg_send_info_dwork);
mutex_init(&oplus_chg_debug_info.dcs_info_lock);
#endif
INIT_DELAYED_WORK(&oplus_chg_debug_info.soc_load_dwork, oplus_chg_soc_load_dwork);
oplus_chg_debug_info_parse_dt(chip);

View File

@@ -156,14 +156,6 @@ struct oplus_chg_debug_info {
int rechg_counts;/*add for rechg counts*/
struct workqueue_struct *oplus_chg_debug_wq;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
struct kernel_packet_info *dcs_info;
struct mutex dcs_info_lock;
#define SEND_INFO_DELAY 3000
struct delayed_work send_info_dwork;
#define SEND_INFO_MAX_CNT 5
int retry_cnt;
#endif
char flag_reason[32];
char type_reason[32];
char sc85x7_error_reason[32];

View File

@@ -20,11 +20,6 @@
#include <linux/sched/clock.h>
#include <soc/oplus/system/boot_mode.h>
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#include <soc/oplus/system/kernel_fb.h>
#endif
#include <oplus_chg.h>
#include <oplus_chg_module.h>
#include <oplus_mms_gauge.h>
@@ -382,10 +377,6 @@ struct oplus_chg_track {
wait_queue_head_t upload_wq;
struct workqueue_struct *trigger_upload_wq;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
struct kernel_packet_info *dcs_info;
#endif
struct delayed_work upload_info_dwork;
struct mutex dcs_info_lock;
int dwork_retry_cnt;
@@ -448,10 +439,6 @@ static struct oplus_chg_track *g_track_chip;
static struct dentry *track_debugfs_root;
static DEFINE_MUTEX(debugfs_root_mutex);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_pack_dcs_info(struct oplus_chg_track *chip);
#endif
static int
oplus_chg_track_get_charger_type(struct oplus_monitor *monitor,
struct oplus_chg_track_status *track_status,
@@ -460,58 +447,6 @@ static int oplus_chg_track_obtain_wls_break_sub_crux_info(
struct oplus_chg_track *track_chip, char *crux_info);
static int oplus_chg_track_upload_trigger_data(oplus_chg_track_trigger data);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static struct type_reason_table track_type_reason_table[] = {
{ TRACK_NOTIFY_TYPE_DEFAULT, "default" },
{ TRACK_NOTIFY_TYPE_SOC_JUMP, "soc_error" },
{ TRACK_NOTIFY_TYPE_GENERAL_RECORD, "general_record" },
{ TRACK_NOTIFY_TYPE_NO_CHARGING, "no_charging" },
{ TRACK_NOTIFY_TYPE_CHARGING_SLOW, "charge_slow" },
{ TRACK_NOTIFY_TYPE_CHARGING_BREAK, "charge_break" },
{ TRACK_NOTIFY_TYPE_DEVICE_ABNORMAL, "device_abnormal" },
{ TRACK_NOTIFY_TYPE_IC_ERROR, "ic_error" },
};
static struct flag_reason_table track_flag_reason_table[] = {
{ TRACK_NOTIFY_FLAG_DEFAULT, "default" },
{ TRACK_NOTIFY_FLAG_UI_SOC_LOAD_JUMP, "UiSoc_LoadSocJump" },
{ TRACK_NOTIFY_FLAG_SOC_JUMP, "SocJump" },
{ TRACK_NOTIFY_FLAG_UI_SOC_JUMP, "UiSocJump" },
{ TRACK_NOTIFY_FLAG_UI_SOC_TO_SOC_JUMP, "UiSoc-SocJump" },
{ TRACK_NOTIFY_FLAG_CHARGER_INFO, "ChargerInfo" },
{ TRACK_NOTIFY_FLAG_UISOC_KEEP_1_T_INFO, "UisocKeep1TInfo" },
{ TRACK_NOTIFY_FLAG_VBATT_TOO_LOW_INFO, "VbattTooLowInfo" },
{ TRACK_NOTIFY_FLAG_USBTEMP_INFO, "UsbTempInfo" },
{ TRACK_NOTIFY_FLAG_VBATT_DIFF_OVER_INFO, "VbattDiffOverInfo" },
{ TRACK_NOTIFY_FLAG_WLS_TRX_INFO, "WlsTrxInfo" },
{ TRACK_NOTIFY_FLAG_NO_CHARGING, "NoCharging" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_TBATT_WARM, "BattTempWarm" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_TBATT_COLD, "BattTempCold" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_NON_STANDARD_PA, "NonStandardAdatpter" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_BATT_CAP_HIGH, "BattCapHighWhenPlugin" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_COOLDOWN, "CoolDownCtlLongTime" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_WLS_SKEW, "WlsSkew" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_WLS_SKEW, "VerityFail" },
{ TRACK_NOTIFY_FLAG_CHG_SLOW_OTHER, "Other" },
{ TRACK_NOTIFY_FLAG_FAST_CHARGING_BREAK, "FastChgBreak" },
{ TRACK_NOTIFY_FLAG_GENERAL_CHARGING_BREAK, "GeneralChgBreak" },
{ TRACK_NOTIFY_FLAG_WLS_CHARGING_BREAK, "WlsChgBreak" },
{ TRACK_NOTIFY_FLAG_WLS_TRX_ABNORMAL, "WlsTrxAbnormal" },
{ TRACK_NOTIFY_FLAG_GPIO_ABNORMAL, "GpioAbnormal" },
{ TRACK_NOTIFY_FLAG_CP_ABNORMAL, "CpAbnormal" },
{ TRACK_NOTIFY_FLAG_PLAT_PMIC_ABNORMAL, "PlatPmicAbnormal" },
{ TRACK_NOTIFY_FLAG_EXTERN_PMIC_ABNORMAL, "ExternPmicAbnormal" },
{ TRACK_NOTIFY_FLAG_GAGUE_ABNORMAL, "GagueAbnormal" },
{ TRACK_NOTIFY_FLAG_DCHG_ABNORMAL, "DchgAbnormal" },
};
#endif
static struct oplus_chg_track_type wired_type_table[] = {
{ OPLUS_CHG_USB_TYPE_UNKNOWN, TRACK_POWER_2500MW, "unknow" },
{ OPLUS_CHG_USB_TYPE_SDP, TRACK_POWER_2500MW, "sdp" },
@@ -1822,39 +1757,6 @@ static int oplus_chg_track_init(struct oplus_chg_track *track_dev)
return ret;
}
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_get_type_tag(int type_reason, char *type_reason_tag)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(track_type_reason_table); i++) {
if (track_type_reason_table[i].type_reason == type_reason) {
strncpy(type_reason_tag,
track_type_reason_table[i].type_reason_tag,
OPLUS_CHG_TRIGGER_REASON_TAG_LEN - 1);
break;
}
}
return i;
}
static int oplus_chg_track_get_flag_tag(int flag_reason, char *flag_reason_tag)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(track_flag_reason_table); i++) {
if (track_flag_reason_table[i].flag_reason == flag_reason) {
strncpy(flag_reason_tag,
track_flag_reason_table[i].flag_reason_tag,
OPLUS_CHG_TRIGGER_REASON_TAG_LEN - 1);
break;
}
}
return i;
}
#endif
static bool
oplus_chg_track_trigger_data_is_valid(oplus_chg_track_trigger *pdata)
{
@@ -2003,10 +1905,6 @@ static int oplus_chg_track_thread(void *data)
chg_err("oplus chg false wakeup, rc=%d\n", rc);
mutex_lock(&chip->trigger_data_lock);
chip->trigger_data_ok = false;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_chg_track_pack_dcs_info(chip);
#endif
chip->dwork_retry_cnt = OPLUS_CHG_TRACK_DWORK_RETRY_CNT;
queue_delayed_work(chip->trigger_upload_wq,
&chip->upload_info_dwork, 0);
@@ -2059,63 +1957,6 @@ static int oplus_chg_track_get_local_time_s(void)
*/
#define TRACK_VERSION "3.1"
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
static int oplus_chg_track_pack_dcs_info(struct oplus_chg_track *chip)
{
int ret = 0;
int len;
struct rtc_time tm;
char log_tag[] = OPLUS_CHG_TRACK_LOG_TAG;
char event_id[] = OPLUS_CHG_TRACK_EVENT_ID;
char *p_data = (char *)(chip->dcs_info);
char type_reason_tag[OPLUS_CHG_TRIGGER_REASON_TAG_LEN] = { 0 };
char flag_reason_tag[OPLUS_CHG_TRIGGER_REASON_TAG_LEN] = { 0 };
memset(p_data, 0x0, sizeof(char) * OPLUS_CHG_TRIGGER_MSG_LEN);
ret += sizeof(struct kernel_packet_info);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
OPLUS_CHG_TRACK_EVENT_ID);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$track_ver@@%s", TRACK_VERSION);
oplus_chg_track_get_type_tag(chip->trigger_data.type_reason,
type_reason_tag);
oplus_chg_track_get_flag_tag(chip->trigger_data.flag_reason,
flag_reason_tag);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$type_reason@@%s", type_reason_tag);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$flag_reason@@%s", flag_reason_tag);
oplus_chg_track_get_current_time_s(&tm);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret,
"$$time@@[%04d-%02d-%02d %02d:%02d:%02d]", tm.tm_year,
tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min,
tm.tm_sec);
ret += snprintf(&p_data[ret], OPLUS_CHG_TRIGGER_MSG_LEN - ret, "%s",
chip->trigger_data.crux_info);
len = strlen(&(p_data[sizeof(struct kernel_packet_info)]));
if (len) {
mutex_lock(&chip->dcs_info_lock);
memset(chip->dcs_info, 0x0, sizeof(struct kernel_packet_info));
chip->dcs_info->type = 1;
memcpy(chip->dcs_info->log_tag, log_tag, strlen(log_tag));
memcpy(chip->dcs_info->event_id, event_id, strlen(event_id));
chip->dcs_info->payload_length = len + 1;
mutex_unlock(&chip->dcs_info_lock);
chg_info("%s\n", chip->dcs_info->payload);
return 0;
}
return -1;
}
#endif
static void oplus_chg_track_upload_info_dwork(struct work_struct *work)
{
int ret = 0;
@@ -2126,12 +1967,6 @@ static void oplus_chg_track_upload_info_dwork(struct work_struct *work)
if (!chip)
return;
mutex_lock(&chip->dcs_info_lock);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
ret = fb_kevent_send_to_user(chip->dcs_info);
#endif
mutex_unlock(&chip->dcs_info_lock);
if (!ret)
complete(&chip->trigger_ack);
else if (chip->dwork_retry_cnt > 0)
@@ -4450,16 +4285,6 @@ int oplus_chg_track_driver_init(struct oplus_monitor *monitor)
}
monitor->track = track_dev;
track_dev->monitor = monitor;
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
track_dev->dcs_info = (struct kernel_packet_info *)kmalloc(
sizeof(char) * OPLUS_CHG_TRIGGER_MSG_LEN, GFP_KERNEL);
if (track_dev->dcs_info == NULL) {
rc = -ENOMEM;
goto dcs_info_kmalloc_fail;
}
#endif
track_dev->dev = monitor->dev;
rc = oplus_chg_track_debugfs_init(track_dev);
@@ -4502,11 +4327,6 @@ parse_dt_err:
if (track_debugfs_root)
debugfs_remove_recursive(track_debugfs_root);
debugfs_create_fail:
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
kfree(track_dev->dcs_info);
dcs_info_kmalloc_fail:
#endif
devm_kfree(monitor->dev, track_dev);
monitor->track = NULL;
return rc;
@@ -4531,10 +4351,7 @@ int oplus_chg_track_driver_exit(struct oplus_monitor *monitor)
if (track_debugfs_root)
debugfs_remove_recursive(track_debugfs_root);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || \
defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
kfree(track_dev->dcs_info);
#endif
devm_kfree(monitor->dev, track_dev);
return 0;
}

View File

@@ -24,9 +24,6 @@
#include <linux/version.h>
#include "sensor_feedback.h"
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
#include <soc/oplus/system/kernel_fb.h>
#endif
#define ALIGN4(s) ((sizeof(s) + 3)&(~0x3))
@@ -345,9 +342,6 @@ static void cal_subsystem_sleep_ratio(struct subsystem_desc *subsystem_desc) {
adsp_sleep_ratio_fied,
subsystem_desc[index].subsys_name,
subsys_sleep_ratio);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_kevent_fb(FB_SENSOR, SENSOR_POWER_TYPE, payload);
#endif
}
}
}
@@ -439,9 +433,6 @@ static ssize_t hal_info_store(struct device *dev,
strbuf);
pr_info("payload =%s\n", payload);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_kevent_fb(FB_SENSOR, g_fb_conf[index].fb_event_id, payload);
#endif
return count;
}
@@ -714,10 +705,6 @@ static int parse_shr_info(struct sensor_fb_cxt *sensor_fb_cxt)
detail_buff,
sensor_fb_cxt->fb_smem.event[count].name);
pr_info("payload1 =%s\n", payload);
#if defined(CONFIG_OPLUS_FEATURE_FEEDBACK) || defined(CONFIG_OPLUS_FEATURE_FEEDBACK_MODULE)
oplus_kevent_fb(FB_SENSOR, g_fb_conf[index].fb_event_id, payload);
pr_info("send oplus kevent fb\n");
#endif
}
return ret;

View File

@@ -36,7 +36,6 @@ config OPLUS_FEATURE_DETAILHEAD
define this config to add cpu number and current id and current comm to kmsg
source "drivers/soc/oplus/system/feedback/Kconfig"
source "drivers/soc/oplus/system/shutdown_detect/Kconfig"
source "drivers/soc/oplus/system/oplus_project/Kconfig"
source "drivers/soc/oplus/system/hung_task_enhance/Kconfig"
@@ -54,10 +53,6 @@ source "drivers/soc/oplus/system/qcom_pmicwd/Kconfig"
source "drivers/soc/oplus/system/dump_reason/Kconfig"
#endif /* OPLUS_FEATURE_DUMP_REASON */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
source "drivers/soc/oplus/system/oplus_mm_fb/Kconfig"
#endif /* OPLUS_FEATURE_MM_FEEDBACK */
#ifdef OPLUS_FEATURE_QCOM_WATCHDOG
source "drivers/soc/oplus/system/qcom_watchdog/Kconfig"
#endif /* OPLUS_FEATURE_QCOM_WATCHDOG */

View File

@@ -2,7 +2,6 @@
# Copyright (C) 2018-2020 Oplus. All rights reserved.
obj-y += platform.o
obj-$(CONFIG_OPLUS_FEATURE_FEEDBACK) += feedback/
obj-$(CONFIG_OPLUS_FEATURE_SHUTDOWN_DETECT) += shutdown_detect/
obj-$(CONFIG_OPLUS_FEATURE_OPROJECT) += oplus_project/
obj-$(CONFIG_OPLUS_FEATURE_HUNG_TASK_ENHANCE) += hung_task_enhance/
@@ -23,10 +22,6 @@ endif
obj-$(CONFIG_OPLUS_FEATURE_QCOM_PMICWD) += qcom_pmicwd/
#endif /* OPLUS_FEATURE_QCOM_PMICWD */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
obj-$(CONFIG_OPLUS_FEATURE_MM_FEEDBACK) += oplus_mm_fb/
#endif /* OPLUS_FEATURE_MM_FEEDBACK */
#ifdef OPLUS_FEATURE_QCOM_WATCHDOG
obj-$(CONFIG_OPLUS_FEATURE_QCOM_WATCHDOG) += qcom_watchdog/
#endif /* OPLUS_FEATURE_QCOM_WATCHDOG */

View File

@@ -1,8 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (C) 2018-2020 Oplus. All rights reserved.
config OPLUS_FEATURE_FEEDBACK
tristate "Oplus system feedback"
default n
depends on OPLUS_SYSTEM_KERNEL
help
define this config to init oplus system feedback.

View File

@@ -1,4 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (C) 2018-2020 Oplus. All rights reserved.
obj-$(CONFIG_OPLUS_FEATURE_FEEDBACK) += kernel_fb.o

View File

@@ -1,601 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
/***************************************************************
** File : kerbel_fb.c
** Description : BSP kevent fb data
** Version : 1.0
******************************************************************/
#define pr_fmt(fmt) "<kernel_fb>" fmt
#include <linux/err.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <soc/oplus/system/kernel_fb.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <linux/vmalloc.h>
#include <linux/version.h>
#include <linux/uaccess.h>
#include <net/genetlink.h>
#include <linux/time64.h>
#include <linux/random.h>
#include "oplus_fb_guard_netlink.h"
#define MAX_LOG (31)
#define MAX_ID (19)
#define LIST_MAX (50)
#define DELAY_REPORT_US (30*1000*1000)
#define MAX_BUF_LEN (2048)
#define CAUSENAME_SIZE 128
struct packets_pool {
struct list_head packets;
struct task_struct *flush_task;
spinlock_t wlock;
bool wlock_init;
};
struct packet {
struct kernel_packet_info *pkt;
struct list_head list;
int retry;
};
static struct packets_pool *g_pkts = NULL;
static char *const _tag[FB_MAX_TYPE + 1] = {
"fb_stability",
"fb_fs",
"fb_storage",
"PSW_BSP_SENSOR",
"fb_boot",
};
static char fid[CAUSENAME_SIZE]={""};
static volatile unsigned int kevent_pid;
#define OPLUS_KEVENT_MAX_UP_PALOAD_LEN 2048
#define OPLUS_KEVENT_TEST_TAG "test_event"
#define OPLUS_KEVENT_TEST_ID "test_check"
static int fb_keventupload_sendpid_cmd(struct sk_buff *skb,
struct genl_info *info)
{
struct nlattr *na = NULL;
unsigned int *p_data = NULL;
pr_info(" kernel recv cmd \n");
if (info->attrs[FB_GUARD_CMD_ATTR_MSG]) {
na = info->attrs[FB_GUARD_CMD_ATTR_MSG];
/*PRINT_FORMAT(nla_data(na), nla_len(na));*/
pr_info(" nla_len(na) is %d \n", nla_len(na));
p_data = nla_data(na);
kevent_pid = *p_data;
pr_info(" kevent_pid is 0x%x \n", kevent_pid);
}
return 0;
}
static int fb_keventupload_test_upload(struct sk_buff *skb,
struct genl_info *info)
{
int ret = 0;
struct nlattr *na = NULL;
struct msg_test_upload *p_test_upload = NULL;
struct kernel_packet_info *p_dcs_event = NULL;
size_t data_len = 0;
pr_info(" fb_keventupload_test_upload \n");
if (info->attrs[FB_GUARD_CMD_ATTR_OPT]) {
na = info->attrs[FB_GUARD_CMD_ATTR_OPT];
/*PRINT_FORMAT(nla_data(na), nla_len(na));*/
pr_info(" nla_len(na) is %d \n", nla_len(na));
p_test_upload = (struct msg_test_upload *)nla_data(na);
kevent_pid = p_test_upload->pro_pid;
pr_info(" p_test_upload->pro_pid is %u, p_test_upload->val is %u, \n",
p_test_upload->pro_pid, p_test_upload->val);
if ((p_test_upload->val) > OPLUS_KEVENT_MAX_UP_PALOAD_LEN) {
pr_err("[ERROR]:p_test_upload->val too long \n", p_test_upload->val);
return -1;
}
data_len = p_test_upload->val + sizeof(struct kernel_packet_info);
pr_info(" data_len is %u\n", data_len);
p_dcs_event = (struct kernel_packet_info *)kmalloc(data_len, GFP_ATOMIC);
if (NULL == p_dcs_event) {
pr_err("[ERROR]:kmalloc for p_dcs_event err\n");
return -1;
}
pr_info(" p_dcs_event kmalloc ok .\n");
memset((unsigned char *)p_dcs_event, 0x00, data_len);
p_dcs_event->type = 1;
strncpy(p_dcs_event->log_tag, OPLUS_KEVENT_TEST_TAG,
sizeof(p_dcs_event->log_tag));
strncpy(p_dcs_event->event_id, OPLUS_KEVENT_TEST_ID,
sizeof(p_dcs_event->event_id));
p_dcs_event->payload_length = p_test_upload->val;
memset(p_dcs_event->payload, 0xFF, p_test_upload->val);
ret = fb_kevent_send_to_user(p_dcs_event);
if (ret) {
pr_err("[ERROR]:fb_kevent_send_to_user err, ret is %d \n", ret);
}
kfree(p_dcs_event);
}
return 0;
}
static const struct genl_ops oplus_fb_kevent_upload_ops[] = {
{
.cmd = FB_GUARD_CMD_GENL_SENDPID,
.doit = fb_keventupload_sendpid_cmd,
/*.policy = taskstats_cmd_get_policy,*/
/*.flags = GENL_ADMIN_PERM,*/
},
{
.cmd = FB_GUARD_CMD_GENL_TEST_UPLOAD,
.doit = fb_keventupload_test_upload,
/*.dumpit = taskstats2_foreach,*/
/*.policy = taskstats_cmd_get_policy,*/
},
};
static struct genl_family oplus_fb_kevent_family __ro_after_init = {
.name = OPLUS_FB_GUARD_PROTOCAL_NAME,
.version = OPLUS_FB_GUARD_GENL_VERSION,
.maxattr = FB_GUARD_CMD_ATTR_MAX,
.module = THIS_MODULE,
.ops = oplus_fb_kevent_upload_ops,
.n_ops = ARRAY_SIZE(oplus_fb_kevent_upload_ops),
};
static inline int genl_msg_prepare_usr_msg(unsigned char cmd, size_t size,
pid_t pid, struct sk_buff **skbp)
{
struct sk_buff *skb;
/* create a new netlink msg */
skb = genlmsg_new(size, GFP_KERNEL);
if (skb == NULL) {
return -ENOMEM;
}
/* Add a new netlink message to an skb */
genlmsg_put(skb, pid, 0, &oplus_fb_kevent_family, 0, cmd);
*skbp = skb;
return 0;
}
static inline int genl_msg_mk_usr_msg(struct sk_buff *skb, int type, void *data,
int len)
{
int ret;
/* add a netlink attribute to a socket buffer */
if ((ret = nla_put(skb, type, len, data)) != 0) {
return ret;
}
return 0;
}
int fb_kevent_send_to_user(struct kernel_packet_info *userinfo)
{
int ret = 0;
struct sk_buff *skbuff = NULL;
void *head = NULL;
size_t data_len = 0;
/*max_len */
pr_info(" fb_kevent_send_to_user\n");
if (userinfo->payload_length >= OPLUS_KEVENT_MAX_UP_PALOAD_LEN) {
pr_err("[ERROR]:fb_kevent_send_to_user: payload_length out of range\n");
ret = -1;
return ret;
}
data_len = userinfo->payload_length + sizeof(struct kernel_packet_info);
pr_info(" data_len is %u\n", data_len);
ret = genl_msg_prepare_usr_msg(FB_GUARD_CMD_GENL_UPLOAD, data_len, kevent_pid,
&skbuff);
if (ret) {
pr_err("[ERROR]:genl_msg_prepare_usr_msg err, ret is %d \n");
return ret;
}
ret = genl_msg_mk_usr_msg(skbuff, FB_GUARD_CMD_ATTR_MSG, userinfo, data_len);
if (ret) {
kfree_skb(skbuff);
return ret;
}
head = genlmsg_data(nlmsg_data(nlmsg_hdr(skbuff)));
genlmsg_end(skbuff, head);
ret = genlmsg_unicast(&init_net, skbuff, kevent_pid);
if (ret < 0) {
return ret;
}
return 0;
}
EXPORT_SYMBOL(fb_kevent_send_to_user);
/*
int kevent_send_to_user(struct kernel_packet_info *userinfo)
{
return fb_kevent_send_to_user(userinfo);
}*/
static struct packet * package_alloc(
fb_tag tag_id, const char *event_id, unsigned char *payload)
{
struct packet *packet;
struct kernel_packet_info *pkt;
char *tmp = payload;
if (tag_id > FB_MAX_TYPE || !event_id || !payload || !_tag[tag_id]) {
return NULL;
}
packet = (struct packet *)kmalloc(sizeof(struct packet), GFP_ATOMIC);
if (!packet) {
return NULL;
}
/*presplit payload, '\n' is not allowed*/
for(;*tmp != '\0'; tmp++) {
if (*tmp == '\n') {
*tmp = '\0';
break;
}
}
pkt = (struct kernel_packet_info *)
kzalloc(sizeof(struct kernel_packet_info) + strlen(payload) + 1, GFP_ATOMIC);
if (!pkt) {
kfree(packet);
return NULL;
}
packet->pkt = pkt;
packet->retry = 4; /* retry 4 times at most*/
pkt->type = 1; /*means only string is available*/
memcpy(pkt->log_tag, _tag[tag_id], strlen(_tag[tag_id]) > MAX_LOG?MAX_LOG:strlen(_tag[tag_id]));
memcpy(pkt->event_id, event_id, strlen(event_id) > MAX_ID?MAX_ID:strlen(event_id));
pkt->payload_length = strlen(payload) + 1;
memcpy(pkt->payload, payload, strlen(payload));
return packet;
}
static void package_release(struct packet *packet)
{
if (packet) {
kfree(packet->pkt);
kfree(packet);
}
}
int oplus_kevent_fb(fb_tag tag_id, const char *event_id, unsigned char *payload)
{
struct packet *packet;
unsigned long flags;
/*ignore before wlock init*/
if (!g_pkts->wlock_init) {
return -ENODEV;
}
packet = package_alloc(tag_id, event_id, payload);
if (!packet) {
return -ENODEV;
}
spin_lock_irqsave(&g_pkts->wlock, flags);
list_add(&packet->list, &g_pkts->packets);
spin_unlock_irqrestore(&g_pkts->wlock, flags);
wake_up_process(g_pkts->flush_task);
return 0;
}
EXPORT_SYMBOL(oplus_kevent_fb);
static unsigned int BKDRHash(char *str, unsigned int len)
{
unsigned int seed = 131;
/* 31 131 1313 13131 131313 etc.. */
unsigned int hash = 0;
unsigned int i = 0;
if (str == NULL) {
return 0;
}
for(i = 0; i < len; str++, i++) {
hash = (hash * seed) + (*str);
}
return hash;
}
int oplus_kevent_fb_str(fb_tag tag_id, const char *event_id, unsigned char *str)
{
unsigned char payload[1024] = {0x00};
unsigned int hashid = 0;
int ret = 0;
char strHashSource[CAUSENAME_SIZE] = {0x00};
/*
unsigned long rdm = 0;
rdm = get_random_u64();
snprintf(strHashSource, CAUSENAME_SIZE, "%s %lu", str, rdm);
*/
snprintf(strHashSource, CAUSENAME_SIZE, "%s", str);
hashid = BKDRHash(strHashSource, strlen(strHashSource));
/*
memset(fid, 0 , CAUSENAME_SIZE);
snprintf(fid, CAUSENAME_SIZE, "%u", hashid);
*/
ret = snprintf(payload, sizeof(payload),
"NULL$$EventField@@%u$$FieldData@@%s$$detailData@@%s", hashid, str,
_tag[tag_id]);
pr_err("%s, payload= %s, ret=%d\n", __func__, payload, ret);
return oplus_kevent_fb(tag_id, event_id, payload);
}
EXPORT_SYMBOL(oplus_kevent_fb_str);
/*thread to deal with the buffer list*/
static int fb_flush_thread(void *arg)
{
struct packets_pool *pkts_pool = (struct packets_pool *)arg;
struct packet *tmp, *s;
unsigned long flags;
struct list_head list_tmp;
while(!kthread_should_stop()) {
if (list_empty(&pkts_pool->packets)) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
}
set_current_state(TASK_RUNNING);
spin_lock_irqsave(&pkts_pool->wlock, flags);
INIT_LIST_HEAD(&list_tmp);
list_splice_init(&pkts_pool->packets, &list_tmp);
spin_unlock_irqrestore(&pkts_pool->wlock, flags);
list_for_each_entry_safe(s, tmp, &list_tmp, list) {
if (s->pkt) {
if (fb_kevent_send_to_user(s->pkt) && s->retry) {
pr_debug("failed to send feedback %s\n", s->pkt->log_tag);
s->retry--;
spin_lock_irqsave(&pkts_pool->wlock, flags);
list_add(&s->list, &pkts_pool->packets);
spin_unlock_irqrestore(&pkts_pool->wlock, flags);
} else {
package_release(s);
}
msleep(20);
}
}
}
return 0;
}
/*
* @format: tag_id:event_id:payload
*/
static ssize_t kernel_fb_write(struct file *file,
const char __user *buf,
size_t count,
loff_t *lo)
{
char *r_buf;
int tag_id = 0;
char event_id[MAX_ID] = {0};
int idx1 = 0, idx2 = 0;
int len;
r_buf = (char *)kzalloc(MAX_BUF_LEN, GFP_KERNEL);
if (!r_buf) {
return count;
}
if (copy_from_user(r_buf, buf, MAX_BUF_LEN > count?count:MAX_BUF_LEN)) {
goto exit;
}
r_buf[MAX_BUF_LEN - 1] ='\0'; /*make sure last bype is eof*/
len = strlen(r_buf);
tag_id = r_buf[0] - '0';
if (tag_id > FB_MAX_TYPE || tag_id < 0) {
goto exit;
}
while(idx1 < len) {
if (r_buf[idx1++] == ':') {
idx2 = idx1;
while (idx2 < len) {
if (r_buf[idx2++] == ':') {
break;
}
}
break;
}
}
if (idx1 == len || idx2 == len) {
goto exit;
}
memcpy(event_id, &r_buf[idx1], idx2-idx1-1 > MAX_ID?MAX_ID: idx2-idx1-1);
event_id[MAX_ID - 1] = '\0';
oplus_kevent_fb(tag_id, event_id, r_buf + idx2);
exit:
kfree(r_buf);
return count;
}
static ssize_t kernel_fb_read(struct file *file,
char __user *buf,
size_t count,
loff_t *ppos)
{
return count;
}
static const struct file_operations kern_fb_fops = {
.write = kernel_fb_write,
.read = kernel_fb_read,
.open = simple_open,
.owner = THIS_MODULE,
};
static ssize_t crash_cause_read(struct file *file,
char __user *buf,
size_t count,
loff_t *off)
{
char page[512] = {0x00};
int len = 0;
len = snprintf(page, sizeof(page), "%s", fid);
len = simple_read_from_buffer(buf, count, off, page, strlen(page));
return len;
}
static const struct file_operations crash_cause_fops = {
.read = crash_cause_read,
.open = simple_open,
.owner = THIS_MODULE,
};
static int __init kernel_fb_init(void)
{
struct proc_dir_entry *d_entry = NULL;
int ret = 0;
pr_err("%s\n", __func__);
g_pkts = (struct packets_pool *)kzalloc(sizeof(struct packets_pool),
GFP_KERNEL);
if (!g_pkts) {
ret = -ENOMEM;
goto failed_kzalloc;
}
/*register gen_link family*/
ret = genl_register_family(&oplus_fb_kevent_family);
if (ret) {
pr_err("failed genl_register_family");
goto failed_genl_register_family;
}
INIT_LIST_HEAD(&g_pkts->packets);
spin_lock_init(&g_pkts->wlock);
g_pkts->flush_task = kthread_create(fb_flush_thread, g_pkts, "fb_flush");
if (!g_pkts->flush_task) {
pr_err("failed to kthread_create fb_flush\n");
ret = -ENODEV;
goto failed_kthread_create;
}
g_pkts->wlock_init = true;
d_entry = proc_create_data("kern_fb", 0664, NULL, &kern_fb_fops, NULL);
if (!d_entry) {
pr_err("failed to create kern_fb node\n");
ret = -ENODEV;
goto failed_proc_create_data;
}
d_entry = proc_create_data("crash_cause", 0664, NULL, &crash_cause_fops, NULL);
if (!d_entry) {
pr_err("failed to create crash_cause node\n");
ret = -ENODEV;
goto failed_proc_create_data;
}
pr_info("kernel_fb_init probe ok\n");
return 0;
failed_proc_create_data:
failed_kthread_create:
genl_unregister_family(&oplus_fb_kevent_family);
failed_genl_register_family:
kfree(g_pkts->flush_task);
failed_kzalloc:
return ret;
}
static void __exit kernel_fb_exit(void)
{
genl_unregister_family(&oplus_fb_kevent_family);
kfree(g_pkts->flush_task);
return;
}
/*core_initcall(kernel_fb_init);*/
module_init(kernel_fb_init);
module_exit(kernel_fb_exit);
MODULE_LICENSE("GPL v2");

View File

@@ -1,64 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/**************************************************************
* Copyright (c) 2008- 2030 OPLUS Mobile communication Corp.ltd All rights reserved.
*
* File : oplus_feedback_guard_netlink.h
* Description: For oplus_feedback_guard_netlink
* Version : 1.0
* Date : 2020-11-24
* Author :
* TAG :
****************************************************************/
#ifndef _OPLUS_FB_GUARD_NETLINK_H
#define _OPLUS_FB_GUARD_NETLINK_H
#define OPLUS_FB_GUARD_TEST_NETLINK_CMD_MIN 0
#define OPLUS_FB_GUARD_TEST_NETLINK_SEND_PID 1
#define OPLUS_FB_GUARD_TEST_NETLINK_RECEV 2
#define OPLUS_FB_GUARD_TEST_NETLINK_CMD_MAX 3
#define OPLUS_FB_GUARD_MSG_TO_KERNEL_BUF_LEN 256
#define OPLUS_FB_GUARD_MSG_FROM_KERNEL_BUF_LEN (2048 + 128)
#define OPLUS_FB_GUARD_PROTOCAL_NAME "fb_guard"
#define OPLUS_FB_GUARD_GENL_VERSION 0x01
#define OPLUS_FB_GUARD_PROTOCAL_NAME_MAX_LEN 100
enum {
FB_GUARD_CMD_ATTR_UNSPEC = 0,
FB_GUARD_CMD_ATTR_MSG,
FB_GUARD_CMD_ATTR_OPT,
__FB_GUARD_CMD_ATTR_MAX,
};
#define FB_GUARD_CMD_ATTR_MAX (__FB_GUARD_CMD_ATTR_MAX - 1)
enum {
FB_GUARD_CMD_GENL_UNSPEC = 0,
FB_GUARD_CMD_GENL_SENDPID,
FB_GUARD_CMD_GENL_UPLOAD,
FB_GUARD_CMD_GENL_TEST_UPLOAD,
};
struct msg_to_kernel {
struct nlmsghdr n_hd;
struct genlmsghdr g_hd;
char buf[OPLUS_FB_GUARD_MSG_TO_KERNEL_BUF_LEN];
};
struct msg_from_kernel {
struct nlmsghdr n_hd;
struct genlmsghdr g_hd;
char buf[OPLUS_FB_GUARD_MSG_FROM_KERNEL_BUF_LEN];
};
struct msg_test_upload {
unsigned int pro_pid;
unsigned int val;
};
int oplus_fb_guard_test_netlink(int cmd, unsigned int val);
#endif

View File

@@ -1,40 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#ifndef __KERNEL_FEEDBACK_H
#define __KERNEL_FEEDBACK_H
typedef enum {
FB_STABILITY = 0,
FB_FS,
FB_STORAGE,
FB_SENSOR,
FB_BOOT,
FB_MAX_TYPE = FB_BOOT,
} fb_tag;
#define FB_STABILITY_ID_CRASH "202007272030"
#define FB_SENSOR_ID_CRASH "10004"
#define FB_SENSOR_ID_QMI "202007272041"
struct kernel_packet_info
{
int type; /* 0:root,1:only string,other number represent other type */
char log_tag[32]; /* logTag */
char event_id[20]; /*eventID */
size_t payload_length; /* Length of packet data */
unsigned char payload[0]; /* Optional packet data */
}__attribute__((packed));
int oplus_kevent_fb(fb_tag tag_id, const char *event_id, unsigned char *payload);
int oplus_kevent_fb_str(fb_tag tag_id, const char *event_id, unsigned char *str);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int fb_kevent_send_to_user(struct kernel_packet_info *userinfo);
#pragma GCC diagnostic pop
#endif

View File

@@ -1,105 +0,0 @@
/***************************************************************
** Copyright (C), 2018, OPLUS Mobile Comm Corp., Ltd
** File : oplus_mm_kevent_fb.h
** Description : MM kevent fb data
** Version : 1.0
** Date : 2018/12/03
**
** ------------------------------- Revision History: -----------
** <author> <data> <version > <desc>
** Guo.Ling 2018/12/03 1.0 Build this moudle
** LiPing-M 2019/01/29 1.1 Add SMMU for QCOM
******************************************************************/
#ifndef _OPLUS_MM_KEVENT_FB_
#define _OPLUS_MM_KEVENT_FB_
#define MAX_PAYLOAD_DATASIZE (512)
#define MM_KEVENT_MAX_PAYLOAD_SIZE MAX_PAYLOAD_DATASIZE
#define MAX_FUNC_LINE_SIZE (128)
enum {
MM_FB_KEY_RATELIMIT_NONE = 0,
MM_FB_KEY_RATELIMIT_1MIN = 60 * 1000,
MM_FB_KEY_RATELIMIT_5MIN = 60 * 5 * 1000,
MM_FB_KEY_RATELIMIT_30MIN = 60 * 30 * 1000,
MM_FB_KEY_RATELIMIT_1H = MM_FB_KEY_RATELIMIT_30MIN * 2,
MM_FB_KEY_RATELIMIT_1DAY = MM_FB_KEY_RATELIMIT_1H * 24,
};
#define FEEDBACK_DELAY_60S 60
#define OPLUS_FB_ADSP_CRASH_RATELIMIT (60 * 5 * 1000) /*ms, for mtk*/
enum OPLUS_MM_DIRVER_FB_EVENT_MODULE {
OPLUS_MM_DIRVER_FB_EVENT_DISPLAY = 0,
OPLUS_MM_DIRVER_FB_EVENT_AUDIO
};
/*------- multimedia bigdata feedback event id, start ------------ */
#define OPLUS_AUDIO_EVENTID_ADSP_CRASH (10001)
#define OPLUS_AUDIO_EVENTID_HEADSET_DET (10009)
#define OPLUS_AUDIO_EVENTID_ADSP_RECOVERY_FAIL (10045)
#define OPLUS_DISPLAY_EVENTID_DRIVER_ERR (12002)
#define OPLUS_DISPLAY_EVENTID_GPU_FAULT (12005)
/*this id just for test or debug */
#define OPLUS_MM_EVENTID_TEST_OR_DEBUG (30000)
/*------- multimedia bigdata feedback event id, end ------------*/
#if IS_ENABLED(CONFIG_OPLUS_FEATURE_MM_FEEDBACK)
int upload_mm_fb_kevent_to_atlas_limit(unsigned int event_id, unsigned char *payload, int limit_ms);
int upload_mm_fb_kevent_limit(enum OPLUS_MM_DIRVER_FB_EVENT_MODULE module, unsigned int event_id,
const char *name, int rate_limit_ms, unsigned int delay_s, char *payload);
#define mm_fb_audio_kevent_named_delay(event_id, rate_limit_ms, delay_s, fmt, ...) \
do { \
char name[MAX_PAYLOAD_DATASIZE] = ""; \
char kv_data[MAX_PAYLOAD_DATASIZE] = ""; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
scnprintf(kv_data, sizeof(kv_data), fmt, ##__VA_ARGS__); \
upload_mm_fb_kevent_limit(OPLUS_MM_DIRVER_FB_EVENT_AUDIO, event_id, name, rate_limit_ms, delay_s, kv_data); \
} while (0)
#define mm_fb_kevent(m, id, name, rate_limit_ms, fmt, ...) \
do { \
char kv_data[MAX_PAYLOAD_DATASIZE] = ""; \
scnprintf(kv_data, sizeof(kv_data), fmt, ##__VA_ARGS__); \
upload_mm_fb_kevent_limit(m, id, name, rate_limit_ms, 0, kv_data); \
} while (0)
#define mm_fb_display_kevent(name, rate_limit_ms, fmt, ...) \
mm_fb_kevent(OPLUS_MM_DIRVER_FB_EVENT_DISPLAY, OPLUS_DISPLAY_EVENTID_DRIVER_ERR, name, rate_limit_ms, fmt, ##__VA_ARGS__)
#define mm_fb_display_kevent_named(rate_limit_ms, fmt, ...) \
do { \
char name[MAX_FUNC_LINE_SIZE]; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
mm_fb_display_kevent(name, rate_limit_ms, fmt, ##__VA_ARGS__); \
} while (0)
#define mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ...) \
mm_fb_kevent(OPLUS_MM_DIRVER_FB_EVENT_AUDIO, event_id, name, rate_limit_ms, fmt, ##__VA_ARGS__)
#define mm_fb_audio_kevent_named(event_id, rate_limit_ms, fmt, ...) \
do { \
char name[MAX_FUNC_LINE_SIZE]; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ##__VA_ARGS__); \
} while (0)
int mm_fb_kevent_init(void);
void mm_fb_kevent_deinit(void);
#else /*CONFIG_OPLUS_FEATURE_MM_FEEDBACK*/
#define upload_mm_fb_kevent_to_atlas_limit(event_id, payload, limit_ms) (0)
#define mm_fb_kevent(m, name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_display_kevent(name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_display_kevent_named(rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_audio_kevent_named(event_id, rate_limit_ms, fmt, ...) do {} while (0)
#endif /*CONFIG_OPLUS_FEATURE_MM_FEEDBACK*/
#endif /* _OPLUS_MM_KEVENT_FB_ */

View File

@@ -1,5 +0,0 @@
config OPLUS_FEATURE_MM_FEEDBACK
bool "Oplus multimedia kevent feedback"
default n
help
define this config to init oplus multimedia kevent feedback driver

View File

@@ -1,2 +0,0 @@
obj-$(CONFIG_OPLUS_FEATURE_MM_FEEDBACK) += oplus_mm_kevent.o
obj-$(CONFIG_OPLUS_FEATURE_MM_FEEDBACK) += oplus_mm_kevent_fb.o

View File

@@ -1,52 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/**************************************************************
* Copyright (c) 2008- 2030 OPLUS Mobile communication Corp.ltd All rights reserved.
*
* File : oplus_mm_fb_netlink.h
* Description : For oplus_mm_fb_netlink
* Version : 1.0
* Date : 2020-11-24
* Author :
* TAG :
****************************************************************/
#ifndef _OPLUS_MM_NETLINK_H
#define _OPLUS_MM_NETLINK_H
#define OPLUS_MM_MSG_TO_KERNEL_BUF_LEN 256
#define OPLUS_MM_MSG_FROM_KERNEL_BUF_LEN (1024)
#define OPLUS_MM_PROTOCAL_NAME "mm_fb"
#define OPLUS_MM_GENL_VERSION 0x01
#define OPLUS_MM_PROTOCAL_NAME_MAX_LEN 100
enum {
MM_FB_CMD_ATTR_UNSPEC = 0,
MM_FB_CMD_ATTR_MSG,
MM_FB_CMD_ATTR_OPT,
__MM_FB_CMD_ATTR_MAX,
};
#define MM_FB_CMD_ATTR_MAX (__MM_FB_CMD_ATTR_MAX - 1)
enum {
MM_FB_CMD_GENL_UNSPEC = 0,
MM_FB_CMD_GENL_SEND_MODULE,
MM_FB_CMD_GENL_UPLOAD,
MM_FB_CMD_GENL_TEST_UPLOAD,
};
struct msg_to_kernel {
struct nlmsghdr n_hd;
struct genlmsghdr g_hd;
char buf[OPLUS_MM_MSG_TO_KERNEL_BUF_LEN];
};
struct msg_from_kernel {
struct nlmsghdr n_hd;
struct genlmsghdr g_hd;
char buf[OPLUS_MM_MSG_FROM_KERNEL_BUF_LEN];
};
#endif //_OPLUS_MM_NETLINK_H

View File

@@ -1,320 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <net/net_namespace.h>
#include <linux/proc_fs.h>
#include <net/sock.h>
#include <linux/vmalloc.h>
#include <linux/version.h>
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include "oplus_mm_kevent.h"
#include <net/genetlink.h>
#include "oplus_mm_fb_netlink.h"
static struct mm_kevent_module mm_modules[MM_KEVENT_MODULE_SIZE_MAX];
static volatile bool mm_kevent_init_flag = false;
static spinlock_t mm_slock;
static mm_kevent_recv_user_func mm_fb_kevent_recv_fb = NULL;
/* record connect pid and modules*/
void mm_fb_kevent_add_module(u32 pid, char *module) {
int i = 0x0;
int len = 0x0;
if (!module) {
return;
}
len = strlen(module);
if (len > (MM_KEVENT_MODULE_LEN_MAX - 1)) {
pr_err("mm_kevent: module len is larger than %d error\n", MM_KEVENT_MODULE_LEN_MAX);
return;
}
for (i = 0; i < MM_KEVENT_MODULE_SIZE_MAX; i++) {
if ((!mm_modules[i].pid) || (!strcmp(mm_modules[i].modl, module))) {
spin_lock(&mm_slock);
mm_modules[i].pid = pid;
memcpy(mm_modules[i].modl, module, len);
mm_modules[i].modl[len] = 0x0;
spin_unlock(&mm_slock);
return;
}
}
return;
}
/* record connect pid and modules*/
int mm_fb_kevent_get_pid(char *module) {
int i = 0;
if (!module) {
return MM_KEVENT_BAD_VALUE;
}
for (i = 0; i < MM_KEVENT_MODULE_SIZE_MAX; i++) {
if (!strcmp(mm_modules[i].modl, module)) {
return mm_modules[i].pid;
}
}
return MM_KEVENT_BAD_VALUE;
}
static int mm_fb_kevent_send_module(struct sk_buff *skb,
struct genl_info *info)
{
struct sk_buff *skbu = NULL;
struct nlmsghdr *nlh;
struct nlattr *na = NULL;
char *pmesg = NULL;
pr_info("mm_kevent: mm_fb_kevent_send_module enter\n");
if (!mm_kevent_init_flag) {
pr_err("%s: mm_kevent: not init error\n", __func__);
return -1;
}
skbu = skb_get(skb);
if (!skbu) {
pr_err("mm_kevent: skb_get result is null error\n");
return -1;
}
if (info->attrs[MM_FB_CMD_ATTR_MSG]) {
na = info->attrs[MM_FB_CMD_ATTR_MSG];
nlh = nlmsg_hdr(skbu);
pmesg = (char*)kmalloc(nla_len(na) + 0x10, GFP_KERNEL);
if (pmesg) {
memcpy(pmesg, nla_data(na), nla_len(na));
pmesg[nla_len(na)] = 0x0;
pr_info("mm_kevent: nla_len(na) %d, pid %d, module: %s\n",
nla_len(na), nlh->nlmsg_pid, pmesg);
mm_fb_kevent_add_module(nlh->nlmsg_pid, pmesg);
}
}
if (pmesg) {
kfree(pmesg);
}
if (skbu) {
kfree_skb(skbu);
}
return 0;
}
void mm_fb_kevent_set_recv_user(mm_kevent_recv_user_func recv_func) {
mm_fb_kevent_recv_fb = recv_func;
}
EXPORT_SYMBOL(mm_fb_kevent_set_recv_user);
static int mm_fb_kevent_test_upload(struct sk_buff *skb,
struct genl_info *info)
{
struct sk_buff *skbu = NULL;
struct nlattr *na = NULL;
char *pmesg = NULL;
pr_info("mm_kevent: mm_fb_kevent_test_upload enter\n");
if (!mm_kevent_init_flag) {
pr_err("%s: mm_kevent: not init error\n", __func__);
return -1;
}
skbu = skb_get(skb);
if (!skbu) {
pr_err("mm_kevent: skb_get result is null error\n");
return -1;
}
if (info->attrs[MM_FB_CMD_ATTR_MSG]) {
na = info->attrs[MM_FB_CMD_ATTR_MSG];
pr_info("mm_kevent: nla_len(na) is %d, data= %s\n", nla_len(na), (char *)nla_data(na));
if (nla_len(na) > OPLUS_MM_MSG_TO_KERNEL_BUF_LEN) {
pr_err("mm_kevent: message len %d too long error\n", nla_len(na));
return -1;
}
pmesg = (char*)kmalloc(nla_len(na) + 0x10, GFP_KERNEL);
if (!pmesg) {
pr_err("mm_kevent: kmalloc return null error\n");
return -1;
}
memcpy(pmesg, nla_data(na), nla_len(na));
pmesg[nla_len(na)] = 0x0;
if (mm_fb_kevent_recv_fb) {
mm_fb_kevent_recv_fb(0, OPLUS_NETLINK_MM_DBG_LV2, pmesg);
}
if (pmesg) {
kfree(pmesg);
}
}
if (skbu) {
kfree_skb(skbu);
}
return 0;
}
#define MM_FB_FAMILY_VERSION 1
#define MM_FB_FAMILY "mm_fb"
#define GENL_ID_GENERATE 0
static const struct genl_ops mm_fb_genl_ops[] = {
{
.cmd = MM_FB_CMD_GENL_SEND_MODULE,
.doit = mm_fb_kevent_send_module,
},
{
.cmd = MM_FB_CMD_GENL_TEST_UPLOAD,
.doit = mm_fb_kevent_test_upload,
},
};
static struct genl_family mm_fb_genl_family __ro_after_init = {
.id = GENL_ID_GENERATE,
.name = MM_FB_FAMILY,
.version = MM_FB_FAMILY_VERSION,
.maxattr = MM_FB_CMD_ATTR_MAX,
.module = THIS_MODULE,
.ops = mm_fb_genl_ops,
.n_ops = ARRAY_SIZE(mm_fb_genl_ops),
};
static inline int genl_msg_prepare_usr_msg(unsigned char cmd, size_t size,
pid_t pid, struct sk_buff **skbp)
{
struct sk_buff *skb;
/* create a new netlink msg */
skb = genlmsg_new(size, GFP_KERNEL);
if (skb == NULL) {
pr_err("mm_kevent: genlmsg_new failed\n");
return -ENOMEM;
}
/* Add a new netlink message to an skb */
genlmsg_put(skb, pid, 0, &mm_fb_genl_family, 0, cmd);
*skbp = skb;
return 0;
}
static inline int genl_msg_mk_usr_msg(struct sk_buff *skb, int type, void *data,
int len)
{
int ret = 0;
/* add a netlink attribute to a socket buffer */
ret = nla_put(skb, type, len, data);
return ret;
}
/* send to user space */
int mm_fb_kevent_send_to_user(struct mm_kevent_packet *userinfo) {
int ret;
int size_use;
struct sk_buff *skbuff;
void * head;
int pid;
if (!mm_kevent_init_flag) {
pr_err("%s: mm_kevent: not init error\n", __func__);
return MM_KEVENT_BAD_VALUE;
}
/* protect payload too long problem*/
if (userinfo->len >= MAX_PAYLOAD_DATASIZE) {
pr_err("mm_kevent: payload_length out of range error\n");
return MM_KEVENT_BAD_VALUE;
}
pid = mm_fb_kevent_get_pid(userinfo->tag);
if (pid == MM_KEVENT_BAD_VALUE) {
pr_err("mm_kevent: tag=%s get pid error\n", userinfo->tag);
return MM_KEVENT_BAD_VALUE;
}
size_use = sizeof(struct mm_kevent_packet) + userinfo->len;
ret = genl_msg_prepare_usr_msg(MM_FB_CMD_GENL_UPLOAD, size_use, pid, &skbuff);
if (ret) {
pr_err("mm_kevent: genl_msg_prepare_usr_msg error, ret is %d \n", ret);
return ret;
}
ret = genl_msg_mk_usr_msg(skbuff, MM_FB_CMD_ATTR_MSG, userinfo, size_use);
if (ret) {
pr_err("mm_kevent: genl_msg_mk_usr_msg error, ret is %d \n", ret);
kfree_skb(skbuff);
return ret;
}
head = genlmsg_data(nlmsg_data(nlmsg_hdr(skbuff)));
genlmsg_end(skbuff, head);
ret = genlmsg_unicast(&init_net, skbuff, pid);
if (ret < 0) {
pr_err("mm_kevent: genlmsg_unicast fail=%d \n", ret);
return MM_KEVENT_BAD_VALUE;
}
return MM_KEVENT_NO_ERROR;
}
EXPORT_SYMBOL(mm_fb_kevent_send_to_user);
int __init mm_fb_kevent_module_init(void) {
int ret;
ret = genl_register_family(&mm_fb_genl_family);
if (ret) {
pr_err("mm_kevent: genl_register_family:%s error,ret = %d\n", MM_FB_FAMILY, ret);
return ret;
} else {
pr_info("mm_kevent: genl_register_family complete, id = %d!\n", mm_fb_genl_family.id);
}
spin_lock_init(&mm_slock);
memset(mm_modules, 0x0, sizeof(mm_modules));
mm_kevent_init_flag = true;
pr_info("mm_kevent: init ok\n");
return MM_KEVENT_NO_ERROR;
}
void __exit mm_fb_kevent_module_exit(void) {
genl_unregister_family(&mm_fb_genl_family);
mm_kevent_init_flag = false;
pr_info("mm_kevent: exit\n");
}
module_init(mm_fb_kevent_module_init);
module_exit(mm_fb_kevent_module_exit);
MODULE_DESCRIPTION("mm_kevent@1.0");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");

View File

@@ -1,67 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* oplus_kevent.h - for kevent action upload upload to user layer
* author by pdl
*/
#ifndef _OPLUS_MM_KEVENT_
#define _OPLUS_MM_KEVENT_
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <linux/version.h>
#define MAX_PAYLOAD_TAG (128)
#define MAX_PAYLOAD_EVENTID (128)
#define MAX_PAYLOAD_DATASIZE (512)
#define MM_KEVENT_MODULE_SIZE_MAX (16)
#define MM_KEVENT_MODULE_LEN_MAX (64)
#define MM_KEVENT_BAD_VALUE (-1)
#define MM_KEVENT_NO_ERROR (0)
//#define OPLUS_NETLINK_MM_KEVENT_TEST
#define OPLUS_NETLINK_MM_DBG_LV1 0x1
#define OPLUS_NETLINK_MM_DBG_LV2 0x2
#define DP_FB_EVENT "mm_kevent_dp"
#define ATLAS_FB_EVENT "mm_kevent_atlas"
enum mm_kevent_type {
MM_KEVENT_NOME = 0x0,
MM_KEVENT_CONNECT,
};
struct mm_kevent_module {
u32 pid;
char modl[MM_KEVENT_MODULE_LEN_MAX];
};
typedef void (*mm_kevent_recv_user_func)(int type, int flags, char* data);
struct mm_kevent_packet {
int type; /* 0:warrning,1:error,2:hw error*/
char tag[MAX_PAYLOAD_TAG]; /* logTag */
char event_id[MAX_PAYLOAD_EVENTID]; /* eventID */
size_t len; /* Length of packet data */
unsigned char data[0]; /* Optional packet data */
}__attribute__((packed));
#if IS_ENABLED(CONFIG_OPLUS_FEATURE_MM_FEEDBACK)
int mm_fb_kevent_send_to_user(struct mm_kevent_packet *userinfo);
void mm_fb_kevent_set_recv_user(mm_kevent_recv_user_func recv_func);
#else //CONFIG_OPLUS_FEATURE_MM_FEEDBACK
int mm_fb_kevent_send_to_user(struct mm_kevent_packet *userinfo) {return 0;}
void mm_fb_kevent_set_recv_user(mm_kevent_recv_user_func recv_func) {return;}
#endif //CONFIG_OPLUS_FEATURE_MM_FEEDBACK
#endif //_OPLUS_MM_KEVENT_

View File

@@ -1,610 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#include <linux/err.h>
#include <linux/sysfs.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#include "oplus_mm_kevent.h"
#include <linux/version.h>
static void mm_fb_kevent_upload_jobs(struct work_struct *work);
static LIST_HEAD(mm_kevent_list);
static DEFINE_MUTEX(mm_kevent_lock);
static DECLARE_DELAYED_WORK(mm_kevent_upload_work_thread,
mm_fb_kevent_upload_jobs);
static struct workqueue_struct *mm_kevent_wq = NULL;
static int mm_kevent_len = 0;
static bool mm_fb_init = false;
#define CAUSENAME_SIZE 128
static char fid[CAUSENAME_SIZE]={"12345678"};
#define LIMIT_UPLOAD_TIME_MS 10000 /*ms*/
struct limit_upload_frq {
unsigned int last_id;
ktime_t last_time;
};
static struct limit_upload_frq g_limit;
struct mm_kevent {
struct list_head head;
enum OPLUS_MM_DIRVER_FB_EVENT_MODULE module;
unsigned int event_id;
struct mutex lock;
int count;
int count_total;
u32 count_limit;
int rate_limit_ms;
ktime_t first;
ktime_t last;
ktime_t last_upload;
struct delayed_work dwork;
char *payload;
char name[0];
};
#define RELATION_EVENT_LIMIT_NUM 6
struct relation_event_limit {
unsigned int fst_id;
ktime_t fst_time;
unsigned int limit_ms;
unsigned int limit_id[RELATION_EVENT_LIMIT_NUM];
};
static struct relation_event_limit g_relate[] = {
{10001, 0, 2000, {10003, 10008, 10041, 10042, 10046, 10047}},
{10003, 0, 1000, {10008, 10046, 0, 0, 0, 0}},
{10046, 0, 1000, {10008, 0, 0, 0, 0, 0}}
};
static void record_relation_first_event(unsigned int id)
{
int lp = 0;
for (lp = 0; lp < sizeof(g_relate)/sizeof(struct relation_event_limit); lp++) {
if (id == g_relate[lp].fst_id) {
g_relate[lp].fst_time = ktime_get();
}
}
}
static bool is_relation_event_limit(unsigned int id)
{
int lp = 0;
int offset = 0;
for (lp = 0; lp < sizeof(g_relate)/sizeof(struct relation_event_limit); lp++) {
for (offset = 0; offset < RELATION_EVENT_LIMIT_NUM; offset++) {
if ((id == g_relate[lp].limit_id[offset]) && \
(g_relate[lp].fst_time != 0) && \
ktime_before(ktime_get(), \
ktime_add_ms(g_relate[lp].fst_time, g_relate[lp].limit_ms))) {
return true;
} else if (0 == g_relate[lp].limit_id[offset]) {
break;
}
}
}
return false;
}
static unsigned int BKDRHash(char *str, unsigned int len)
{
unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */
unsigned int hash = 0;
unsigned int i = 0;
if (str == NULL) {
return 0;
}
for(i = 0; i < len; str++, i++) {
hash = (hash * seed) + (*str);
}
return hash;
}
static void calc_fid(unsigned char *str)
{
char strHashSource[MAX_PAYLOAD_DATASIZE] = {0x00};
unsigned int hashid = 0;
/*struct timespec64 ts64;*/
unsigned long rdm = 0;
ktime_t t;
t = ktime_get();
rdm = get_random_u64();
snprintf(strHashSource, MAX_PAYLOAD_DATASIZE, "%lu %lu %s", rdm, t, str);
hashid = BKDRHash(strHashSource, strlen(strHashSource));
memset(fid, 0 , CAUSENAME_SIZE);
snprintf(fid, CAUSENAME_SIZE, "%u", hashid);
printk(KERN_INFO "calc_fid: fid=%u\n", hashid);
}
static int upload_mm_fb_kevent(unsigned int event_id, unsigned char *payload)
{
struct mm_kevent_packet *user_msg_info;
char event_id_str[MAX_PAYLOAD_EVENTID] = {0};
void *buffer = NULL;
int len, size;
int ret = 0;
printk(KERN_INFO "%s: mm_kevent fb: enter, event_id = %d\n", __func__,
event_id);
mutex_lock(&mm_kevent_lock);
len = strlen(payload);
if (len > MAX_PAYLOAD_DATASIZE) {
printk(KERN_INFO "%s: error: payload len=%d > %d\n",
__func__, len, MAX_PAYLOAD_DATASIZE);
ret = -1;
goto _exit;
}
size = sizeof(struct mm_kevent_packet) + len + 1;
buffer = kmalloc(size, GFP_ATOMIC);
if (!buffer) {
printk(KERN_INFO "%s: kmalloc %d bytes failed\n", __func__, size);
ret = -1;
goto _exit;
}
memset(buffer, 0, size);
user_msg_info = (struct mm_kevent_packet *)buffer;
user_msg_info->type = 1;
memcpy(user_msg_info->tag, ATLAS_FB_EVENT, sizeof(ATLAS_FB_EVENT));
snprintf(event_id_str, sizeof(event_id_str) - 1, "%d", event_id);
memcpy(user_msg_info->event_id, event_id_str, strlen(event_id_str));
user_msg_info->len = len + 1;
memcpy(user_msg_info->data, payload, len + 1);
mm_fb_kevent_send_to_user(user_msg_info);
kfree(buffer);
record_relation_first_event(event_id);
_exit:
mutex_unlock(&mm_kevent_lock);
return ret;
}
static void mm_fb_kevent_upload_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mm_kevent *new_kevent = container_of(dwork, struct mm_kevent, dwork);
struct mm_kevent *kevent = NULL, *n = NULL;
bool found = false;
int cnt = 0;
list_for_each_entry_safe(kevent, n, &mm_kevent_list, head) {
if (!strcmp(kevent->name, new_kevent->name)) {
found = true;
break;
}
}
if (!found) {
if (mm_kevent_len > 200) {
unsigned char payload[MAX_PAYLOAD_DATASIZE] = "";
pr_err("mm_kevent large than 200");
if (OPLUS_MM_DIRVER_FB_EVENT_AUDIO == new_kevent->module) {
#define PAYLOAD(fmt, ...) \
if (sizeof(payload) > cnt) \
cnt += scnprintf(payload + cnt, sizeof(payload) - cnt, fmt, ##__VA_ARGS__);
PAYLOAD("func@@%s$$", new_kevent->name);
PAYLOAD("%s", new_kevent->payload ? new_kevent->payload : "NULL");
} else {
scnprintf(payload, sizeof(payload), "MSG@@%s", new_kevent->name);
}
upload_mm_fb_kevent(new_kevent->event_id, payload);
goto done;
}
kevent = new_kevent;
kevent->count = 1;
kevent->count_total = 1;
new_kevent = NULL;
mm_kevent_len++;
list_add_tail(&kevent->head, &mm_kevent_list);
goto done;
}
if (WARN_ON(!kevent)) {
goto done;
}
mutex_lock(&kevent->lock);
kevent->count++;
kevent->count_total++;
kevent->last = new_kevent->first;
kfree(kevent->payload);
kevent->payload = new_kevent->payload;
new_kevent->payload = NULL;
mutex_unlock(&kevent->lock);
done:
mm_fb_kevent_upload_jobs(NULL);
if (new_kevent) {
kfree(new_kevent->payload);
}
kfree(new_kevent);
}
static void mm_fb_kevent_upload_jobs(struct work_struct *work)
{
struct mm_kevent *kevent = NULL, *n = NULL;
unsigned char payload[MAX_PAYLOAD_DATASIZE] = "";
int cnt;
list_for_each_entry_safe(kevent, n, &mm_kevent_list, head) {
if (ktime_before(kevent->last, kevent->last_upload)) {
continue;
}
if (kevent->count_limit && (kevent->count_total % kevent->count_limit == 0)) {
kevent->count_limit <<= 1;
if (kevent->count_limit > 4096) {
kevent->count_limit = 4096;
}
} else if (!kevent->rate_limit_ms || (kevent->rate_limit_ms &&
ktime_before(ktime_get(), ktime_add_ms(kevent->last_upload,
kevent->rate_limit_ms)))) {
continue;
}
mutex_lock(&kevent->lock);
cnt = 0;
#define PAYLOAD(fmt, ...) \
if (sizeof(payload) > cnt) \
cnt += scnprintf(payload + cnt, sizeof(payload) - cnt, fmt, ##__VA_ARGS__);
if (OPLUS_MM_DIRVER_FB_EVENT_AUDIO == kevent->module) {
PAYLOAD("func@@%s$$", kevent->name);
PAYLOAD("CT@@%d$$", kevent->count);
PAYLOAD("%s", kevent->payload ? kevent->payload : "NULL");
} else {
PAYLOAD("EventName@@%s$$", kevent->name);
PAYLOAD("CT@@%d$$", kevent->count);
PAYLOAD("FT@@%lu$$", ktime_to_ms(kevent->first) / 1000);
PAYLOAD("ET@@%lu$$", ktime_to_ms(kevent->last) / 1000);
PAYLOAD("MSG@@%s", kevent->payload ? kevent->payload : "NULL");
}
if (kevent->payload) {
kfree(kevent->payload);
kevent->payload = NULL;
}
kevent->count = 0;
kevent->last_upload = ktime_get();
mutex_unlock(&kevent->lock);
upload_mm_fb_kevent(kevent->event_id, payload);
}
if (mm_kevent_wq) {
mod_delayed_work(mm_kevent_wq, &mm_kevent_upload_work_thread, 60 * 60 * HZ);
}
}
static void mm_fb_kevent_upload_recv_user(int type, int flags, char *data)
{
printk(KERN_INFO "mm_kevent fb recv user type=0x%x, flags=0x%x, data=%s\n",
type, flags, data);
#ifdef OPLUS_NETLINK_MM_KEVENT_TEST
if (flags & OPLUS_NETLINK_MM_DBG_LV2) {
upload_mm_fb_kevent(OPLUS_MM_EVENTID_TEST_OR_DEBUG, data);
}
#endif
}
/* queue a delaywork to upload the feedback info, can used in interrupt function or timeliness requirement place*/
int upload_mm_fb_kevent_limit(enum OPLUS_MM_DIRVER_FB_EVENT_MODULE module,
unsigned int event_id,
const char *name, int rate_limit_ms, unsigned int delay_s, char *payload)
{
struct mm_kevent *kevent = NULL;
int size;
char buf[MAX_PAYLOAD_DATASIZE] = {0};
if (!mm_fb_init || !mm_kevent_wq) {
pr_err("%s: error: not init or mm_kevent_wq is null\n", __func__);
return -EINVAL;
}
if(is_relation_event_limit(event_id)) {
pr_info("%s: relation event has feedback before, not feedback %u\n", __func__, event_id);
return -EINVAL;
}
size = strlen(name) + sizeof(*kevent) + 1;
kevent = kzalloc(size, GFP_ATOMIC);
if (!kevent) {
return -ENOMEM;
}
kevent->module = module;
kevent->event_id = event_id;
kevent->count_limit = 1;
kevent->last_upload = ktime_get();
kevent->first = ktime_get();
kevent->last = ktime_get();
kevent->rate_limit_ms = rate_limit_ms;
memcpy(kevent->name, name, strlen(name) + 1);
if (OPLUS_AUDIO_EVENTID_ADSP_CRASH == event_id) {
calc_fid(payload);
scnprintf(buf, MAX_PAYLOAD_DATASIZE, "EventField@@%s$$%s",
fid, payload ? payload : "NULL");
kevent->payload = kmemdup(buf, strlen(buf) + 1, GFP_ATOMIC);
} else {
kevent->payload = kmemdup(payload, strlen(payload) + 1, GFP_ATOMIC);
}
mutex_init(&kevent->lock);
INIT_DELAYED_WORK(&kevent->dwork, mm_fb_kevent_upload_work);
if (delay_s > 0) {
printk(KERN_INFO "%s:feedback delay %d second\n", __func__, delay_s);
queue_delayed_work(mm_kevent_wq, &kevent->dwork, delay_s * HZ);
} else {
queue_delayed_work(mm_kevent_wq, &kevent->dwork, 0);
}
printk(KERN_INFO "%s:event_id=%d,payload:%s\n", __func__, event_id, payload);
return 0;
}
EXPORT_SYMBOL(upload_mm_fb_kevent_limit);
/* upload the feedback info immediately, can't used in interrupt function */
int upload_mm_fb_kevent_to_atlas_limit(unsigned int event_id,
unsigned char *payload, int limit_ms)
{
struct mm_kevent_packet *user_msg_info;
char event_id_str[MAX_PAYLOAD_EVENTID] = {0};
void *buffer = NULL;
int len, size;
int ret = 0;
printk(KERN_INFO "mm_kevent fb:upload_mm_fb_kevent_to_atlas_limit enter\n");
if (!mm_fb_init) {
pr_err("%s: error, module not init\n", __func__);
return -EINVAL;
}
if(is_relation_event_limit(event_id)) {
pr_info("%s: relation event has feedback before, not feedback %u\n", __func__, event_id);
return -EINVAL;
}
mutex_lock(&mm_kevent_lock);
if ((limit_ms > 0) && (g_limit.last_id == event_id)) {
if (ktime_before(ktime_get(), ktime_add_ms(g_limit.last_time, limit_ms))) {
printk(KERN_INFO "upload event_id=%d failed, report too often, limit_ms=%d\n",
event_id, limit_ms);
ret = -1;
goto _exit;
}
}
len = strlen(payload);
if (len > MAX_PAYLOAD_DATASIZE) {
printk(KERN_INFO "error: payload len=%d > %d\n", len, MAX_PAYLOAD_DATASIZE);
ret = -1;
goto _exit;
}
size = sizeof(struct mm_kevent_packet) + len + 1;
buffer = kmalloc(size, GFP_ATOMIC);
if (!buffer) {
printk(KERN_INFO "%s: kmalloc %d bytes failed\n", __func__, size);
ret = -1;
goto _exit;
}
memset(buffer, 0, size);
user_msg_info = (struct mm_kevent_packet *)buffer;
user_msg_info->type = 1;
if ((MAX_PAYLOAD_TAG - 1) > strlen(ATLAS_FB_EVENT)) {
memcpy(user_msg_info->tag, ATLAS_FB_EVENT, strlen(ATLAS_FB_EVENT));
user_msg_info->tag[strlen(ATLAS_FB_EVENT)] = 0;
}
snprintf(event_id_str, sizeof(event_id_str) - 1, "%d", event_id);
memcpy(user_msg_info->event_id, event_id_str, strlen(event_id_str));
user_msg_info->len = len + 1;
memcpy(user_msg_info->data, payload, len + 1);
pr_info("%s: mm_kevent: type %d, tag=%s, event_id=%s, len=%zu, payload=%s\n",
__func__,
user_msg_info->type, user_msg_info->tag, user_msg_info->event_id,
user_msg_info->len, user_msg_info->data);
mm_fb_kevent_send_to_user(user_msg_info);
kfree(buffer);
g_limit.last_id = event_id;
g_limit.last_time = ktime_get();
record_relation_first_event(event_id);
_exit:
mutex_unlock(&mm_kevent_lock);
return ret;
}
EXPORT_SYMBOL(upload_mm_fb_kevent_to_atlas_limit);
#define MM_FB_EVENTID_LEN 5
#define MM_FB_HAL_LIMIT (30*1000)
#define IS_DIGITAL(x) (((x) >= '0') && ((x) <= '9'))
static ssize_t mm_fb_write(struct file *file,
const char __user *buf,
size_t count,
loff_t *lo)
{
char *r_buf;
unsigned int event_id = 0;
int len, i;
if (!mm_fb_init) {
pr_err("%s: error, module not init\n", __func__);
return -EINVAL;
}
r_buf = (char *)kzalloc(MAX_PAYLOAD_DATASIZE, GFP_KERNEL);
if (!r_buf) {
return count;
}
if (copy_from_user(r_buf, buf,
MAX_PAYLOAD_DATASIZE > count ? count : MAX_PAYLOAD_DATASIZE)) {
goto exit;
}
r_buf[MAX_PAYLOAD_DATASIZE - 1] ='\0'; /*make sure last bype is eof*/
len = strlen(r_buf);
printk(KERN_INFO "%s: mm_kevent fb len=%d, data=%s\n", __func__, len, r_buf);
if (len < (MM_FB_EVENTID_LEN + 2)) {
printk(KERN_INFO "%s: mm_kevent fb data len=%d is error\n", __func__, len);
goto exit;
}
for (i = 0; i < MM_FB_EVENTID_LEN; i++) {
if (IS_DIGITAL(r_buf[i])) {
event_id = event_id*10 + r_buf[i] - '0';
} else {
printk(KERN_INFO "%s: mm_kevent fb eventid is error, data=%s\n", __func__,
r_buf);
goto exit;
}
}
upload_mm_fb_kevent_to_atlas_limit(event_id, r_buf + MM_FB_EVENTID_LEN + 1,
MM_FB_HAL_LIMIT);
exit:
kfree(r_buf);
return count;
}
static ssize_t mm_fb_read(struct file *file,
char __user *buf,
size_t count,
loff_t *ppos)
{
if (!mm_fb_init) {
pr_err("%s: error, module not init\n", __func__);
return -EINVAL;
}
return count;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
static const struct proc_ops mm_fb_fops = {
.proc_write = mm_fb_write,
.proc_read = mm_fb_read,
.proc_open = simple_open,
};
#else
static const struct file_operations mm_fb_fops = {
.write = mm_fb_write,
.read = mm_fb_read,
.open = simple_open,
.owner = THIS_MODULE,
};
#endif
static ssize_t adsp_crash_cause_read(struct file *file,
char __user *buf,
size_t count,
loff_t *off)
{
char page[CAUSENAME_SIZE] = {0x00};
int len = 0;
len = snprintf(page, sizeof(page) - 1, "%s", fid);
len = simple_read_from_buffer(buf, count, off, page, strlen(page));
return len;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
static const struct proc_ops adsp_crash_cause_fops = {
.proc_read = adsp_crash_cause_read,
.proc_open = simple_open,
};
#else
static const struct file_operations adsp_crash_cause_fops = {
.read = adsp_crash_cause_read,
.open = simple_open,
.owner = THIS_MODULE,
};
#endif
int mm_fb_kevent_init(void)
{
struct proc_dir_entry *d_entry = NULL;
int ret = 0;
mm_kevent_wq = create_workqueue("mm_kevent");
if (!mm_kevent_wq) {
ret = -ENOMEM;
goto failed_create_workqueue;
}
queue_delayed_work(mm_kevent_wq, &mm_kevent_upload_work_thread, 0);
mm_fb_kevent_set_recv_user(mm_fb_kevent_upload_recv_user);
g_limit.last_id = 0xFFFFFFFF;
g_limit.last_time = 0;
d_entry = proc_create_data("mm_fb", 0664, NULL, &mm_fb_fops, NULL);
if (!d_entry) {
pr_err("%s: failed to create node\n", __func__);
ret = -ENODEV;
goto failed_proc_create_data;
}
d_entry = proc_create_data("adsp_crash_cause", 0664, NULL,
&adsp_crash_cause_fops, NULL);
if (!d_entry) {
pr_err("failed to adsp_crash_cause node\n");
ret = -ENODEV;
goto failed_proc_create_data;
}
mm_fb_init = true;
pr_info("%s: init success\n", __func__);
return 0;
failed_proc_create_data:
if (mm_kevent_wq) {
destroy_workqueue(mm_kevent_wq);
mm_kevent_wq = NULL;
}
failed_create_workqueue:
return ret;
}
void mm_fb_kevent_deinit(void)
{
if (mm_kevent_wq) {
destroy_workqueue(mm_kevent_wq);
mm_kevent_wq = NULL;
}
mm_fb_kevent_set_recv_user(NULL);
mm_fb_init = false;
pr_info("%s: deinit\n", __func__);
}
module_init(mm_fb_kevent_init);
module_exit(mm_fb_kevent_deinit);
MODULE_LICENSE("GPL v2");

View File

@@ -26,13 +26,6 @@
#include <linux/soc/qcom/smem_state.h>
#include "peripheral-loader.h"
//#ifdef OPLUS_FEATURE_SENSOR
#include <soc/oplus/system/kernel_fb.h>
//#endif
#ifdef OPLUS_FEATURE_MM_FEEDBACK
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif
#define XO_FREQ 19200000
#define PROXY_TIMEOUT_MS 10000
@@ -849,22 +842,6 @@ static void log_failure_reason(const struct pil_tz_data *d)
}
#endif /* OPLUS_FEATURE_WIFI_DCS_SWITCH */
//#ifdef OPLUS_FEATURE_SENSOR
set_subsys_crash_cause(reason);
if((strncmp(name, "slpi", strlen("slpi")) == 0)
|| (strncmp(name, "cdsp", strlen("cdsp")) == 0)
|| (strncmp(name, "adsp", strlen("adsp")) == 0)){
strcat(reason, "$$module@@");
strcat(reason, name);
oplus_kevent_fb_str(FB_SENSOR, FB_SENSOR_ID_CRASH, reason);
}
//#endif
#ifdef OPLUS_FEATURE_MM_FEEDBACK
if(strncmp(name, "adsp", strlen("adsp")) == 0){
mm_fb_audio_kevent_named(OPLUS_AUDIO_EVENTID_ADSP_CRASH, \
MM_FB_KEY_RATELIMIT_5MIN, "payload@@%s$$fid@@123456", reason);
}
#endif
pr_err("%s subsystem failure reason: %s.\n", name, reason);
}

View File

@@ -1,39 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#ifndef __KERNEL_FEEDBACK_H
#define __KERNEL_FEEDBACK_H
typedef enum {
FB_STABILITY = 0,
FB_FS,
FB_STORAGE,
FB_SENSOR,
FB_BOOT,
FB_MAX_TYPE = FB_BOOT,
} fb_tag;
#define FB_STABILITY_ID_CRASH "202007272030"
#define FB_SENSOR_ID_CRASH "10004"
#define FB_SENSOR_ID_QMI "202007272041"
struct kernel_packet_info
{
int type; /* 0:root,1:only string,other number represent other type */
char log_tag[32]; /* logTag */
char event_id[20]; /*eventID */
size_t payload_length; /* Length of packet data */
unsigned char payload[0]; /* Optional packet data */
}__attribute__((packed));
int oplus_kevent_fb(fb_tag tag_id, const char *event_id, unsigned char *payload);
int oplus_kevent_fb_str(fb_tag tag_id, const char *event_id, unsigned char *str);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int fb_kevent_send_to_user(struct kernel_packet_info *userinfo);
#pragma GCC diagnostic pop
#endif

View File

@@ -1,105 +0,0 @@
/***************************************************************
** Copyright (C), 2018, OPLUS Mobile Comm Corp., Ltd
** File : oplus_mm_kevent_fb.h
** Description : MM kevent fb data
** Version : 1.0
** Date : 2018/12/03
**
** ------------------------------- Revision History: -----------
** <author> <data> <version > <desc>
** Guo.Ling 2018/12/03 1.0 Build this moudle
** LiPing-M 2019/01/29 1.1 Add SMMU for QCOM
******************************************************************/
#ifndef _OPLUS_MM_KEVENT_FB_
#define _OPLUS_MM_KEVENT_FB_
#define MAX_PAYLOAD_DATASIZE (512)
#define MM_KEVENT_MAX_PAYLOAD_SIZE MAX_PAYLOAD_DATASIZE
#define MAX_FUNC_LINE_SIZE (128)
enum {
MM_FB_KEY_RATELIMIT_NONE = 0,
MM_FB_KEY_RATELIMIT_1MIN = 60 * 1000,
MM_FB_KEY_RATELIMIT_5MIN = 60 * 5 * 1000,
MM_FB_KEY_RATELIMIT_30MIN = 60 * 30 * 1000,
MM_FB_KEY_RATELIMIT_1H = MM_FB_KEY_RATELIMIT_30MIN * 2,
MM_FB_KEY_RATELIMIT_1DAY = MM_FB_KEY_RATELIMIT_1H * 24,
};
#define FEEDBACK_DELAY_60S 60
#define OPLUS_FB_ADSP_CRASH_RATELIMIT (60 * 5 * 1000) /*ms, for mtk*/
enum OPLUS_MM_DIRVER_FB_EVENT_MODULE {
OPLUS_MM_DIRVER_FB_EVENT_DISPLAY = 0,
OPLUS_MM_DIRVER_FB_EVENT_AUDIO
};
/*------- multimedia bigdata feedback event id, start ------------ */
#define OPLUS_AUDIO_EVENTID_ADSP_CRASH (10001)
#define OPLUS_AUDIO_EVENTID_HEADSET_DET (10009)
#define OPLUS_AUDIO_EVENTID_ADSP_RECOVERY_FAIL (10045)
#define OPLUS_DISPLAY_EVENTID_DRIVER_ERR (12002)
#define OPLUS_DISPLAY_EVENTID_GPU_FAULT (12005)
/*this id just for test or debug */
#define OPLUS_MM_EVENTID_TEST_OR_DEBUG (30000)
/*------- multimedia bigdata feedback event id, end ------------*/
#if IS_ENABLED(CONFIG_OPLUS_FEATURE_MM_FEEDBACK)
int upload_mm_fb_kevent_to_atlas_limit(unsigned int event_id, unsigned char *payload, int limit_ms);
int upload_mm_fb_kevent_limit(enum OPLUS_MM_DIRVER_FB_EVENT_MODULE module, unsigned int event_id,
const char *name, int rate_limit_ms, unsigned int delay_s, char *payload);
#define mm_fb_audio_kevent_named_delay(event_id, rate_limit_ms, delay_s, fmt, ...) \
do { \
char name[MAX_PAYLOAD_DATASIZE] = ""; \
char kv_data[MAX_PAYLOAD_DATASIZE] = ""; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
scnprintf(kv_data, sizeof(kv_data), fmt, ##__VA_ARGS__); \
upload_mm_fb_kevent_limit(OPLUS_MM_DIRVER_FB_EVENT_AUDIO, event_id, name, rate_limit_ms, delay_s, kv_data); \
} while (0)
#define mm_fb_kevent(m, id, name, rate_limit_ms, fmt, ...) \
do { \
char kv_data[MAX_PAYLOAD_DATASIZE] = ""; \
scnprintf(kv_data, sizeof(kv_data), fmt, ##__VA_ARGS__); \
upload_mm_fb_kevent_limit(m, id, name, rate_limit_ms, 0, kv_data); \
} while (0)
#define mm_fb_display_kevent(name, rate_limit_ms, fmt, ...) \
mm_fb_kevent(OPLUS_MM_DIRVER_FB_EVENT_DISPLAY, OPLUS_DISPLAY_EVENTID_DRIVER_ERR, name, rate_limit_ms, fmt, ##__VA_ARGS__)
#define mm_fb_display_kevent_named(rate_limit_ms, fmt, ...) \
do { \
char name[MAX_FUNC_LINE_SIZE]; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
mm_fb_display_kevent(name, rate_limit_ms, fmt, ##__VA_ARGS__); \
} while (0)
#define mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ...) \
mm_fb_kevent(OPLUS_MM_DIRVER_FB_EVENT_AUDIO, event_id, name, rate_limit_ms, fmt, ##__VA_ARGS__)
#define mm_fb_audio_kevent_named(event_id, rate_limit_ms, fmt, ...) \
do { \
char name[MAX_FUNC_LINE_SIZE]; \
scnprintf(name, sizeof(name), "%s:%d", __func__, __LINE__); \
mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ##__VA_ARGS__); \
} while (0)
int mm_fb_kevent_init(void);
void mm_fb_kevent_deinit(void);
#else /*CONFIG_OPLUS_FEATURE_MM_FEEDBACK*/
#define upload_mm_fb_kevent_to_atlas_limit(event_id, payload, limit_ms) (0)
#define mm_fb_kevent(m, name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_display_kevent(name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_display_kevent_named(rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_audio_kevent(event_id, name, rate_limit_ms, fmt, ...) do {} while (0)
#define mm_fb_audio_kevent_named(event_id, rate_limit_ms, fmt, ...) do {} while (0)
#endif /*CONFIG_OPLUS_FEATURE_MM_FEEDBACK*/
#endif /* _OPLUS_MM_KEVENT_FB_ */

File diff suppressed because one or more lines are too long

View File

@@ -63,10 +63,6 @@ extern bool g_speaker_resistance_fail;
#include <linux/fs.h>
#endif /* OPLUS_ARCH_EXTENDS */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif
/* Change volume selection behavior:
* Uncomment following line to generate a profile change when updating
* a volume control (also changes to the profile of the modified volume
@@ -2723,239 +2719,6 @@ static int tfa98xx_get_stereo_ctl(struct snd_kcontrol *kcontrol,
#endif /* OPLUS_ARCH_EXTENDS */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
#define OPLUS_AUDIO_EVENTID_SMARTPA_ERR 10041
#define OPLUS_AUDIO_EVENTID_SPK_ERR 10042
#define ERROR_INFO_MAX_LEN 32
#define REG_BITS 16
#define TFA9874_STATUS_NORMAL_VALUE ((0x850F<<REG_BITS) + 0x16)/*reg 0x13 high 16 bits and 0x10 low 16 bits*/
#define TFA9874_STATUS_CHECK_MASK ((0x300<<REG_BITS) + 0x9C)/*reg 0x10 mask bit2~4, bit7, reg 0x13 mask bit8 , bit9 */
#define TFA9873_STATUS_NORMAL_VALUE ((0x850F<<REG_BITS) + 0x56) /*reg 0x13 high 16 bits and 0x10 low 16 bits*/
#define TFA9873_STATUS_CHECK_MASK ((0x300<<REG_BITS) + 0x15C)/*reg 0x10 mask bit2~4, bit6, bit8, reg 0x13 mask bit8 , bit9*/
static ktime_t last_fb = 0;
static bool g_chk_err = false;
static char const *tfa98xx_check_feedback_text[] = {"Off", "On"};
static const struct soc_enum tfa98xx_check_feedback_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tfa98xx_check_feedback_text), tfa98xx_check_feedback_text);
enum {
PA_TFA9874 = 0,
PA_TFA9873,
PA_MAX
};
static int g_pa_type = PA_MAX;
struct check_status_err {
int bit;
uint32_t err_val;
char info[ERROR_INFO_MAX_LEN];
};
static const struct check_status_err check_err_tfa9874[] = {
/*register 0x10 check bits*/
{2, 0, "OverTemperature"},
{3, 1, "CurrentHigh"},
{4, 0, "VbatLow"},
{7, 1, "NoClock"},
/*register 0x13 check bits*/
{8 + REG_BITS, 0, "VbatHigh"},
{9 + REG_BITS, 1, "Clipping"},
};
static const struct check_status_err check_err_tfa9873[] = {
/*register 0x10 check bits*/
{2, 0, "OverTemperature"},
{3, 1, "CurrentHigh"},
{4, 0, "VbatLow"},
{6, 0, "UnstableClk"},
{8, 1, "NoClock"},
/*register 0x13 check bits*/
{8 + REG_BITS, 0, "VbatHigh"},
{9 + REG_BITS, 1, "Clipping"},
};
const unsigned char fb_regs[] = {0x00, 0x01, 0x02, 0x04, 0x05, 0x11, 0x14, 0x15, 0x16};
static int tfa98xx_check_status_reg(void )
{
struct tfa98xx *tfa98xx;
uint32_t reg_val = 0;
uint16_t reg10 = 0, reg13 = 0, reg_tmp = 0;
int flag = 0;
char fd_buf[MM_KEVENT_MAX_PAYLOAD_SIZE] = {0};
char info[MM_KEVENT_MAX_PAYLOAD_SIZE] = {0};
int offset = 0;
enum Tfa98xx_Error err;
int i, num = 0;
if (!g_chk_err) {
return 0;
}
if ((g_pa_type != PA_TFA9874) && (g_pa_type != PA_TFA9873)) {
return 0;
}
if ((last_fb !=0) && ktime_before(ktime_get(), ktime_add_ms(last_fb, MM_FB_KEY_RATELIMIT_5MIN))) {
return 0;
}
mutex_lock(&tfa98xx_mutex);
/* check status register 0x10 value */
list_for_each_entry(tfa98xx, &tfa98xx_device_list, list) {
num++;
err = tfa98xx_read_register16_v6(tfa98xx->tfa, 0x10, &reg10);
if (Tfa98xx_Error_Ok == err) {
err = tfa98xx_read_register16_v6(tfa98xx->tfa, 0x13, &reg13);
}
pr_info("%s: read SPK%d status regs ret=%d, reg[0x10]=0x%x, reg[0x13]=0x%x", __func__, num, err, reg10, reg13);
if (Tfa98xx_Error_Ok == err) {
reg_val = (reg13 << REG_BITS) + reg10;
flag = 0;
if ((g_pa_type == PA_TFA9874) &&
((TFA9874_STATUS_NORMAL_VALUE&TFA9874_STATUS_CHECK_MASK) != (reg_val&TFA9874_STATUS_CHECK_MASK))) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1,
"TFA9874 SPK%d:reg[0x10]=0x%x,reg[0x13]=0x%x,", num, reg10, reg13);
for (i = 0; i < ARRAY_SIZE(check_err_tfa9874); i++) {
if (check_err_tfa9874[i].err_val == (1 & (reg_val>>check_err_tfa9874[i].bit))) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "%s,", check_err_tfa9874[i].info);
}
}
flag = 1;
} else if ((g_pa_type == PA_TFA9873) &&
((TFA9873_STATUS_NORMAL_VALUE&TFA9873_STATUS_CHECK_MASK) != (reg_val&TFA9873_STATUS_CHECK_MASK))) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1,
"TFA9873 SPK%d:reg[0x10]=0x%x,reg[0x13]=0x%x,", num, reg10, reg13);
for (i = 0; i < ARRAY_SIZE(check_err_tfa9873); i++) {
if (check_err_tfa9873[i].err_val == (1 & (reg_val>>check_err_tfa9873[i].bit))) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "%s,", check_err_tfa9873[i].info);
}
}
flag = 1;
}
/* read other registers */
if (flag == 1) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "(");
for (i = 0; i < sizeof(fb_regs); i++) {
err = tfa98xx_read_register16_v6(tfa98xx->tfa, fb_regs[i], &reg_tmp);
if (Tfa98xx_Error_Ok == err) {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "%x,", reg_tmp);
} else {
break;
}
}
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "),");
}
} else {
offset = strlen(info);
scnprintf(info + offset, sizeof(info) - offset - 1, "%s SPK%d: failed to read regs 0x10 and 0x13, error=%d,", \
(g_pa_type == PA_TFA9873) ? "TFA9873" : "TFA9874", num, err);\
last_fb = ktime_get();
}
}
mutex_unlock(&tfa98xx_mutex);
/* feedback the check error */
offset = strlen(info);
if ((offset > 0) && (offset < MM_KEVENT_MAX_PAYLOAD_SIZE)) {
fd_buf[offset] = '\0';
scnprintf(fd_buf, sizeof(fd_buf) - 1, "payload@@%s", info);
mm_fb_audio_kevent_named(OPLUS_AUDIO_EVENTID_SMARTPA_ERR,
MM_FB_KEY_RATELIMIT_5MIN, fd_buf);
pr_err("%s: fd_buf=%s\n", __func__, fd_buf);
}
return 1;
}
static int tfa98xx_set_check_feedback(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int need_chk = ucontrol->value.integer.value[0];
pr_info("%s: need_chk = %d\n", __func__, need_chk);
g_chk_err = need_chk;
return 1;
}
static int tfa98xx_get_check_feedback(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = g_chk_err;
pr_info("%s: g_chk_err = %d\n", __func__, g_chk_err);
return 0;
}
static const struct snd_kcontrol_new tfa98xx_check_feedback[] = {
SOC_ENUM_EXT("TFA_CHECK_FEEDBACK", tfa98xx_check_feedback_enum,
tfa98xx_get_check_feedback, tfa98xx_set_check_feedback),
};
static int tfa98xx_check_speaker_status(struct tfa98xx *tfa98xx)
{
char fd_buf[MM_KEVENT_MAX_PAYLOAD_SIZE] = {0};
enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
char buffer[6] = {0};
if (!g_chk_err) {
return 0;
}
if ((g_pa_type != PA_TFA9874) && (g_pa_type != PA_TFA9873)) {
return 0;
}
if ((last_fb !=0) && ktime_before(ktime_get(), ktime_add_ms(last_fb, MM_FB_KEY_RATELIMIT_5MIN))) {
return 0;
}
mutex_lock(&tfa98xx->dsp_lock);
//Get the GetStatusChange results
err = tfa_dsp_cmd_id_write_read_v6(tfa98xx->tfa, MODULE_FRAMEWORK,
FW_PAR_ID_GET_STATUS_CHANGE, 6, (unsigned char *)buffer);
mutex_unlock(&tfa98xx->dsp_lock);
pr_info("%s: ret=%d, get value=%d\n", __func__, err, buffer[2]);
if (err == Tfa98xx_Error_Ok) {
if (buffer[2] & 0x6) {
scnprintf(fd_buf, sizeof(fd_buf) - 1, "payload@@");
if (buffer[2] & 0x2) {
pr_err("%s: ##ERROR## Primary SPK hole blocked or damaged event detected 0x%x\n",
__func__, buffer[2]);
scnprintf(fd_buf + strlen(fd_buf),
sizeof(fd_buf) - strlen(fd_buf), " SPK1 damaged or hole blocked");
}
if ((tfa98xx_device_count == 2) && (buffer[2] & 0x4)) {
pr_err("%s: ##ERROR## Second SPK hole blocked or SPK damaged event detected 0x%x\n",
__func__, buffer[2]);
scnprintf(fd_buf + strlen(fd_buf),
sizeof(fd_buf) - strlen(fd_buf), " SPK2 damaged or hole blocked");
}
mm_fb_audio_kevent_named(OPLUS_AUDIO_EVENTID_SPK_ERR,
MM_FB_KEY_RATELIMIT_5MIN, fd_buf);
pr_err("%s: fd_buf=%s\n", __func__, fd_buf);
}
} else {
scnprintf(fd_buf, sizeof(fd_buf) - 1, "payload@@spk protection algorithm error, ret=%d,", err);
mm_fb_audio_kevent_named(OPLUS_AUDIO_EVENTID_SMARTPA_ERR,
MM_FB_KEY_RATELIMIT_5MIN, fd_buf);
last_fb = ktime_get();
pr_err("%s: tfa_dsp_cmd_id_write_read_v6 err = %d\n", __func__, err);
}
return err;
}
#endif /*OPLUS_FEATURE_MM_FEEDBACK*/
static int tfa98xx_create_controls(struct tfa98xx *tfa98xx)
{
int prof, nprof, mix_index = 0;
@@ -4511,15 +4274,6 @@ static int tfa98xx_mute(struct snd_soc_dai *dai, int mute, int stream)
/* stop DSP only when both playback and capture streams
* are deactivated
*/
#ifdef OPLUS_FEATURE_MM_FEEDBACK
if (g_chk_err) {
tfa98xx_check_status_reg();
tfa98xx_check_speaker_status(tfa98xx);
g_chk_err = false;
}
#endif /* OPLUS_FEATURE_MM_FEEDBACK */
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
tfa98xx->pstream = 0;
else
@@ -4697,10 +4451,6 @@ static int tfa98xx_probe(struct snd_soc_component *component)
tfadsp_volume_controls, ARRAY_SIZE(tfadsp_volume_controls));
#endif /* OPLUS_FEATURE_FADE_IN */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
snd_soc_add_component_controls(tfa98xx->component,
tfa98xx_check_feedback, ARRAY_SIZE(tfa98xx_check_feedback));
#endif
#ifdef OPLUS_FEATURE_SMARTPA_PM
add_smartpa_pm_controls(tfa98xx->component);
#endif /* OPLUS_FEATURE_SMARTPA_PM */
@@ -5083,18 +4833,12 @@ static int tfa98xx_i2c_probe(struct i2c_client *i2c,
tfa98xx->flags |= TFA98XX_FLAG_CALIBRATION_CTL;
tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE;
tfa98xx->flags |= TFA98XX_FLAG_ADAPT_NOISE_MODE; /***MCH_TO_TEST***/
#ifdef OPLUS_FEATURE_MM_FEEDBACK
g_pa_type = PA_TFA9873;
#endif
break;
case 0x74: /* tfa9874 */
pr_info("TFA9874 detected\n");
tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS;
tfa98xx->flags |= TFA98XX_FLAG_CALIBRATION_CTL;
tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE;
#ifdef OPLUS_FEATURE_MM_FEEDBACK
g_pa_type = PA_TFA9874;
#endif
break;
case 0x88: /* tfa9888 */
pr_info("TFA9888 detected\n");

View File

@@ -22,9 +22,6 @@
#include "wcd-mbhc-adc.h"
#include <asoc/wcd-mbhc-v2.h>
#include <asoc/pdata.h>
#ifdef OPLUS_FEATURE_MM_FEEDBACK
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif
#define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700
#define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75
@@ -819,10 +816,6 @@ static void wcd_correct_swch_plug(struct work_struct *work)
enum wcd_mbhc_plug_type plug_type_second = MBHC_PLUG_TYPE_INVALID;
int output_mv_second = 0;
#endif /* OPLUS_ARCH_EXTENDS */
#ifdef OPLUS_FEATURE_MM_FEEDBACK
int retry = 0;
char buf[MM_KEVENT_MAX_PAYLOAD_SIZE] = {0};
#endif
#ifdef OPLUS_ARCH_EXTENDS
#undef pr_debug
@@ -993,10 +986,6 @@ correct_plug_type:
is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(
mbhc->component);
#ifdef OPLUS_FEATURE_MM_FEEDBACK
retry++;
#endif /* OPLUS_FEATURE_MM_FEEDBACK */
#ifdef OPLUS_ARCH_EXTENDS
if (mbhc->need_cross_conn) {
#endif /* OPLUS_ARCH_EXTENDS */
@@ -1277,14 +1266,6 @@ exit:
mbhc->mbhc_cb->lock_sleep(mbhc, false);
#ifdef OPLUS_FEATURE_MM_FEEDBACK
if ((plug_type != MBHC_PLUG_TYPE_HEADSET) &&
(plug_type != MBHC_PLUG_TYPE_HEADPHONE)) {
scnprintf(buf, sizeof(buf) - 1, "func@@%s$$plug_type@@%d$$output_mv@@%d$$retry@@%d",
__func__, plug_type, output_mv, retry);
upload_mm_fb_kevent_to_atlas_limit(OPLUS_AUDIO_EVENTID_HEADSET_DET, buf, MM_FB_KEY_RATELIMIT_1MIN);
}
#endif /* OPLUS_FEATURE_MM_FEEDBACK */
pr_debug("%s: leave\n", __func__);
}

View File

@@ -22,9 +22,6 @@
#include "dsi_panel.h"
#include "sde_dbg.h"
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif /* OPLUS_BUG_STABILITY */
#if defined(OPLUS_FEATURE_PXLW_IRIS5)
#include "iris/dsi_iris5_api.h"
#endif
@@ -53,7 +50,6 @@
do { \
DRM_DEV_ERROR(NULL, "[msm-dsi-error]: %s: "\
fmt, c ? c->name : "inv", ##__VA_ARGS__); \
mm_fb_display_kevent_named(MM_FB_KEY_RATELIMIT_1H, fmt, ##__VA_ARGS__); \
} while(0)
#endif /* OPLUS_BUG_STABILITY */
@@ -378,10 +374,7 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work)
dsi_ctrl->irq_info.irq_stat_refcount[DSI_SINT_CMD_MODE_DMA_DONE]);
dsi_ctrl_disable_status_interrupt(dsi_ctrl,
DSI_SINT_CMD_MODE_DMA_DONE);
mm_fb_display_kevent("DisplayDriverID@@405$$", MM_FB_KEY_RATELIMIT_NONE, "dma_tx irq trigger fixup irq status=%x", status);
}
mm_fb_display_kevent("DisplayDriverID@@413$$", MM_FB_KEY_RATELIMIT_1H, "dma_tx irq trigger err irq status=%x", status);
#endif
} else {
DSI_CTRL_ERR(dsi_ctrl,

View File

@@ -22,12 +22,10 @@
#ifdef OPLUS_BUG_STABILITY
#undef DSI_CTRL_HW_ERR
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#define DSI_CTRL_HW_ERR(c, fmt, ...) \
do { \
DRM_DEV_ERROR(NULL, "[msm-dsi-error]: DSI_%d: "\
fmt, c ? c->index : -1, ##__VA_ARGS__); \
mm_fb_display_kevent_named(MM_FB_KEY_RATELIMIT_1H, fmt, ##__VA_ARGS__); \
} while(0)
#endif /* OPLUS_BUG_STABILITY */

View File

@@ -53,11 +53,9 @@
##__VA_ARGS__)
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#define DSI_MM_ERR(fmt, ...) \
do { \
DRM_DEV_ERROR(NULL, "[msm-dsi-error]: " fmt, ##__VA_ARGS__); \
mm_fb_display_kevent_named(MM_FB_KEY_RATELIMIT_1H, fmt, ##__VA_ARGS__); \
} while(0)
#endif /* OPLUS_BUG_STABILITY */

View File

@@ -34,7 +34,6 @@
#include "iris/dsi_iris5_api.h"
#endif
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#include <linux/msm_drm_notify.h>
#include <linux/notifier.h>
#include "oplus_display_private_api.h"
@@ -801,7 +800,6 @@ static bool dsi_display_validate_reg_read(struct dsi_panel *panel)
for (i = 0; i < len; ++i)
cnt += scnprintf(payload + cnt, sizeof(payload) - cnt, "[%02x] ", config->return_buf[i]);
DRM_ERROR("ESD check failed: %s\n", payload);
mm_fb_display_kevent(payload, MM_FB_KEY_RATELIMIT_1H, "ESD check failed");
}
#endif /*OPLUS_BUG_STABILITY*/

View File

@@ -23,12 +23,10 @@
p ? p->index : -1, ##__VA_ARGS__)
#ifdef OPLUS_BUG_STABILITY
#undef DSI_PHY_ERR
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#define DSI_PHY_ERR(p, fmt, ...) \
do { \
DRM_DEV_ERROR(NULL, "[msm-dsi-error]: DSI_%d: "\
fmt, p ? p->index : -1, ##__VA_ARGS__); \
mm_fb_display_kevent_named(MM_FB_KEY_RATELIMIT_1H, fmt, ##__VA_ARGS__); \
} while(0)
#endif /* OPLUS_BUG_STABILITY */

View File

@@ -18,10 +18,6 @@
#include "msm_drv.h"
#include "msm_mmu.h"
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#endif /*OPLUS_BUG_STABILITY*/
struct msm_iommu {
struct msm_mmu base;
struct iommu_domain *domain;
@@ -36,10 +32,6 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
return iommu->base.handler(iommu->base.arg, iova, flags);
pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags);
#ifdef OPLUS_BUG_STABILITY
mm_fb_display_kevent("DisplayDriverID@@404$$", MM_FB_KEY_RATELIMIT_1H, "SMMU msm fault iova=%08lx flags=%d", iova, flags);
#endif /*OPLUS_BUG_STABILITY*/
return 0;
}

View File

@@ -33,7 +33,6 @@
#ifdef OPLUS_BUG_STABILITY
#define PP_TIMEOUT_BAD_TRIALS 10
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
extern int oplus_dimlayer_fingerprint_failcount;
#endif
@@ -616,9 +615,6 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout(
phys_enc->hw_pp->idx - PINGPONG_0,
phys_enc->hw_ctl->idx - CTL_0,
pending_kickoff_cnt);
#ifdef OPLUS_BUG_STABILITY
mm_fb_display_kevent("DisplayDriverID@@409$$", MM_FB_KEY_RATELIMIT_NONE, "ppdone timeout failed pp:%d kickoff timeout", phys_enc->hw_pp->idx - PINGPONG_0);
#endif /* OPLUS_BUG_STABILITY */
SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL);
mutex_lock(phys_enc->vblank_ctl_lock);
sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
@@ -1773,9 +1769,6 @@ static int _sde_encoder_phys_cmd_handle_wr_ptr_timeout(
SDE_ERROR_CMDENC(cmd_enc,
"wr_ptr_irq wait failed, switch_te:%d\n", switch_te);
SDE_EVT32(DRMID(phys_enc->parent), switch_te, SDE_EVTLOG_ERROR);
#ifdef OPLUS_BUG_STABILITY
mm_fb_display_kevent("DisplayDriverID@@418$$", MM_FB_KEY_RATELIMIT_30MIN, "wr_ptr_irq timeout failed switch_te:%d", switch_te);
#endif
if (sde_encoder_phys_cmd_is_master(phys_enc) &&
atomic_add_unless(

View File

@@ -82,11 +82,9 @@
#define SDE_ERROR(fmt, ...) pr_err("[sde error]" fmt, ##__VA_ARGS__)
#ifdef OPLUS_BUG_STABILITY
#include <soc/oplus/system/oplus_mm_kevent_fb.h>
#define SDE_MM_ERROR(fmt, ...) \
do { \
pr_err("[sde error]" fmt, ##__VA_ARGS__); \
mm_fb_display_kevent_named(MM_FB_KEY_RATELIMIT_1H, fmt, ##__VA_ARGS__); \
} while(0)
#endif /* OPLUS_BUG_STABILITY */