msm: mdss: debugfs: xlog: enable xlog with different flags

xlog buffer helps capture debug events, however, due to its small
size, one set of xlogs cannot solve all problems. It would be helpful
that when a specific issue happens, only one set of xlogs specific to
that particular issue is dumped and other irrelevant events can be
ignored. Accordingly different event handlers can be registered as
well for different issues.

echo 0x00 > <debugfs>/mdp/xlog/enable -> disable
echo 0x01 > <debugfs>/mdp/xlog/enable -> enable default xlogs
echo 0x80 > <debugfs>/mdp/xlog/enable -> enable all xlogs
echo 0xff > <debugfs>/mdp/xlog/enable -> enable xlogs regardless flags

Change-Id: Id1bf2a6f2009afdc63d74add652ce2722a3173a4
Signed-off-by: Huaibin Yang <huaibiny@codeaurora.org>
This commit is contained in:
Huaibin Yang 2014-10-09 16:20:38 -07:00 committed by David Keitel
parent 26a8df47f4
commit 33c3002ff1
2 changed files with 46 additions and 25 deletions

View file

@ -36,9 +36,21 @@ enum mdss_dbg_reg_dump_flag {
MDSS_REG_DUMP_IN_MEM = BIT(1),
};
#define MDSS_XLOG(...) mdss_xlog(__func__, ##__VA_ARGS__, DATA_LIMITER)
enum mdss_dbg_xlog_flag {
MDSS_XLOG_DEFAULT = BIT(0),
MDSS_XLOG_ALL = BIT(7),
};
#define MDSS_XLOG(...) mdss_xlog(__func__, MDSS_XLOG_DEFAULT, ##__VA_ARGS__, \
DATA_LIMITER)
#define MDSS_XLOG_TOUT_HANDLER(...) \
mdss_xlog_tout_handler(__func__, ##__VA_ARGS__, XLOG_TOUT_DATA_LIMITER)
mdss_xlog_tout_handler_default(__func__, ##__VA_ARGS__, \
XLOG_TOUT_DATA_LIMITER)
#define MDSS_XLOG_ALL(...) mdss_xlog(__func__, MDSS_XLOG_ALL, \
##__VA_ARGS__, DATA_LIMITER)
#define ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0)
#define ATRACE_BEGIN(name) trace_tracing_mark_write(current->tgid, name, 1)
@ -91,10 +103,9 @@ int mdss_misr_get(struct mdss_data_type *mdata, struct mdp_misr *resp,
void mdss_misr_crc_collect(struct mdss_data_type *mdata, int block_id);
int mdss_create_xlog_debug(struct mdss_debug_data *mdd);
void mdss_xlog(const char *name, ...);
void mdss_xlog_dump(void);
void mdss_xlog(const char *name, int flag, ...);
void mdss_dump_reg(struct mdss_debug_base *dbg, u32 reg_dump_flag);
void mdss_xlog_tout_handler(const char *name, ...);
void mdss_xlog_tout_handler_default(const char *name, ...);
#else
static inline int mdss_debugfs_init(struct mdss_data_type *mdata) { return 0; }
static inline int mdss_debugfs_remove(struct mdss_data_type *mdata)
@ -119,8 +130,9 @@ static inline void mdss_xlog(const char *name, ...) { }
static inline void mdss_xlog_dump(void) { }
static inline void mdss_dump_reg(struct mdss_debug_base *dbg,
u32 reg_dump_flag) { }
static inline void mdss_xlog(const char *name, int flag...) { }
static inline void mdss_dsi_debug_check_te(struct mdss_panel_data *pdata) { }
static inline void mdss_xlog_tout_handler(const char *name, ...) { }
static inline void mdss_xlog_tout_handler_default(const char *name, ...) { }
#endif
static inline int mdss_debug_register_io(const char *name,

View file

@ -75,7 +75,7 @@ int mdss_create_xlog_debug(struct mdss_debug_data *mdd)
}
debugfs_create_file("dump", 0644, mdss_dbg_xlog.xlog, NULL,
&mdss_xlog_fops);
debugfs_create_bool("enable", 0644, mdss_dbg_xlog.xlog,
debugfs_create_u32("enable", 0644, mdss_dbg_xlog.xlog,
&mdss_dbg_xlog.xlog_enable);
debugfs_create_bool("panic", 0644, mdss_dbg_xlog.xlog,
&mdss_dbg_xlog.panic_on_err);
@ -84,7 +84,13 @@ int mdss_create_xlog_debug(struct mdss_debug_data *mdd)
return 0;
}
void mdss_xlog(const char *name, ...)
static inline bool mdss_xlog_is_enabled(u32 flag)
{
return (flag & mdss_dbg_xlog.xlog_enable) ||
(flag == MDSS_XLOG_ALL && mdss_dbg_xlog.xlog_enable);
}
void mdss_xlog(const char *name, int flag, ...)
{
unsigned long flags;
int i, val = 0;
@ -92,7 +98,7 @@ void mdss_xlog(const char *name, ...)
struct tlog *log;
ktime_t time;
if (!mdss_dbg_xlog.xlog_enable)
if (!mdss_xlog_is_enabled(flag))
return;
spin_lock_irqsave(&mdss_dbg_xlog.xlock, flags);
@ -104,7 +110,7 @@ void mdss_xlog(const char *name, ...)
log->name = name;
log->data_cnt = 0;
va_start(args, name);
va_start(args, flag);
for (i = 0; i < MDSS_XLOG_MAX_DATA; i++) {
val = va_arg(args, int);
@ -124,7 +130,7 @@ void mdss_xlog(const char *name, ...)
spin_unlock_irqrestore(&mdss_dbg_xlog.xlock, flags);
}
void mdss_xlog_dump(void)
static void mdss_xlog_dump(void)
{
int i, n, d_cnt, off;
unsigned long flags;
@ -132,9 +138,6 @@ void mdss_xlog_dump(void)
struct tlog *log;
char xlog_buf[MDSS_XLOG_BUF_MAX];
if (!mdss_dbg_xlog.xlog_enable)
return;
spin_lock_irqsave(&mdss_dbg_xlog.xlock, flags);
i = mdss_dbg_xlog.first;
for (n = 0; n < MDSS_XLOG_ENTRY; n++) {
@ -156,39 +159,45 @@ void mdss_xlog_dump(void)
spin_unlock_irqrestore(&mdss_dbg_xlog.xlock, flags);
}
void mdss_xlog_tout_handler(const char *name, ...)
static void mdss_dump_reg_by_blk(const char *blk_name)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
struct mdss_debug_data *mdd = mdata->debug_inf.debug_data;
struct mdss_debug_base *blk_base, *tmp;
if (!mdd)
return;
list_for_each_entry_safe(blk_base, tmp, &mdd->base_list, head) {
if (blk_base->name &&
!strcmp(blk_base->name, blk_name))
mdss_dump_reg(blk_base,
mdss_dbg_xlog.enable_reg_dump);
}
}
void mdss_xlog_tout_handler_default(const char *name, ...)
{
int i, dead = 0;
va_list args;
char *blk_name = NULL;
if (!mdss_dbg_xlog.xlog_enable)
if (!mdss_xlog_is_enabled(MDSS_XLOG_DEFAULT))
return;
va_start(args, name);
for (i = 0; i < MDSS_XLOG_MAX_DATA; i++) {
blk_name = va_arg(args, char*);
if (IS_ERR_OR_NULL(blk_name))
break;
list_for_each_entry_safe(blk_base, tmp, &mdd->base_list, head) {
mdss_dump_reg_by_blk(blk_name);
if (blk_base->name &&
!strcmp(blk_base->name, blk_name))
mdss_dump_reg(blk_base,
mdss_dbg_xlog.enable_reg_dump);
}
if (!strcmp(blk_name, "panic"))
dead = 1;
}
va_end(args);
MDSS_XLOG(0xffff, 0xffff, 0xffff, 0xffff, 0xffff);
mdss_xlog_dump();
if (dead && mdss_dbg_xlog.panic_on_err)