disp: msm: sde: modify SDE_DBG_DUMP to use blk_mask instead of blk_name
Currently, SDE_DBG_DUMP takes any number of hw block names along with few defined strings as arguments. This set of arguments is used to determine which HW block registers needs to be dumped. Move to a blk bitmask to avoid passing a large set of arguments. The bitmask is split based on the clks required to access the HW block for ease of use. The lower 0-23 bits are used for HW blocks which can be accessed by just enabling the MDP clks. DP is kept separate as it needs DP specific clks to be enabled. Add a debugfs node through which the mask can be modified, which can be useful while using the debugfs dump option to force a panic. As part of the change, remove in-log/in-mem enable mask debugfs node for every debugbus and use a single node to control the logging mechanism for all the HW blocks debugbus. Change-Id: Ibb6354b3e3265c9911104bb0f964616eb8a898c9 Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:
413
msm/sde_dbg.c
413
msm/sde_dbg.c
@@ -23,12 +23,7 @@
|
||||
|
||||
#define DEFAULT_PANIC 1
|
||||
#define DEFAULT_REGDUMP SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_SDE SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_VBIFRT SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_DSI SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_RSC SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_LUTDMA SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_DP SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_DBGBUS_DUMP SDE_DBG_DUMP_IN_MEM
|
||||
#define DEFAULT_BASE_REG_CNT DEFAULT_MDSS_HW_BLOCK_SIZE
|
||||
#define GROUP_BYTES 4
|
||||
#define ROW_BYTES 16
|
||||
@@ -164,6 +159,7 @@ struct sde_dbg_reg_range {
|
||||
* @reg_dump: address for the mem dump if no ranges used
|
||||
* @cb: callback for external dump function, null if not defined
|
||||
* @cb_ptr: private pointer to callback function
|
||||
* @blk_id: id indicate the HW block
|
||||
*/
|
||||
struct sde_dbg_reg_base {
|
||||
struct list_head reg_base_head;
|
||||
@@ -178,6 +174,7 @@ struct sde_dbg_reg_base {
|
||||
u32 *reg_dump;
|
||||
void (*cb)(void *ptr);
|
||||
void *cb_ptr;
|
||||
u64 blk_id;
|
||||
};
|
||||
|
||||
struct sde_debug_bus_entry {
|
||||
@@ -198,13 +195,12 @@ struct sde_dbg_dsi_ctrl_list_entry {
|
||||
|
||||
struct sde_dbg_debug_bus_common {
|
||||
char *name;
|
||||
u32 enable_mask;
|
||||
bool include_in_deferred_work;
|
||||
u32 entries_size;
|
||||
u32 limited_entries_size;
|
||||
u32 *dumped_content;
|
||||
u32 content_idx;
|
||||
u32 content_size;
|
||||
u64 blk_id;
|
||||
};
|
||||
|
||||
struct sde_dbg_sde_debug_bus {
|
||||
@@ -246,13 +242,14 @@ struct sde_dbg_regbuf {
|
||||
* @dump_work: work struct for deferring register dump work to separate thread
|
||||
* @work_panic: panic after dump if internal user passed "panic" special region
|
||||
* @enable_reg_dump: whether to dump registers into memory, kernel log, or both
|
||||
* @enable_dbgbus_dump: whether to dump dbgbus into memory, kernel log, or both
|
||||
* @dbgbus_sde: debug bus structure for the sde
|
||||
* @dbgbus_vbif_rt: debug bus structure for the realtime vbif
|
||||
* @dbgbus_dsi: debug bus structure for the dsi
|
||||
* @dbgbus_rsc: debug bus structure for rscc
|
||||
* @dbgbus_lutdma: debug bus structure for the lutdma hw
|
||||
* @dbgbus_dp: debug bus structure for dp
|
||||
* @dump_all: dump all entries in register dump
|
||||
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
|
||||
* @dump_secure: dump entries excluding few as it is in secure-session
|
||||
* @regbuf: buffer data to track the register dumping in hw recovery
|
||||
* @cur_evt_index: index used for tracking event logs dump in hw recovery
|
||||
@@ -271,6 +268,7 @@ static struct sde_dbg_base {
|
||||
struct work_struct dump_work;
|
||||
bool work_panic;
|
||||
u32 enable_reg_dump;
|
||||
u32 enable_dbgbus_dump;
|
||||
|
||||
struct sde_dbg_sde_debug_bus dbgbus_sde;
|
||||
struct sde_dbg_sde_debug_bus dbgbus_vbif_rt;
|
||||
@@ -278,7 +276,7 @@ static struct sde_dbg_base {
|
||||
struct sde_dbg_sde_debug_bus dbgbus_rsc;
|
||||
struct sde_dbg_sde_debug_bus dbgbus_lutdma;
|
||||
struct sde_dbg_sde_debug_bus dbgbus_dp;
|
||||
bool dump_all;
|
||||
u64 dump_blk_mask;
|
||||
bool dump_secure;
|
||||
u32 debugfs_ctrl;
|
||||
|
||||
@@ -465,7 +463,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
|
||||
u32 *dump_addr = NULL;
|
||||
char *end_addr;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (!len_bytes || !dump_mem)
|
||||
return;
|
||||
@@ -489,14 +486,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
|
||||
dump_addr = *dump_mem;
|
||||
SDE_DBG_LOG_DUMP_ADDR(dump_name, dump_addr, len_padded, (unsigned long)(addr - base_addr));
|
||||
|
||||
if (_sde_power_check(sde_dbg_base.dump_mode)) {
|
||||
rc = pm_runtime_get_sync(sde_dbg_base.dev);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to enable power %d\n", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len_align; i++) {
|
||||
u32 x0, x4, x8, xc;
|
||||
|
||||
@@ -517,9 +506,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
|
||||
|
||||
addr += REG_DUMP_ALIGN;
|
||||
}
|
||||
|
||||
if (_sde_power_check(sde_dbg_base.dump_mode))
|
||||
pm_runtime_put_sync(sde_dbg_base.dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -582,10 +568,8 @@ static bool is_block_exclude(char **modules, char *name)
|
||||
* _sde_dump_reg_by_ranges - dump ranges or full range of the register blk base
|
||||
* @dbg: register blk base structure
|
||||
* @reg_dump_flag: dump target, memory, kernel log, or both
|
||||
* @dump_secure: flag to indicate dumping in secure-session
|
||||
*/
|
||||
static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
|
||||
u32 reg_dump_flag, bool dump_secure)
|
||||
static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg, u32 reg_dump_flag)
|
||||
{
|
||||
char *addr;
|
||||
size_t len;
|
||||
@@ -604,81 +588,48 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
|
||||
/* sort the list by start address first */
|
||||
list_sort(NULL, &dbg->sub_range_list, _sde_dump_reg_range_cmp);
|
||||
list_for_each_entry(range_node, &dbg->sub_range_list, head) {
|
||||
len = _sde_dbg_get_dump_range(&range_node->offset,
|
||||
dbg->max_offset);
|
||||
len = _sde_dbg_get_dump_range(&range_node->offset, dbg->max_offset);
|
||||
addr = dbg->base + range_node->offset.start;
|
||||
|
||||
if (dump_secure &&
|
||||
is_block_exclude((char**)exclude_modules,
|
||||
range_node->range_name))
|
||||
continue;
|
||||
|
||||
pr_debug("%s: range_base=0x%pK start=0x%x end=0x%x\n",
|
||||
range_node->range_name,
|
||||
addr, range_node->offset.start,
|
||||
range_node->range_name, addr, range_node->offset.start,
|
||||
range_node->offset.end);
|
||||
|
||||
_sde_dump_reg(range_node->range_name, reg_dump_flag,
|
||||
dbg->base, addr, len,
|
||||
&range_node->reg_dump);
|
||||
dbg->base, addr, len, &range_node->reg_dump);
|
||||
}
|
||||
} else {
|
||||
/* If there is no list to dump ranges, dump all registers */
|
||||
dev_info(sde_dbg_base.dev,
|
||||
"Ranges not found, will dump full registers\n");
|
||||
dev_info(sde_dbg_base.dev, "Ranges not found, will dump full registers\n");
|
||||
SDE_DBG_LOG_DUMP_ADDR("base", dbg->base, dbg->max_offset, 0);
|
||||
addr = dbg->base;
|
||||
len = dbg->max_offset;
|
||||
_sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len,
|
||||
&dbg->reg_dump);
|
||||
_sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len, &dbg->reg_dump);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _sde_dump_reg_by_blk - dump a named register base region
|
||||
* @blk_name: register blk name
|
||||
* _sde_dump_reg_mask - dump register regions based on mask
|
||||
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
|
||||
* @dump_secure: flag to indicate dumping in secure-session
|
||||
*/
|
||||
static void _sde_dump_reg_by_blk(const char *blk_name, bool dump_secure)
|
||||
static void _sde_dump_reg_mask(u64 dump_blk_mask, bool dump_secure)
|
||||
{
|
||||
struct sde_dbg_base *dbg_base = &sde_dbg_base;
|
||||
struct sde_dbg_reg_base *blk_base;
|
||||
|
||||
if (!dbg_base)
|
||||
return;
|
||||
|
||||
list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
|
||||
if (strlen(blk_base->name) &&
|
||||
!strcmp(blk_base->name, blk_name)) {
|
||||
_sde_dump_reg_by_ranges(blk_base,
|
||||
dbg_base->enable_reg_dump, dump_secure);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _sde_dump_reg_all - dump all register regions
|
||||
*/
|
||||
static void _sde_dump_reg_all(bool dump_secure)
|
||||
{
|
||||
struct sde_dbg_base *dbg_base = &sde_dbg_base;
|
||||
struct sde_dbg_reg_base *blk_base;
|
||||
|
||||
if (!dbg_base)
|
||||
if (!dump_blk_mask)
|
||||
return;
|
||||
|
||||
list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
|
||||
|
||||
if (!strlen(blk_base->name))
|
||||
if ((!(blk_base->blk_id & dump_blk_mask)) || (!strlen(blk_base->name)))
|
||||
continue;
|
||||
|
||||
if (dump_secure &&
|
||||
is_block_exclude((char **)exclude_modules,
|
||||
blk_base->name))
|
||||
if (dump_secure && is_block_exclude((char **)exclude_modules, blk_base->name))
|
||||
continue;
|
||||
|
||||
_sde_dump_reg_by_blk(blk_base->name, dump_secure);
|
||||
_sde_dump_reg_by_ranges(blk_base, dbg_base->enable_reg_dump);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,7 +805,7 @@ static bool _is_dbg_bus_limited_valid(struct sde_dbg_sde_debug_bus *bus,
|
||||
|
||||
static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
|
||||
struct sde_debug_bus_entry *entries, u32 bus_size,
|
||||
void __iomem *mem_base, u32 *dump_addr)
|
||||
void __iomem *mem_base, u32 *dump_addr, u32 enable_mask)
|
||||
{
|
||||
u32 status = 0;
|
||||
int i, j, k;
|
||||
@@ -864,9 +815,9 @@ static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
|
||||
if (!bus->read_tp || !bus->clear_tp)
|
||||
return;
|
||||
|
||||
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
in_log = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_LOG);
|
||||
in_log_limited = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_LOG_LIMITED);
|
||||
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
in_log = (enable_mask & SDE_DBG_DUMP_IN_LOG);
|
||||
in_log_limited = (enable_mask & SDE_DBG_DUMP_IN_LOG_LIMITED);
|
||||
|
||||
for (k = 0; k < bus_size; k++) {
|
||||
entry = entries + k;
|
||||
@@ -899,7 +850,7 @@ static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 enable_mask)
|
||||
{
|
||||
bool in_mem;
|
||||
u32 **dump_mem = NULL;
|
||||
@@ -939,7 +890,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
snprintf(name, sizeof(name), "%s-debugbus", bus->cmn.name);
|
||||
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_START);
|
||||
|
||||
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
if (in_mem && (!(*dump_mem))) {
|
||||
*dump_mem = devm_kzalloc(sde_dbg_base.dev, list_size, GFP_KERNEL);
|
||||
bus->cmn.content_size = list_size / sizeof(u32);
|
||||
@@ -947,12 +898,12 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
dump_addr = *dump_mem;
|
||||
SDE_DBG_LOG_DUMP_ADDR(bus->cmn.name, dump_addr, list_size, 0);
|
||||
|
||||
_sde_dbg_dump_bus_entry(bus, entries, bus_size, mem_base, dump_addr);
|
||||
_sde_dbg_dump_bus_entry(bus, entries, bus_size, mem_base, dump_addr, enable_mask);
|
||||
|
||||
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_END);
|
||||
}
|
||||
|
||||
static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 enable_mask)
|
||||
{
|
||||
struct sde_dbg_dsi_ctrl_list_entry *ctl_entry;
|
||||
struct list_head *list;
|
||||
@@ -982,7 +933,7 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_START);
|
||||
|
||||
mutex_lock(&sde_dbg_dsi_mutex);
|
||||
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
|
||||
if (in_mem && (!(*dump_mem))) {
|
||||
*dump_mem = devm_kzalloc(sde_dbg_base.dev, list_size, GFP_KERNEL);
|
||||
bus->cmn.content_size = list_size / sizeof(u32);
|
||||
@@ -992,7 +943,8 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
list_for_each_entry(ctl_entry, &sde_dbg_dsi_list, list) {
|
||||
SDE_DBG_LOG_DUMP_ADDR(ctl_entry->name, dump_addr, list_size / dsi_count, 0);
|
||||
|
||||
_sde_dbg_dump_bus_entry(bus, entries, bus_size, ctl_entry->base, dump_addr);
|
||||
_sde_dbg_dump_bus_entry(bus, entries, bus_size, ctl_entry->base,
|
||||
dump_addr, enable_mask);
|
||||
}
|
||||
mutex_unlock(&sde_dbg_dsi_mutex);
|
||||
|
||||
@@ -1001,42 +953,23 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
|
||||
|
||||
/**
|
||||
* _sde_dump_array - dump array of register bases
|
||||
* @blk_arr: array of register base pointers
|
||||
* @len: length of blk_arr
|
||||
* @do_panic: whether to trigger a panic after dumping
|
||||
* @name: string indicating origin of dump
|
||||
* @dump_dbgbus_sde: whether to dump the sde debug bus
|
||||
* @dump_dbgbus_vbif_rt: whether to dump the vbif rt debug bus
|
||||
* @dump_dbgbus_dsi: whether to dump the dsi debug bus
|
||||
* @dump_dbgbus_dp: whether to dump the dp debug bus
|
||||
* @dump_all: dump evtlog + regs
|
||||
* @dump_secure: flag to indicate dumping in secure-session
|
||||
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
|
||||
*/
|
||||
static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
|
||||
u32 len, bool do_panic, const char *name, bool dump_dbgbus_sde, bool dump_dbgbus_vbif_rt,
|
||||
bool dump_dbgbus_dsi, bool dump_dbgbus_dp, bool dump_all, bool dump_secure)
|
||||
static void _sde_dump_array(bool do_panic, const char *name, bool dump_secure, u64 dump_blk_mask)
|
||||
{
|
||||
int i, rc;
|
||||
int rc;
|
||||
ktime_t start, end;
|
||||
struct sde_dbg_base *dbg_base = &sde_dbg_base;
|
||||
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
mutex_lock(&dbg_base->mutex);
|
||||
|
||||
if (dump_all)
|
||||
sde_evtlog_dump_all(sde_dbg_base.evtlog);
|
||||
sde_evtlog_dump_all(dbg_base->evtlog);
|
||||
|
||||
if (dump_all || !blk_arr || !len) {
|
||||
_sde_dump_reg_all(dump_secure);
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (blk_arr[i] != NULL)
|
||||
_sde_dump_reg_by_ranges(blk_arr[i],
|
||||
sde_dbg_base.enable_reg_dump,
|
||||
dump_secure);
|
||||
}
|
||||
}
|
||||
|
||||
if (_sde_power_check(sde_dbg_base.dump_mode)) {
|
||||
rc = pm_runtime_get_sync(sde_dbg_base.dev);
|
||||
if (_sde_power_check(dbg_base->dump_mode)) {
|
||||
rc = pm_runtime_get_sync(dbg_base->dev);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to enable power %d\n", rc);
|
||||
return;
|
||||
@@ -1044,33 +977,43 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
|
||||
}
|
||||
|
||||
start = ktime_get();
|
||||
if (dump_dbgbus_sde) {
|
||||
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_sde);
|
||||
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_lutdma);
|
||||
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_rsc);
|
||||
}
|
||||
_sde_dump_reg_mask(dump_blk_mask, dump_secure);
|
||||
end = ktime_get();
|
||||
dev_info(dbg_base->dev,
|
||||
"reg-dump logging time start_us:%llu, end_us:%llu , duration_us:%llu\n",
|
||||
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end, start));
|
||||
|
||||
if (dump_dbgbus_vbif_rt)
|
||||
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_vbif_rt);
|
||||
start = ktime_get();
|
||||
if (dump_blk_mask & SDE_DBG_SDE_DBGBUS)
|
||||
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_sde, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
if (dump_dbgbus_dsi)
|
||||
_sde_dbg_dump_dsi_dbg_bus(&sde_dbg_base.dbgbus_dsi);
|
||||
if (dump_blk_mask & SDE_DBG_LUTDMA_DBGBUS)
|
||||
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_lutdma, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
if (dump_dbgbus_dp)
|
||||
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_dp);
|
||||
if (dump_blk_mask & SDE_DBG_RSC_DBGBUS)
|
||||
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_rsc, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
if (dump_blk_mask & SDE_DBG_VBIF_RT_DBGBUS)
|
||||
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_vbif_rt, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
if (dump_blk_mask & SDE_DBG_DSI_DBGBUS)
|
||||
_sde_dbg_dump_dsi_dbg_bus(&dbg_base->dbgbus_dsi, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
if (dump_blk_mask & SDE_DBG_DP_DBGBUS)
|
||||
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_dp, dbg_base->enable_dbgbus_dump);
|
||||
|
||||
end = ktime_get();
|
||||
dev_info(sde_dbg_base.dev,
|
||||
dev_info(dbg_base->dev,
|
||||
"debug-bus logging time start_us:%llu, end_us:%llu , duration_us:%llu\n",
|
||||
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end , start));
|
||||
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end, start));
|
||||
|
||||
if (_sde_power_check(sde_dbg_base.dump_mode))
|
||||
pm_runtime_put_sync(sde_dbg_base.dev);
|
||||
if (_sde_power_check(dbg_base->dump_mode))
|
||||
pm_runtime_put_sync(dbg_base->dev);
|
||||
|
||||
if (do_panic && sde_dbg_base.panic_on_err)
|
||||
if (do_panic && dbg_base->panic_on_err)
|
||||
panic(name);
|
||||
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
mutex_unlock(&dbg_base->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1079,87 +1022,36 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
|
||||
*/
|
||||
static void _sde_dump_work(struct work_struct *work)
|
||||
{
|
||||
_sde_dump_array(sde_dbg_base.req_dump_blks,
|
||||
ARRAY_SIZE(sde_dbg_base.req_dump_blks),
|
||||
sde_dbg_base.work_panic, "evtlog_workitem",
|
||||
sde_dbg_base.dbgbus_sde.cmn.include_in_deferred_work,
|
||||
sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work,
|
||||
sde_dbg_base.dbgbus_dsi.cmn.include_in_deferred_work,
|
||||
sde_dbg_base.dbgbus_dp.cmn.include_in_deferred_work,
|
||||
sde_dbg_base.dump_all, sde_dbg_base.dump_secure);
|
||||
_sde_dump_array(sde_dbg_base.work_panic, "evtlog_workitem",
|
||||
sde_dbg_base.dump_secure, sde_dbg_base.dump_blk_mask);
|
||||
}
|
||||
|
||||
void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, ...)
|
||||
void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, u64 dump_blk_mask, ...)
|
||||
{
|
||||
int i, index = 0;
|
||||
int i = 0;
|
||||
bool do_panic = false;
|
||||
bool dump_dbgbus_sde = false;
|
||||
bool dump_dbgbus_vbif_rt = false;
|
||||
bool dump_dbgbus_dsi = false;
|
||||
bool dump_dbgbus_dp = false;
|
||||
bool dump_all = false;
|
||||
bool dump_secure = false;
|
||||
va_list args;
|
||||
char *blk_name = NULL;
|
||||
struct sde_dbg_reg_base *blk_base = NULL;
|
||||
struct sde_dbg_reg_base **blk_arr;
|
||||
u32 blk_len;
|
||||
char *str = NULL;
|
||||
|
||||
if (!sde_evtlog_is_enabled(sde_dbg_base.evtlog, SDE_EVTLOG_ALWAYS))
|
||||
return;
|
||||
|
||||
if ((dump_mode == SDE_DBG_DUMP_IRQ_CTX) &&
|
||||
work_pending(&sde_dbg_base.dump_work))
|
||||
if ((dump_mode == SDE_DBG_DUMP_IRQ_CTX) && work_pending(&sde_dbg_base.dump_work))
|
||||
return;
|
||||
|
||||
blk_arr = &sde_dbg_base.req_dump_blks[0];
|
||||
blk_len = ARRAY_SIZE(sde_dbg_base.req_dump_blks);
|
||||
|
||||
memset(sde_dbg_base.req_dump_blks, 0,
|
||||
sizeof(sde_dbg_base.req_dump_blks));
|
||||
sde_dbg_base.dump_all = false;
|
||||
sde_dbg_base.dump_mode = dump_mode;
|
||||
|
||||
va_start(args, name);
|
||||
i = 0;
|
||||
while ((blk_name = va_arg(args, char*))) {
|
||||
va_start(args, dump_blk_mask);
|
||||
while ((str = va_arg(args, char*))) {
|
||||
if (i++ >= SDE_EVTLOG_MAX_DATA) {
|
||||
pr_err("could not parse all dump arguments\n");
|
||||
break;
|
||||
}
|
||||
if (IS_ERR_OR_NULL(blk_name))
|
||||
break;
|
||||
|
||||
blk_base = _sde_dump_get_blk_addr(blk_name);
|
||||
if (blk_base) {
|
||||
if (index < blk_len) {
|
||||
blk_arr[index] = blk_base;
|
||||
index++;
|
||||
} else {
|
||||
pr_err("insufficient space to to dump %s\n",
|
||||
blk_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(blk_name, "all"))
|
||||
dump_all = true;
|
||||
|
||||
if (!strcmp(blk_name, "dbg_bus"))
|
||||
dump_dbgbus_sde = true;
|
||||
|
||||
if (!strcmp(blk_name, "vbif_dbg_bus"))
|
||||
dump_dbgbus_vbif_rt = true;
|
||||
|
||||
if (!strcmp(blk_name, "dsi_dbg_bus"))
|
||||
dump_dbgbus_dsi = true;
|
||||
|
||||
if (!strcmp(blk_name, "dp_dbg_bus"))
|
||||
dump_dbgbus_dp = true;
|
||||
|
||||
if (!strcmp(blk_name, "panic"))
|
||||
if (!strcmp(str, "panic"))
|
||||
do_panic = true;
|
||||
|
||||
if (!strcmp(blk_name, "secure"))
|
||||
else if (!strcmp(str, "secure"))
|
||||
dump_secure = true;
|
||||
}
|
||||
va_end(args);
|
||||
@@ -1167,17 +1059,10 @@ void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, ...)
|
||||
if (dump_mode == SDE_DBG_DUMP_IRQ_CTX) {
|
||||
/* schedule work to dump later */
|
||||
sde_dbg_base.work_panic = do_panic;
|
||||
sde_dbg_base.dbgbus_sde.cmn.include_in_deferred_work = dump_dbgbus_sde;
|
||||
sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work = dump_dbgbus_vbif_rt;
|
||||
sde_dbg_base.dbgbus_dsi.cmn.include_in_deferred_work = dump_dbgbus_dsi;
|
||||
sde_dbg_base.dbgbus_rsc.cmn.include_in_deferred_work = dump_dbgbus_sde;
|
||||
sde_dbg_base.dbgbus_dp.cmn.include_in_deferred_work = dump_dbgbus_dp;
|
||||
sde_dbg_base.dump_all = dump_all;
|
||||
sde_dbg_base.dump_blk_mask = dump_blk_mask;
|
||||
schedule_work(&sde_dbg_base.dump_work);
|
||||
} else {
|
||||
_sde_dump_array(blk_arr, blk_len, do_panic, name, dump_dbgbus_sde,
|
||||
dump_dbgbus_vbif_rt, dump_dbgbus_dsi, dump_dbgbus_dp,
|
||||
dump_all, dump_secure);
|
||||
_sde_dump_array(do_panic, name, dump_secure, dump_blk_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1203,23 +1088,19 @@ void sde_dbg_ctrl(const char *name, ...)
|
||||
break;
|
||||
|
||||
if (!strcmp(blk_name, "stop_ftrace") &&
|
||||
sde_dbg_base.debugfs_ctrl &
|
||||
DBG_CTRL_STOP_FTRACE) {
|
||||
sde_dbg_base.debugfs_ctrl & DBG_CTRL_STOP_FTRACE) {
|
||||
pr_debug("tracing off\n");
|
||||
tracing_off();
|
||||
}
|
||||
|
||||
if (!strcmp(blk_name, "panic_underrun") &&
|
||||
sde_dbg_base.debugfs_ctrl &
|
||||
DBG_CTRL_PANIC_UNDERRUN) {
|
||||
sde_dbg_base.debugfs_ctrl & DBG_CTRL_PANIC_UNDERRUN) {
|
||||
pr_err("panic underrun\n");
|
||||
SDE_DBG_DUMP_WQ("all", "dbg_bus", "vbif_dbg_bus",
|
||||
"panic");
|
||||
SDE_DBG_DUMP_WQ(SDE_DBG_BUILT_IN_ALL, "panic");
|
||||
}
|
||||
|
||||
if (!strcmp(blk_name, "reset_hw_panic") &&
|
||||
sde_dbg_base.debugfs_ctrl &
|
||||
DBG_CTRL_RESET_HW_PANIC) {
|
||||
sde_dbg_base.debugfs_ctrl & DBG_CTRL_RESET_HW_PANIC) {
|
||||
pr_debug("reset hw panic\n");
|
||||
panic("reset_hw");
|
||||
}
|
||||
@@ -1326,8 +1207,8 @@ static ssize_t sde_evtlog_dump_read(struct file *file, char __user *buff,
|
||||
static ssize_t sde_evtlog_dump_write(struct file *file,
|
||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
_sde_dump_array(NULL, 0, sde_dbg_base.panic_on_err, "dump_debugfs",
|
||||
true, true, true, true, true, false);
|
||||
_sde_dump_array(sde_dbg_base.panic_on_err, "dump_debugfs", false,
|
||||
sde_dbg_base.dump_blk_mask);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -2146,106 +2027,61 @@ int sde_dbg_debugfs_register(struct device *dev)
|
||||
struct drm_device *ddev = platform_get_drvdata(pdev);
|
||||
struct msm_drm_private *priv = NULL;
|
||||
|
||||
if (!ddev) {
|
||||
if (!ddev || !ddev->dev_private) {
|
||||
pr_err("Invalid drm device node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv = ddev->dev_private;
|
||||
if (!priv) {
|
||||
pr_err("Invalid msm drm private node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
debugfs_root = debugfs_create_dir("debug",
|
||||
ddev->primary->debugfs_root);
|
||||
debugfs_root = debugfs_create_dir("debug", ddev->primary->debugfs_root);
|
||||
if (IS_ERR_OR_NULL(debugfs_root)) {
|
||||
pr_err("debugfs_root create_dir fail, error %ld\n",
|
||||
PTR_ERR(debugfs_root));
|
||||
pr_err("debugfs_root create_dir fail, error %ld\n", PTR_ERR(debugfs_root));
|
||||
priv->debug_root = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->debug_root = debugfs_root;
|
||||
|
||||
debugfs_create_file("dbg_ctrl", 0600, debugfs_root, NULL,
|
||||
&sde_dbg_ctrl_fops);
|
||||
debugfs_create_file("dump", 0600, debugfs_root, NULL,
|
||||
&sde_evtlog_fops);
|
||||
debugfs_create_u32("enable", 0600, debugfs_root,
|
||||
&(sde_dbg_base.evtlog->enable));
|
||||
debugfs_create_u32("panic", 0600, debugfs_root,
|
||||
&sde_dbg_base.panic_on_err);
|
||||
debugfs_create_u32("reg_dump", 0600, debugfs_root,
|
||||
&sde_dbg_base.enable_reg_dump);
|
||||
debugfs_create_file("recovery_reg", 0400, debugfs_root, NULL,
|
||||
&sde_recovery_reg_fops);
|
||||
debugfs_create_file("dbg_ctrl", 0600, debugfs_root, NULL, &sde_dbg_ctrl_fops);
|
||||
debugfs_create_file("dump", 0600, debugfs_root, NULL, &sde_evtlog_fops);
|
||||
debugfs_create_file("recovery_reg", 0400, debugfs_root, NULL, &sde_recovery_reg_fops);
|
||||
|
||||
if (dbg->dbgbus_sde.entries) {
|
||||
debugfs_create_u32("enable", 0600, debugfs_root, &(sde_dbg_base.evtlog->enable));
|
||||
debugfs_create_u32("panic", 0600, debugfs_root, &sde_dbg_base.panic_on_err);
|
||||
debugfs_create_u32("reg_dump", 0600, debugfs_root, &sde_dbg_base.enable_reg_dump);
|
||||
debugfs_create_u32("dbgbus_dump", 0600, debugfs_root, &sde_dbg_base.enable_dbgbus_dump);
|
||||
debugfs_create_u64("reg_dump_blk_mask", 0600, debugfs_root, &sde_dbg_base.dump_blk_mask);
|
||||
|
||||
if (dbg->dbgbus_sde.entries)
|
||||
debugfs_create_file("recovery_dbgbus", 0400, debugfs_root, NULL,
|
||||
&sde_recovery_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_sde.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_sde.cmn.enable_mask);
|
||||
}
|
||||
|
||||
if (dbg->dbgbus_vbif_rt.entries) {
|
||||
if (dbg->dbgbus_vbif_rt.entries)
|
||||
debugfs_create_file("recovery_vbif_dbgbus", 0400, debugfs_root,
|
||||
NULL, &sde_recovery_vbif_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_vbif_rt.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_vbif_rt.cmn.enable_mask);
|
||||
}
|
||||
|
||||
if (dbg->dbgbus_dsi.entries) {
|
||||
if (dbg->dbgbus_dsi.entries)
|
||||
debugfs_create_file("recovery_dsi_dbgbus", 0400, debugfs_root,
|
||||
NULL, &sde_recovery_dsi_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_dsi.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_dsi.cmn.enable_mask);
|
||||
}
|
||||
|
||||
if (dbg->dbgbus_rsc.entries) {
|
||||
if (dbg->dbgbus_rsc.entries)
|
||||
debugfs_create_file("recovery_rsc_dbgbus", 0400, debugfs_root,
|
||||
NULL, &sde_recovery_rsc_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_rsc.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_rsc.cmn.enable_mask);
|
||||
}
|
||||
|
||||
if (dbg->dbgbus_lutdma.entries) {
|
||||
debugfs_create_file("recovery_lutdma_dbgbus", 0400,
|
||||
debugfs_root, NULL,
|
||||
&sde_recovery_lutdma_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_lutdma.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_lutdma.cmn.enable_mask);
|
||||
}
|
||||
if (dbg->dbgbus_lutdma.entries)
|
||||
debugfs_create_file("recovery_lutdma_dbgbus", 0400, debugfs_root,
|
||||
NULL, &sde_recovery_lutdma_dbgbus_fops);
|
||||
|
||||
if (dbg->dbgbus_dp.entries) {
|
||||
if (dbg->dbgbus_dp.entries)
|
||||
debugfs_create_file("recovery_dp_dbgbus", 0400, debugfs_root,
|
||||
NULL, &sde_recovery_dp_dbgbus_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
|
||||
dbg->dbgbus_dp.cmn.name);
|
||||
debugfs_create_u32(debug_name, 0600, debugfs_root,
|
||||
&dbg->dbgbus_dp.cmn.enable_mask);
|
||||
}
|
||||
|
||||
list_for_each_entry(blk_base, &dbg->reg_base_list, reg_base_head) {
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_off",
|
||||
blk_base->name);
|
||||
debugfs_create_file(debug_name, 0600, debugfs_root, blk_base,
|
||||
&sde_off_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_off", blk_base->name);
|
||||
debugfs_create_file(debug_name, 0600, debugfs_root, blk_base, &sde_off_fops);
|
||||
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_reg",
|
||||
blk_base->name);
|
||||
debugfs_create_file(debug_name, 0400, debugfs_root, blk_base,
|
||||
&sde_reg_fops);
|
||||
snprintf(debug_name, sizeof(debug_name), "%s_reg", blk_base->name);
|
||||
debugfs_create_file(debug_name, 0400, debugfs_root, blk_base, &sde_reg_fops);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2279,7 +2115,7 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
|
||||
dbg->dbgbus_sde.limited_entries = dbg_bus_sde_limited;
|
||||
dbg->dbgbus_sde.cmn.limited_entries_size = ARRAY_SIZE(dbg_bus_sde_limited);
|
||||
dbg->dbgbus_sde.cmn.name = DBGBUS_NAME_SDE;
|
||||
dbg->dbgbus_sde.cmn.enable_mask = DEFAULT_DBGBUS_SDE;
|
||||
dbg->dbgbus_sde.cmn.blk_id = SDE_DBG_SDE_DBGBUS;
|
||||
dbg->dbgbus_sde.read_tp = _sde_dbg_sde_read_test_point;
|
||||
dbg->dbgbus_sde.clear_tp = _sde_dbg_sde_clear_test_point;
|
||||
|
||||
@@ -2288,7 +2124,7 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
|
||||
dbg->dbgbus_vbif_rt.limited_entries = vbif_dbg_bus_limited;
|
||||
dbg->dbgbus_vbif_rt.cmn.limited_entries_size = ARRAY_SIZE(vbif_dbg_bus_limited);
|
||||
dbg->dbgbus_vbif_rt.cmn.name = DBGBUS_NAME_VBIF_RT;
|
||||
dbg->dbgbus_vbif_rt.cmn.enable_mask = DEFAULT_DBGBUS_VBIFRT;
|
||||
dbg->dbgbus_vbif_rt.cmn.blk_id = SDE_DBG_VBIF_RT_DBGBUS;
|
||||
dbg->dbgbus_vbif_rt.read_tp = _sde_dbg_vbif_read_test_point;
|
||||
dbg->dbgbus_vbif_rt.clear_tp = _sde_dbg_vbif_clear_test_point;
|
||||
dbg->dbgbus_vbif_rt.disable_block = _sde_dbg_vbif_disable_block;
|
||||
@@ -2296,33 +2132,30 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
|
||||
dbg->dbgbus_dsi.entries = dsi_dbg_bus;
|
||||
dbg->dbgbus_dsi.cmn.entries_size = ARRAY_SIZE(dsi_dbg_bus);
|
||||
dbg->dbgbus_dsi.cmn.name = DBGBUS_NAME_DSI;
|
||||
dbg->dbgbus_dsi.cmn.enable_mask = DEFAULT_DBGBUS_DSI;
|
||||
dbg->dbgbus_dsi.cmn.blk_id = SDE_DBG_DSI_DBGBUS;
|
||||
dbg->dbgbus_dsi.read_tp = _sde_dbg_dsi_read_test_point;
|
||||
dbg->dbgbus_dsi.clear_tp = _sde_dbg_cmn_clear_test_point;
|
||||
|
||||
dbg->dbgbus_rsc.entries = rsc_dbg_bus;
|
||||
dbg->dbgbus_rsc.cmn.entries_size = ARRAY_SIZE(rsc_dbg_bus);
|
||||
dbg->dbgbus_rsc.cmn.name = DBGBUS_NAME_RSC;
|
||||
dbg->dbgbus_rsc.cmn.enable_mask = DEFAULT_DBGBUS_RSC;
|
||||
dbg->dbgbus_rsc.cmn.blk_id = SDE_DBG_RSC_DBGBUS;
|
||||
dbg->dbgbus_rsc.read_tp = _sde_dbg_rsc_read_test_point;
|
||||
dbg->dbgbus_rsc.clear_tp = _sde_dbg_cmn_clear_test_point;
|
||||
|
||||
dbg->dbgbus_dp.entries = dp_dbg_bus;
|
||||
dbg->dbgbus_dp.cmn.entries_size = ARRAY_SIZE(dp_dbg_bus);
|
||||
dbg->dbgbus_dp.cmn.name = DBGBUS_NAME_DP;
|
||||
dbg->dbgbus_dp.cmn.enable_mask = DEFAULT_DBGBUS_DP;
|
||||
dbg->dbgbus_dp.cmn.blk_id = SDE_DBG_DP_DBGBUS;
|
||||
dbg->dbgbus_dp.read_tp = _sde_dbg_dp_read_test_point;
|
||||
dbg->dbgbus_dp.clear_tp = _sde_dbg_cmn_clear_test_point;
|
||||
|
||||
if (SDE_HW_REV_MAJOR(hwversion) >= 0x7) {
|
||||
dbg->dbgbus_lutdma.entries = dbg_bus_lutdma;
|
||||
dbg->dbgbus_lutdma.cmn.name = DBGBUS_NAME_LUTDMA;
|
||||
dbg->dbgbus_lutdma.cmn.entries_size = ARRAY_SIZE(dbg_bus_lutdma);
|
||||
dbg->dbgbus_lutdma.cmn.enable_mask = DEFAULT_DBGBUS_LUTDMA;
|
||||
dbg->dbgbus_lutdma.cmn.include_in_deferred_work = true;
|
||||
dbg->dbgbus_lutdma.read_tp = _sde_dbg_lutdma_read_test_point;
|
||||
dbg->dbgbus_lutdma.clear_tp = _sde_dbg_cmn_clear_test_point;
|
||||
}
|
||||
dbg->dbgbus_lutdma.entries = dbg_bus_lutdma;
|
||||
dbg->dbgbus_lutdma.cmn.name = DBGBUS_NAME_LUTDMA;
|
||||
dbg->dbgbus_lutdma.cmn.blk_id = SDE_DBG_LUTDMA_DBGBUS;
|
||||
dbg->dbgbus_lutdma.cmn.entries_size = ARRAY_SIZE(dbg_bus_lutdma);
|
||||
dbg->dbgbus_lutdma.read_tp = _sde_dbg_lutdma_read_test_point;
|
||||
dbg->dbgbus_lutdma.clear_tp = _sde_dbg_cmn_clear_test_point;
|
||||
}
|
||||
|
||||
int sde_dbg_init(struct device *dev)
|
||||
@@ -2346,6 +2179,8 @@ int sde_dbg_init(struct device *dev)
|
||||
sde_dbg_base.work_panic = false;
|
||||
sde_dbg_base.panic_on_err = DEFAULT_PANIC;
|
||||
sde_dbg_base.enable_reg_dump = DEFAULT_REGDUMP;
|
||||
sde_dbg_base.enable_dbgbus_dump = DEFAULT_DBGBUS_DUMP;
|
||||
sde_dbg_base.dump_blk_mask = SDE_DBG_BUILT_IN_ALL;
|
||||
memset(&sde_dbg_base.regbuf, 0, sizeof(sde_dbg_base.regbuf));
|
||||
|
||||
pr_info("evtlog_status: enable:%d, panic:%d, dump:%d\n",
|
||||
@@ -2422,8 +2257,7 @@ int sde_dbg_dsi_ctrl_register(void __iomem *base, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sde_dbg_reg_register_base(const char *name, void __iomem *base,
|
||||
size_t max_offset)
|
||||
int sde_dbg_reg_register_base(const char *name, void __iomem *base, size_t max_offset, u64 blk_id)
|
||||
{
|
||||
struct sde_dbg_base *dbg_base = &sde_dbg_base;
|
||||
struct sde_dbg_reg_base *reg_base;
|
||||
@@ -2443,6 +2277,7 @@ int sde_dbg_reg_register_base(const char *name, void __iomem *base,
|
||||
reg_base->off = 0;
|
||||
reg_base->cnt = DEFAULT_BASE_REG_CNT;
|
||||
reg_base->reg_dump = NULL;
|
||||
reg_base->blk_id = blk_id;
|
||||
|
||||
/* Initialize list to make sure check for null list will be valid */
|
||||
INIT_LIST_HEAD(®_base->sub_range_list);
|
||||
|
Reference in New Issue
Block a user