476 lines
13 KiB
C
476 lines
13 KiB
C
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
|
/*
|
||
|
|
* Copyright (c) 2019 MediaTek Inc.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#if (defined(CONFIG_MTK_HDMI_SUPPORT)) || \
|
||
|
|
(defined(CONFIG_MTK_DUAL_DISPLAY_SUPPORT) && \
|
||
|
|
(CONFIG_MTK_DUAL_DISPLAY_SUPPORT == 2))
|
||
|
|
#include <linux/string.h>
|
||
|
|
#include <linux/time.h>
|
||
|
|
#include <linux/uaccess.h>
|
||
|
|
#include <linux/debugfs.h>
|
||
|
|
#include <linux/delay.h>
|
||
|
|
/*#include <mach/mt_typedefs.h>*/
|
||
|
|
#include <linux/types.h>
|
||
|
|
/*#include <mach/mt_gpio.h>*/
|
||
|
|
/*#include <mt-plat/mt_gpio.h>*/
|
||
|
|
/* #include <cust_gpio_usage.h> */
|
||
|
|
#if defined(CONFIG_MTK_DUAL_DISPLAY_SUPPORT) && \
|
||
|
|
(CONFIG_MTK_DUAL_DISPLAY_SUPPORT == 2)
|
||
|
|
#include "m4u.h"
|
||
|
|
#endif
|
||
|
|
#include <linux/vmalloc.h>
|
||
|
|
#include <linux/slab.h>
|
||
|
|
|
||
|
|
#include "ddp_hal.h"
|
||
|
|
#include "ddp_reg.h"
|
||
|
|
#include "ddp_info.h"
|
||
|
|
#include "extd_hdmi.h"
|
||
|
|
#include "external_display.h"
|
||
|
|
#include "extd_multi_control.h"
|
||
|
|
#include "mtk_disp_mgr.h"
|
||
|
|
#include "DpDataType.h"
|
||
|
|
#include "disp_dts_gpio.h"
|
||
|
|
|
||
|
|
static const char STR_HELP[] =
|
||
|
|
"\n"
|
||
|
|
" USAGE\n"
|
||
|
|
" echo [ACTION]... > /d/extd\n"
|
||
|
|
"\n"
|
||
|
|
" ACTION\n"
|
||
|
|
" fakecablein:[enable|disable]\n"
|
||
|
|
" fake mhl cable in/out\n"
|
||
|
|
"\n"
|
||
|
|
" echo [ACTION]... > /d/extd\n"
|
||
|
|
"\n"
|
||
|
|
" ACTION\n"
|
||
|
|
" force_res:0xffff\n"
|
||
|
|
" fix resolution or 3d enable(high 16 bit)\n"
|
||
|
|
"\n";
|
||
|
|
|
||
|
|
#if defined(CONFIG_MTK_DUAL_DISPLAY_SUPPORT) && \
|
||
|
|
(CONFIG_MTK_DUAL_DISPLAY_SUPPORT == 2)
|
||
|
|
#define LCM_WIDTH 1080
|
||
|
|
#define LCM_HEIGHT 1920
|
||
|
|
#define BUFFER_COUNT 1
|
||
|
|
|
||
|
|
unsigned long buffer_va, buffer_mva;
|
||
|
|
unsigned long buffer_va_1, buffer_mva_1;
|
||
|
|
|
||
|
|
static int test_allocate_buffer(void)
|
||
|
|
{
|
||
|
|
m4u_client_t *client = NULL;
|
||
|
|
int ret = 0;
|
||
|
|
int pixelSize = LCM_WIDTH * LCM_HEIGHT;
|
||
|
|
int imageSize = pixelSize * 4;
|
||
|
|
int bufferSize = imageSize * BUFFER_COUNT;
|
||
|
|
|
||
|
|
EXTDMSG("%s\n", __func__);
|
||
|
|
if (buffer_va) {
|
||
|
|
EXTDMSG("buffer has allocated, return in %d\n", __LINE__);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
buffer_va = (unsigned long)vmalloc(bufferSize);
|
||
|
|
buffer_va_1 = (unsigned long)vmalloc(bufferSize);
|
||
|
|
if (!buffer_va || !buffer_va_1) {
|
||
|
|
EXTDMSG("vmalloc %d bytes fail!!!\n", bufferSize);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
client = m4u_create_client();
|
||
|
|
ret =
|
||
|
|
m4u_alloc_mva(client, M4U_PORT_DISP_OVL1, buffer_va, 0, bufferSize,
|
||
|
|
M4U_PROT_READ | M4U_PROT_WRITE, 0,
|
||
|
|
(unsigned int *)(&buffer_mva));
|
||
|
|
ret =
|
||
|
|
m4u_alloc_mva(client, M4U_PORT_DISP_OVL1, buffer_va_1, 0,
|
||
|
|
bufferSize, M4U_PROT_READ | M4U_PROT_WRITE, 0,
|
||
|
|
(unsigned int *)(&buffer_mva_1));
|
||
|
|
|
||
|
|
EXTDMSG("buffer_va:0x%lx, buffer_mva=0x%lx, size %d\n", buffer_va,
|
||
|
|
buffer_mva, bufferSize);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void draw_block(unsigned long addr, unsigned int x, unsigned int y,
|
||
|
|
unsigned int w, unsigned int h, unsigned int color)
|
||
|
|
{
|
||
|
|
int i = 0;
|
||
|
|
int j = 0;
|
||
|
|
unsigned long start_addr = addr + LCM_WIDTH * 4 * y + x * 4;
|
||
|
|
|
||
|
|
for (j = 0; j < h; j++) {
|
||
|
|
for (i = 0; i < w; i++)
|
||
|
|
*(unsigned int *)(start_addr + i * 4 +
|
||
|
|
j * LCM_WIDTH * 4) = color;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static int internal_test(unsigned long va, unsigned int w, unsigned int h,
|
||
|
|
unsigned int odd)
|
||
|
|
{
|
||
|
|
unsigned int i = 0;
|
||
|
|
unsigned int color = 0;
|
||
|
|
int _internal_test_block_h = 240;
|
||
|
|
int _internal_test_block_w = 216;
|
||
|
|
int block_cnts = 0;
|
||
|
|
|
||
|
|
block_cnts = w * h / _internal_test_block_h / _internal_test_block_w;
|
||
|
|
|
||
|
|
/* this is for debug */
|
||
|
|
EXTDMSG("_mtkfb_internal_test, block counts:%d\n", block_cnts);
|
||
|
|
for (i = 0; i < block_cnts; i++) {
|
||
|
|
color = ((i + odd) & 0x1) * 0xff;
|
||
|
|
/* color += ((i&0x2)>>1)*0xff00; */
|
||
|
|
/* color += ((i&0x4)>>2)*0xff0000; */
|
||
|
|
color += 0xff000000U;
|
||
|
|
draw_block(va,
|
||
|
|
i % (w / _internal_test_block_w) *
|
||
|
|
_internal_test_block_w,
|
||
|
|
i / (w / _internal_test_block_w) *
|
||
|
|
_internal_test_block_h, _internal_test_block_w,
|
||
|
|
_internal_test_block_h, color);
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void config_ovl(struct disp_frame_cfg_t *cfg, unsigned int offset)
|
||
|
|
{
|
||
|
|
unsigned long pa;
|
||
|
|
|
||
|
|
cfg->setter = SESSION_USER_HWC;
|
||
|
|
cfg->session_id = 0x20003;
|
||
|
|
cfg->input_layer_num = 1;
|
||
|
|
cfg->tigger_mode = TRIGGER_NORMAL;
|
||
|
|
cfg->mode = DISP_SESSION_DIRECT_LINK_MODE;
|
||
|
|
|
||
|
|
pa = offset ? buffer_mva_1 : buffer_mva;
|
||
|
|
|
||
|
|
memset(&(cfg->input_cfg[0]), 0, sizeof(struct disp_input_config));
|
||
|
|
cfg->input_cfg[0].layer_id = 0;
|
||
|
|
cfg->input_cfg[0].layer_enable = 1;
|
||
|
|
cfg->input_cfg[0].src_fmt = DISP_FORMAT_BGRA8888;
|
||
|
|
cfg->input_cfg[0].src_phy_addr = (void *)pa;
|
||
|
|
cfg->input_cfg[0].src_offset_x = 0;
|
||
|
|
cfg->input_cfg[0].src_offset_y = 0;
|
||
|
|
cfg->input_cfg[0].src_width = LCM_WIDTH;
|
||
|
|
cfg->input_cfg[0].src_height = LCM_HEIGHT;
|
||
|
|
cfg->input_cfg[0].src_pitch = LCM_WIDTH;
|
||
|
|
cfg->input_cfg[0].tgt_offset_x = 0;
|
||
|
|
cfg->input_cfg[0].tgt_offset_y = 0;
|
||
|
|
cfg->input_cfg[0].tgt_width = LCM_WIDTH;
|
||
|
|
cfg->input_cfg[0].tgt_height = LCM_HEIGHT;
|
||
|
|
cfg->input_cfg[0].alpha_enable = 1;
|
||
|
|
cfg->input_cfg[0].alpha = 0xff;
|
||
|
|
cfg->input_cfg[0].ext_sel_layer = -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static void process_dbg_opt(const char *opt)
|
||
|
|
{
|
||
|
|
if (strncmp(opt, "extd_mobile:", 12) == 0) {
|
||
|
|
if (strncmp(opt + 12, "on", 2) == 0)
|
||
|
|
g_extd_mobilelog = 1;
|
||
|
|
else if (strncmp(opt + 12, "off", 3) == 0)
|
||
|
|
g_extd_mobilelog = 0;
|
||
|
|
} else if (strncmp(opt, "on", 2) == 0) {
|
||
|
|
#if defined(CONFIG_MTK_HDMI_SUPPORT)
|
||
|
|
hdmi_power_on();
|
||
|
|
} else if (strncmp(opt, "off", 3) == 0)
|
||
|
|
hdmi_power_off();
|
||
|
|
else if (strncmp(opt, "suspend", 7) == 0)
|
||
|
|
hdmi_suspend();
|
||
|
|
else if (strncmp(opt, "resume", 6) == 0)
|
||
|
|
hdmi_resume();
|
||
|
|
else if (strncmp(opt, "fakecablein:", 12) == 0) {
|
||
|
|
if (strncmp(opt + 12, "enable", 6) == 0)
|
||
|
|
hdmi_cable_fake_plug_in();
|
||
|
|
else if (strncmp(opt + 12, "disable", 7) == 0)
|
||
|
|
hdmi_cable_fake_plug_out();
|
||
|
|
else
|
||
|
|
goto Error;
|
||
|
|
} else if (strncmp(opt, "force_res:", 10) == 0) {
|
||
|
|
char *p = NULL;
|
||
|
|
unsigned int res = 0;
|
||
|
|
int ret = 0;
|
||
|
|
|
||
|
|
p = (char *)opt + 10;
|
||
|
|
ret = kstrtouint(p, 0, &res);
|
||
|
|
hdmi_force_resolution(res);
|
||
|
|
} else if (strncmp(opt, "hdmireg", 7) == 0)
|
||
|
|
ext_disp_diagnose();
|
||
|
|
else if (strncmp(opt, "I2S1:", 5) == 0) {
|
||
|
|
#ifdef GPIO_MHL_I2S_OUT_WS_PIN
|
||
|
|
if (strncmp(opt + 5, "on", 2) == 0) {
|
||
|
|
pr_debug("[hdmi][Debug] Enable I2S1\n");
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_WS_PIN, GPIO_MODE_01);
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_CK_PIN, GPIO_MODE_01);
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_DAT_PIN,
|
||
|
|
GPIO_MODE_01);
|
||
|
|
} else if (strncmp(opt + 5, "off", 3) == 0) {
|
||
|
|
pr_debug("[hdmi][Debug] Disable I2S1\n");
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_WS_PIN, GPIO_MODE_02);
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_CK_PIN, GPIO_MODE_01);
|
||
|
|
mt_set_gpio_mode(GPIO_MHL_I2S_OUT_DAT_PIN,
|
||
|
|
GPIO_MODE_02);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
} else if (strncmp(opt, "forceon", 7) == 0)
|
||
|
|
hdmi_force_on(false);
|
||
|
|
else if (strncmp(opt, "extd_vsync:", 11) == 0) {
|
||
|
|
if (strncmp(opt + 11, "on", 2) == 0)
|
||
|
|
hdmi_wait_vsync_debug(1);
|
||
|
|
else if (strncmp(opt + 11, "off", 3) == 0)
|
||
|
|
hdmi_wait_vsync_debug(0);
|
||
|
|
} else if (strncmp(opt, "dumpReg", 7) == 0)
|
||
|
|
hdmi_dump_vendor_chip_register();
|
||
|
|
else if (strncmp(opt, "extd_ut:", 8) == 0) {
|
||
|
|
if (strncmp(opt + 8, "on", 2) == 0)
|
||
|
|
enable_ut = 1;
|
||
|
|
else if (strncmp(opt + 8, "off", 3) == 0)
|
||
|
|
enable_ut = 0;
|
||
|
|
} else if ((strncmp(opt, "dbgtype:", 8) == 0) ||
|
||
|
|
(strncmp(opt, "regw:", 5) == 0) ||
|
||
|
|
(strncmp(opt, "regr:", 5) == 0) ||
|
||
|
|
(strncmp(opt, "hdcp:", 5) == 0) ||
|
||
|
|
(strncmp(opt, "status", 6) == 0) ||
|
||
|
|
(strncmp(opt, "help", 4) == 0) ||
|
||
|
|
(strncmp(opt, "res:", 4) == 0) ||
|
||
|
|
(strncmp(opt, "edid", 4) == 0) ||
|
||
|
|
(strncmp(opt, "deepcolor:", 10) == 0) ||
|
||
|
|
(strncmp(opt, "irq:", 4) == 0)) {
|
||
|
|
#if defined(CONFIG_MTK_INTERNAL_HDMI_SUPPORT)
|
||
|
|
mt_hdmi_debug_write(opt);
|
||
|
|
#endif
|
||
|
|
#else
|
||
|
|
EXTDMSG("[Debug] Not enable 'CONFIG_MTK_HDMI_SUPPORT'\n");
|
||
|
|
#endif
|
||
|
|
} else if (strncmp(opt, "duallcm:on", 10) == 0) {
|
||
|
|
#if defined(CONFIG_MTK_DUAL_DISPLAY_SUPPORT) && \
|
||
|
|
(CONFIG_MTK_DUAL_DISPLAY_SUPPORT == 2)
|
||
|
|
unsigned int frame_cnts = 0;
|
||
|
|
unsigned int image_size = 0;
|
||
|
|
unsigned int created_session[5];
|
||
|
|
struct disp_session_info info;
|
||
|
|
struct disp_session_config config;
|
||
|
|
struct disp_session_vsync_config vsync_config;
|
||
|
|
struct disp_frame_cfg_t *cfg = NULL;
|
||
|
|
|
||
|
|
EXTDMSG("[Debug] dual lcm test debug duallcm:on start!!!\n");
|
||
|
|
|
||
|
|
cfg = kzalloc(sizeof(struct disp_frame_cfg_t), GFP_KERNEL);
|
||
|
|
|
||
|
|
created_session[0] = 0x20003;
|
||
|
|
config.type = 2;
|
||
|
|
config.device_id = 3;
|
||
|
|
external_display_get_info((void *)&info, 0x20003);
|
||
|
|
EXTDMSG
|
||
|
|
("[Debug] get device info, width:%d, height:%d, mode:%d\n",
|
||
|
|
info.displayWidth, info.displayHeight, info.displayMode);
|
||
|
|
EXTDMSG("[Debug] create path in +\n");
|
||
|
|
disp_create_session(&config);
|
||
|
|
external_display_switch_mode(1, created_session, 0x20003);
|
||
|
|
EXTDMSG("[Debug] create path out -\n");
|
||
|
|
|
||
|
|
if (test_allocate_buffer() < 0)
|
||
|
|
goto Error;
|
||
|
|
|
||
|
|
do {
|
||
|
|
ext_disp_wait_for_vsync((void *)&vsync_config, 0x20003);
|
||
|
|
internal_test(buffer_va, 1080, 1920, 0);
|
||
|
|
EXTDMSG("[Debug] config ovl !\n");
|
||
|
|
config_ovl(cfg, 0);
|
||
|
|
external_display_frame_cfg(cfg);
|
||
|
|
|
||
|
|
msleep(500);
|
||
|
|
|
||
|
|
ext_disp_wait_for_vsync((void *)&vsync_config, 0x20003);
|
||
|
|
image_size = LCM_WIDTH * LCM_HEIGHT * 4;
|
||
|
|
internal_test(buffer_va_1, 1080, 1920, 1);
|
||
|
|
EXTDMSG("[Debug] config ovl !\n");
|
||
|
|
config_ovl(cfg, 1);
|
||
|
|
external_display_frame_cfg(cfg);
|
||
|
|
msleep(500);
|
||
|
|
frame_cnts++;
|
||
|
|
|
||
|
|
if (frame_cnts == 15) {
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT0);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
}
|
||
|
|
} while (frame_cnts < 20);
|
||
|
|
|
||
|
|
kfree(cfg);
|
||
|
|
EXTDMSG("[Debug] dual lcm test debug duallcm:on done!!!\n");
|
||
|
|
} else if (strncmp(opt, "duallcm:suspend", 15) == 0) {
|
||
|
|
EXTDMSG
|
||
|
|
("[Debug] dual lcm test debug duallcm:suspend start!!!\n");
|
||
|
|
external_display_suspend(0x20003);
|
||
|
|
EXTDMSG
|
||
|
|
("[Debug] dual lcm test debug duallcm:suspend done!!!\n");
|
||
|
|
} else if (strncmp(opt, "lcm1_reset", 10) == 0) {
|
||
|
|
EXTDMSG("[EXTD] LCM1 reset !\n");
|
||
|
|
disp_dts_gpio_select_state(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state(DTS_GPIO_STATE_LCM1_RST_OUT0);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
} else if (strncmp(opt, "duallcm:resume", 14) == 0) {
|
||
|
|
struct disp_session_vsync_config vsync_config;
|
||
|
|
struct disp_frame_cfg_t *cfg = NULL;
|
||
|
|
unsigned int frame_cnts = 0;
|
||
|
|
unsigned int image_size = 0;
|
||
|
|
|
||
|
|
EXTDMSG
|
||
|
|
("[Debug] dual lcm test debug duallcm:resume start!!!\n");
|
||
|
|
external_display_resume(0x20003);
|
||
|
|
|
||
|
|
cfg = kzalloc(sizeof(struct disp_frame_cfg_t), GFP_KERNEL);
|
||
|
|
|
||
|
|
if (test_allocate_buffer() < 0)
|
||
|
|
goto Error;
|
||
|
|
|
||
|
|
msleep(500);
|
||
|
|
|
||
|
|
do {
|
||
|
|
ext_disp_wait_for_vsync((void *)&vsync_config, 0x20003);
|
||
|
|
internal_test(buffer_va, 1080, 1920, 0);
|
||
|
|
EXTDMSG("[Debug] config ovl !\n");
|
||
|
|
config_ovl(cfg, 0);
|
||
|
|
external_display_frame_cfg(cfg);
|
||
|
|
|
||
|
|
msleep(500);
|
||
|
|
|
||
|
|
ext_disp_wait_for_vsync((void *)&vsync_config, 0x20003);
|
||
|
|
image_size = LCM_WIDTH * LCM_HEIGHT * 4;
|
||
|
|
internal_test(buffer_va_1, 1080, 1920, 1);
|
||
|
|
EXTDMSG("[Debug] config ovl !\n");
|
||
|
|
config_ovl(cfg, 1);
|
||
|
|
external_display_frame_cfg(cfg);
|
||
|
|
msleep(500);
|
||
|
|
frame_cnts++;
|
||
|
|
|
||
|
|
if (frame_cnts == 15) {
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT0);
|
||
|
|
msleep(20);
|
||
|
|
disp_dts_gpio_select_state
|
||
|
|
(DTS_GPIO_STATE_LCM1_RST_OUT1);
|
||
|
|
}
|
||
|
|
} while (frame_cnts < 20);
|
||
|
|
|
||
|
|
kfree(cfg);
|
||
|
|
|
||
|
|
EXTDMSG("[Debug] dual lcm test debug duallcm:resume done!!!\n");
|
||
|
|
} else if (strncmp(opt, "duallcm:off", 11) == 0) {
|
||
|
|
struct disp_session_config config;
|
||
|
|
|
||
|
|
config.session_id = 0x20003;
|
||
|
|
|
||
|
|
EXTDMSG("[Debug] deinit path in +\n");
|
||
|
|
/* LCM needn't destroy session */
|
||
|
|
disp_destroy_session(&config);
|
||
|
|
EXTDMSG("[Debug] dual lcm test debug duallcm:off!!!\n");
|
||
|
|
#else
|
||
|
|
EXTDMSG
|
||
|
|
("[Debug] not 'CONFIG_MTK_DUAL_DISPLAY_SUPPORT=2'\n");
|
||
|
|
#endif
|
||
|
|
} else
|
||
|
|
goto Error;
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
Error:
|
||
|
|
EXTDMSG("[extd] parse command error!\n\n%s", STR_HELP);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void process_dbg_cmd(char *cmd)
|
||
|
|
{
|
||
|
|
char *tok;
|
||
|
|
|
||
|
|
EXTDMSG("[extd] %s\n", cmd);
|
||
|
|
|
||
|
|
while ((tok = strsep(&cmd, " ")) != NULL)
|
||
|
|
process_dbg_opt(tok);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Debug FileSystem Routines */
|
||
|
|
struct dentry *extd_dbgfs;
|
||
|
|
|
||
|
|
static int debug_open(struct inode *inode, struct file *file)
|
||
|
|
{
|
||
|
|
file->private_data = inode->i_private;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static char debug_buffer[2048];
|
||
|
|
|
||
|
|
static ssize_t debug_read(struct file *file, char __user *ubuf, size_t count,
|
||
|
|
loff_t *ppos)
|
||
|
|
{
|
||
|
|
const int debug_bufmax = sizeof(debug_buffer) - 1;
|
||
|
|
int n = 0;
|
||
|
|
|
||
|
|
n += scnprintf(debug_buffer + n, debug_bufmax - n, STR_HELP);
|
||
|
|
debug_buffer[n++] = 0;
|
||
|
|
|
||
|
|
return simple_read_from_buffer(ubuf, count, ppos, debug_buffer, n);
|
||
|
|
}
|
||
|
|
|
||
|
|
static ssize_t debug_write(struct file *file, const char __user *ubuf,
|
||
|
|
size_t count, loff_t *ppos)
|
||
|
|
{
|
||
|
|
const int debug_bufmax = sizeof(debug_buffer) - 1;
|
||
|
|
size_t ret;
|
||
|
|
|
||
|
|
ret = count;
|
||
|
|
|
||
|
|
if (count > debug_bufmax)
|
||
|
|
count = debug_bufmax;
|
||
|
|
|
||
|
|
if (copy_from_user(&debug_buffer, ubuf, count))
|
||
|
|
return -EFAULT;
|
||
|
|
|
||
|
|
debug_buffer[count] = 0;
|
||
|
|
|
||
|
|
process_dbg_cmd(debug_buffer);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
static const struct file_operations debug_fops = {
|
||
|
|
.read = debug_read,
|
||
|
|
.write = debug_write,
|
||
|
|
.open = debug_open,
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
void Extd_DBG_Init(void)
|
||
|
|
{
|
||
|
|
extd_dbgfs =
|
||
|
|
debugfs_create_file("extd", S_IFREG | 0444, NULL, (void *)0,
|
||
|
|
&debug_fops);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void Extd_DBG_Deinit(void)
|
||
|
|
{
|
||
|
|
debugfs_remove(extd_dbgfs);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|