452 lines
13 KiB
C
452 lines
13 KiB
C
|
/*
|
||
|
* linux/drivers/video/fbdev/exynos/panel/dpui.c
|
||
|
*
|
||
|
* Samsung Common LCD DPUI(display use info) LOGGING Driver.
|
||
|
*
|
||
|
* Copyright (c) 2016 Samsung Electronics
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License version 2 as
|
||
|
* published by the Free Software Foundation.
|
||
|
*/
|
||
|
|
||
|
#include <linux/fb.h>
|
||
|
#include <linux/notifier.h>
|
||
|
#include <linux/export.h>
|
||
|
#include "dpui.h"
|
||
|
|
||
|
/*
|
||
|
* DPUI : display use info (panel common info)
|
||
|
* DPCI : display controller info (ap dependent info)
|
||
|
*/
|
||
|
static BLOCKING_NOTIFIER_HEAD(dpui_notifier_list);
|
||
|
static BLOCKING_NOTIFIER_HEAD(dpci_notifier_list);
|
||
|
static DEFINE_MUTEX(dpui_lock);
|
||
|
|
||
|
static const char * const dpui_key_name[] = {
|
||
|
[DPUI_KEY_NONE] = "NONE",
|
||
|
/* common hw parameter */
|
||
|
[DPUI_KEY_WCRD_X] = "WCRD_X",
|
||
|
[DPUI_KEY_WCRD_Y] = "WCRD_Y",
|
||
|
[DPUI_KEY_WOFS_R] = "WOFS_R",
|
||
|
[DPUI_KEY_WOFS_G] = "WOFS_G",
|
||
|
[DPUI_KEY_WOFS_B] = "WOFS_B",
|
||
|
[DPUI_KEY_WOFS_R_ORG] = "WOFS_R_ORG",
|
||
|
[DPUI_KEY_WOFS_G_ORG] = "WOFS_G_ORG",
|
||
|
[DPUI_KEY_WOFS_B_ORG] = "WOFS_B_ORG",
|
||
|
[DPUI_KEY_LCDID1] = "LCDM_ID1",
|
||
|
[DPUI_KEY_LCDID2] = "LCDM_ID2",
|
||
|
[DPUI_KEY_LCDID3] = "LCDM_ID3",
|
||
|
[DPUI_KEY_MAID_DATE] = "MAID_DATE",
|
||
|
[DPUI_KEY_DISP_MODEL] = "DISP_MODEL",
|
||
|
[DPUI_KEY_CHIPID] = "CHIPID",
|
||
|
[DPUI_KEY_CELLID] = "CELLID",
|
||
|
[DPUI_KEY_OCTAID] = "OCTAID",
|
||
|
[DPUI_KEY_PNDSIE] = "PNDSIE",
|
||
|
[DPUI_KEY_PNELVDE] = "PNELVDE",
|
||
|
[DPUI_KEY_PNVLI1E] = "PNVLI1E",
|
||
|
[DPUI_KEY_PNVLO3E] = "PNVLO3E",
|
||
|
[DPUI_KEY_PNESDE] = "PNESDE",
|
||
|
[DPUI_KEY_PNSDRE] = "PNSDRE",
|
||
|
#ifdef CONFIG_SUPPORT_POC_FLASH
|
||
|
[DPUI_KEY_PNPOCT] = "PNPOCT",
|
||
|
[DPUI_KEY_PNPOCF] = "PNPOCF",
|
||
|
[DPUI_KEY_PNPOCI] = "PNPOCI",
|
||
|
[DPUI_KEY_PNPOCI_ORG] = "PNPOCI_ORG",
|
||
|
[DPUI_KEY_PNPOC_ER_TRY] = "PNPOC_ER_T",
|
||
|
[DPUI_KEY_PNPOC_ER_FAIL] = "PNPOC_ER_F",
|
||
|
[DPUI_KEY_PNPOC_WR_TRY] = "PNPOC_WR_T",
|
||
|
[DPUI_KEY_PNPOC_WR_FAIL] = "PNPOC_WR_F",
|
||
|
[DPUI_KEY_PNPOC_RD_TRY] = "PNPOC_RD_T",
|
||
|
[DPUI_KEY_PNPOC_RD_FAIL] = "PNPOC_RD_F",
|
||
|
#endif
|
||
|
[DPUI_KEY_UB_CON] = "UB_CON",
|
||
|
|
||
|
/* dependent on processor */
|
||
|
[DPUI_KEY_EXY_SWRCV] = "EXY_SWRCV",
|
||
|
};
|
||
|
|
||
|
static const char * const dpui_type_name[] = {
|
||
|
[DPUI_TYPE_NONE] = "NONE",
|
||
|
/* common hw parameter */
|
||
|
[DPUI_TYPE_PANEL] = "PANEL",
|
||
|
/* dependent on processor */
|
||
|
[DPUI_TYPE_CTRL] = "CTRL",
|
||
|
};
|
||
|
|
||
|
static struct dpui_info dpui = {
|
||
|
.pdata = NULL,
|
||
|
.field = {
|
||
|
/* common hw parameter */
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WCRD_X),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WCRD_Y),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_R),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_G),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_B),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_R_ORG),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_G_ORG),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "0", DPUI_KEY_WOFS_B_ORG),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-1", DPUI_KEY_LCDID1),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-1", DPUI_KEY_LCDID2),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-1", DPUI_KEY_LCDID3),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_STR, DPUI_AUTO_CLEAR_OFF, "19000000 000000", DPUI_KEY_MAID_DATE),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_STR, DPUI_AUTO_CLEAR_OFF, "NONE", DPUI_KEY_DISP_MODEL),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_STR, DPUI_AUTO_CLEAR_OFF, "0x0000000000", DPUI_KEY_CHIPID),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_STR, DPUI_AUTO_CLEAR_OFF, "0000000000000000000000", DPUI_KEY_CELLID),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_STR, DPUI_AUTO_CLEAR_OFF, "00000000000000000000000", DPUI_KEY_OCTAID),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNDSIE),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNELVDE),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNVLI1E),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNVLO3E),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNESDE),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNSDRE),
|
||
|
#ifdef CONFIG_SUPPORT_POC_FLASH
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-1", DPUI_KEY_PNPOCT),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-1", DPUI_KEY_PNPOCF),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-100", DPUI_KEY_PNPOCI),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_S32, DPUI_AUTO_CLEAR_OFF, "-100", DPUI_KEY_PNPOCI_ORG),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_ER_TRY),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_ER_FAIL),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_WR_TRY),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_WR_FAIL),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_RD_TRY),
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_PNPOC_RD_FAIL),
|
||
|
#endif
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_PANEL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_UB_CON),
|
||
|
|
||
|
/* dependent on processor */
|
||
|
DPUI_FIELD_INIT(DPUI_LOG_LEVEL_INFO, DPUI_TYPE_CTRL, DPUI_VAR_U32, DPUI_AUTO_CLEAR_ON, "0", DPUI_KEY_EXY_SWRCV),
|
||
|
},
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* dpui_logging_notify - notify clients of fb_events
|
||
|
* @val: dpui log type
|
||
|
* @v : data
|
||
|
*
|
||
|
*/
|
||
|
void dpui_logging_notify(unsigned long val, enum dpui_type type, void *v)
|
||
|
{
|
||
|
if (type == DPUI_TYPE_CTRL)
|
||
|
blocking_notifier_call_chain(&dpci_notifier_list, val, v);
|
||
|
else
|
||
|
blocking_notifier_call_chain(&dpui_notifier_list, val, v);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(dpui_logging_notify);
|
||
|
|
||
|
/**
|
||
|
* dpui_logging_register - register a client notifier
|
||
|
* @n: notifier block to callback on events
|
||
|
*/
|
||
|
int dpui_logging_register(struct notifier_block *n, enum dpui_type type)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
if (type <= DPUI_TYPE_NONE || type >= MAX_DPUI_TYPE) {
|
||
|
pr_err("%s out of dpui_type range (%d)\n", __func__, type);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (type == DPUI_TYPE_CTRL)
|
||
|
ret = blocking_notifier_chain_register(&dpci_notifier_list, n);
|
||
|
else
|
||
|
ret = blocking_notifier_chain_register(&dpui_notifier_list, n);
|
||
|
if (ret < 0) {
|
||
|
pr_err("%s: blocking_notifier_chain_register error(%d)\n",
|
||
|
__func__, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
pr_info("%s register type %s\n", __func__, dpui_type_name[type]);
|
||
|
return 0;
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(dpui_logging_register);
|
||
|
|
||
|
/**
|
||
|
* dpui_logging_unregister - unregister a client notifier
|
||
|
* @n: notifier block to callback on events
|
||
|
*/
|
||
|
int dpui_logging_unregister(struct notifier_block *n)
|
||
|
{
|
||
|
return blocking_notifier_chain_unregister(&dpui_notifier_list, n);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(dpui_logging_unregister);
|
||
|
|
||
|
static bool is_dpui_var_u32(enum dpui_key key)
|
||
|
{
|
||
|
return (dpui.field[key].var_type == DPUI_VAR_U32);
|
||
|
}
|
||
|
|
||
|
void update_dpui_log(enum dpui_log_level level, enum dpui_type type)
|
||
|
{
|
||
|
if (level < 0 || level >= MAX_DPUI_LOG_LEVEL) {
|
||
|
pr_err("%s invalid log level %d\n", __func__, level);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dpui_logging_notify(level, type, &dpui);
|
||
|
pr_info("%s update dpui log(%d) done\n",
|
||
|
__func__, level);
|
||
|
}
|
||
|
|
||
|
void clear_dpui_log(enum dpui_log_level level, enum dpui_type type)
|
||
|
{
|
||
|
size_t i;
|
||
|
|
||
|
if (level < 0 || level >= MAX_DPUI_LOG_LEVEL) {
|
||
|
pr_err("%s invalid log level %d\n", __func__, level);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
for (i = 0; i < ARRAY_SIZE(dpui.field); i++) {
|
||
|
if (dpui.field[i].type != type)
|
||
|
continue;
|
||
|
if (dpui.field[i].auto_clear)
|
||
|
dpui.field[i].initialized = false;
|
||
|
}
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
pr_info("%s clear dpui log(%d) done\n",
|
||
|
__func__, level);
|
||
|
}
|
||
|
|
||
|
static int __get_dpui_field(enum dpui_key key, char *buf)
|
||
|
{
|
||
|
if (!buf) {
|
||
|
pr_err("%s buf is null\n", __func__);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (!dpui.field[key].initialized) {
|
||
|
pr_debug("%s DPUI:%s not initialized, so use default value\n",
|
||
|
__func__, dpui_key_name[key]);
|
||
|
return snprintf(buf, MAX_DPUI_KEY_LEN + MAX_DPUI_VAL_LEN,
|
||
|
"\"%s\":\"%s\"", dpui_key_name[key], dpui.field[key].default_value);
|
||
|
}
|
||
|
|
||
|
return snprintf(buf, MAX_DPUI_KEY_LEN + MAX_DPUI_VAL_LEN,
|
||
|
"\"%s\":\"%s\"", dpui_key_name[key], dpui.field[key].buf);
|
||
|
}
|
||
|
|
||
|
void print_dpui_field(enum dpui_key key)
|
||
|
{
|
||
|
char tbuf[MAX_DPUI_KEY_LEN + MAX_DPUI_VAL_LEN];
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
__get_dpui_field(key, tbuf);
|
||
|
pr_info("DPUI: %s\n", tbuf);
|
||
|
}
|
||
|
|
||
|
static int __set_dpui_field(enum dpui_key key, char *buf, int size)
|
||
|
{
|
||
|
if (!buf) {
|
||
|
pr_err("%s buf is null\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (size > MAX_DPUI_VAL_LEN - 1) {
|
||
|
pr_err("%s exceed dpui value size (%d)\n", __func__, size);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
memcpy(dpui.field[key].buf, buf, size);
|
||
|
dpui.field[key].buf[size] = '\0';
|
||
|
dpui.field[key].initialized = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int __get_dpui_u32_field(enum dpui_key key, u32 *value)
|
||
|
{
|
||
|
int rc, cur_val;
|
||
|
|
||
|
if (value == NULL) {
|
||
|
pr_err("%s invalid value pointer\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
rc = kstrtouint(dpui.field[key].buf, 0, &cur_val);
|
||
|
if (rc < 0) {
|
||
|
pr_err("%s failed to get value\n", __func__);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
*value = cur_val;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int __set_dpui_u32_field(enum dpui_key key, u32 value)
|
||
|
{
|
||
|
char tbuf[MAX_DPUI_VAL_LEN];
|
||
|
int size;
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (!is_dpui_var_u32(key)) {
|
||
|
pr_err("%s invalid type %d\n", __func__, dpui.field[key].var_type);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
size = snprintf(tbuf, MAX_DPUI_VAL_LEN, "%u", value);
|
||
|
if (size > MAX_DPUI_VAL_LEN) {
|
||
|
pr_err("%s exceed dpui value size (%d)\n", __func__, size);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
__set_dpui_field(key, tbuf, size);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int __inc_dpui_u32_field(enum dpui_key key, u32 value)
|
||
|
{
|
||
|
int ret;
|
||
|
u32 cur_val = 0;
|
||
|
|
||
|
if (!DPUI_VALID_KEY(key)) {
|
||
|
pr_err("%s out of dpui_key range (%d)\n", __func__, key);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (!is_dpui_var_u32(key)) {
|
||
|
pr_err("%s invalid type %d\n", __func__, dpui.field[key].var_type);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (dpui.field[key].initialized) {
|
||
|
ret = __get_dpui_u32_field(key, &cur_val);
|
||
|
if (ret < 0) {
|
||
|
pr_err("%s failed to get u32 field (%d)\n", __func__, ret);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
__set_dpui_u32_field(key, cur_val + value);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int get_dpui_field(enum dpui_key key, char *buf)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
ret = __get_dpui_field(key, buf);
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int set_dpui_field(enum dpui_key key, char *buf, int size)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
ret = __set_dpui_field(key, buf, size);
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int get_dpui_u32_field(enum dpui_key key, u32 *value)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
ret = __get_dpui_u32_field(key, value);
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int set_dpui_u32_field(enum dpui_key key, u32 value)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
ret = __set_dpui_u32_field(key, value);
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int inc_dpui_u32_field(enum dpui_key key, u32 value)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
ret = __inc_dpui_u32_field(key, value);
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int __get_dpui_log(char *buf, enum dpui_log_level level, enum dpui_type type)
|
||
|
{
|
||
|
int i, ret, len = 0;
|
||
|
char tbuf[MAX_DPUI_KEY_LEN + MAX_DPUI_VAL_LEN];
|
||
|
|
||
|
if (!buf) {
|
||
|
pr_err("%s buf is null\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (level < 0 || level >= MAX_DPUI_LOG_LEVEL) {
|
||
|
pr_err("%s invalid log level %d\n", __func__, level);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
mutex_lock(&dpui_lock);
|
||
|
for (i = DPUI_KEY_NONE + 1; i < MAX_DPUI_KEY; i++) {
|
||
|
if (level != DPUI_LOG_LEVEL_ALL && dpui.field[i].level != level) {
|
||
|
pr_warn("%s DPUI:%s different log level %d %d\n",
|
||
|
__func__, dpui_key_name[dpui.field[i].key],
|
||
|
dpui.field[i].level, level);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (type != dpui.field[i].type)
|
||
|
continue;
|
||
|
|
||
|
ret = __get_dpui_field(i, tbuf);
|
||
|
if (ret == 0)
|
||
|
continue;
|
||
|
|
||
|
if (len)
|
||
|
len += snprintf(buf + len, 3, ",");
|
||
|
len += snprintf(buf + len, MAX_DPUI_KEY_LEN + MAX_DPUI_VAL_LEN,
|
||
|
"%s", tbuf);
|
||
|
}
|
||
|
mutex_unlock(&dpui_lock);
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
int get_dpui_log(char *buf, enum dpui_log_level level, enum dpui_type type)
|
||
|
{
|
||
|
return __get_dpui_log(buf, level, type);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(get_dpui_log);
|