From 6ea0bdda2596f4d0a5f42cfb0fd95492afa37107 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 8 May 2020 12:20:47 -0700 Subject: [PATCH] mhi: core: expose soc reset and register dump debugfs entries For debug purposes, allow clients to issue SOC reset or read the entire register dump when they wish to do so. They may not read proper values or the reset may not take effect if the device is powered down. Change-Id: I7fb7589a1bdfd5d7c610bdf6aab5edfc814cdceb Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/mhi_boot.c | 7 ++++ drivers/bus/mhi/core/mhi_init.c | 20 ++++++++++ drivers/bus/mhi/core/mhi_internal.h | 3 ++ drivers/bus/mhi/core/mhi_main.c | 58 +++++++++++++++++++++++++++++ drivers/bus/mhi/core/mhi_pm.c | 11 ++++++ 5 files changed, 99 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index d324f0a0c9bc..97af7175a348 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -677,3 +677,10 @@ error_read: error_alloc_fw_table: release_firmware(firmware); } + +void mhi_perform_soc_reset(struct mhi_controller *mhi_cntrl) +{ + mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->regs, + MHI_SOC_RESET_REQ_OFFSET, + MHI_SOC_RESET_REQ); +} diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index a5284a1c25d3..a6272351af29 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -522,6 +522,12 @@ static int mhi_init_debugfs_mhi_vote_open(struct inode *inode, struct file *fp) return single_open(fp, mhi_debugfs_mhi_vote_show, inode->i_private); } +static int mhi_init_debugfs_mhi_regdump_open(struct inode *inode, + struct file *fp) +{ + return single_open(fp, mhi_debugfs_mhi_regdump_show, inode->i_private); +} + static const struct file_operations debugfs_state_ops = { .open = mhi_init_debugfs_mhi_states_open, .release = single_release, @@ -546,9 +552,18 @@ static const struct file_operations debugfs_vote_ops = { .read = seq_read, }; +static const struct file_operations debugfs_regdump_ops = { + .open = mhi_init_debugfs_mhi_regdump_open, + .release = single_release, + .read = seq_read, +}; + DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_reset_fops, NULL, mhi_debugfs_trigger_reset, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_soc_reset_fops, NULL, + mhi_debugfs_trigger_soc_reset, "%llu\n"); + void mhi_init_debugfs(struct mhi_controller *mhi_cntrl) { struct dentry *dentry; @@ -575,6 +590,11 @@ void mhi_init_debugfs(struct mhi_controller *mhi_cntrl) &debugfs_vote_ops); debugfs_create_file_unsafe("reset", 0444, dentry, mhi_cntrl, &debugfs_trigger_reset_fops); + debugfs_create_file_unsafe("regdump", 0444, dentry, mhi_cntrl, + &debugfs_regdump_ops); + debugfs_create_file_unsafe("soc_reset", 0444, dentry, mhi_cntrl, + &debugfs_trigger_soc_reset_fops); + mhi_cntrl->dentry = dentry; } diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 34c518d73d16..baaba5bf5993 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -753,11 +753,13 @@ extern struct mhi_bus mhi_bus; struct mhi_controller *find_mhi_controller_by_name(const char *name); /* debug fs related functions */ +int mhi_debugfs_mhi_regdump_show(struct seq_file *m, void *d); int mhi_debugfs_mhi_vote_show(struct seq_file *m, void *d); int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d); int mhi_debugfs_mhi_event_show(struct seq_file *m, void *d); int mhi_debugfs_mhi_states_show(struct seq_file *m, void *d); int mhi_debugfs_trigger_reset(void *data, u64 val); +int mhi_debugfs_trigger_soc_reset(void *data, u64 val); void mhi_deinit_debugfs(struct mhi_controller *mhi_cntrl); void mhi_init_debugfs(struct mhi_controller *mhi_cntrl); @@ -964,6 +966,7 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl); void mhi_force_reg_write(struct mhi_controller *mhi_cntrl); +void mhi_perform_soc_reset(struct mhi_controller *mhi_cntrl); /* isr handlers */ irqreturn_t mhi_msi_handlr(int irq_number, void *dev); diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 4ba83b09dc0c..a448daac588c 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -2076,6 +2076,64 @@ error_invalid_state: mutex_unlock(&mhi_chan->mutex); } +int mhi_debugfs_mhi_regdump_show(struct seq_file *m, void *d) +{ + struct mhi_controller *mhi_cntrl = m->private; + enum mhi_dev_state state; + enum mhi_ee ee; + int i, ret; + u32 val; + void __iomem *mhi_base = mhi_cntrl->regs; + void __iomem *bhi_base = mhi_cntrl->bhi; + void __iomem *bhie_base = mhi_cntrl->bhie; + void __iomem *wake_db = mhi_cntrl->wake_db; + struct { + const char *name; + int offset; + void __iomem *base; + } debug_reg[] = { + { "MHI_CNTRL", MHICTRL, mhi_base}, + { "MHI_STATUS", MHISTATUS, mhi_base}, + { "MHI_WAKE_DB", 0, wake_db}, + { "BHI_EXECENV", BHI_EXECENV, bhi_base}, + { "BHI_STATUS", BHI_STATUS, bhi_base}, + { "BHI_ERRCODE", BHI_ERRCODE, bhi_base}, + { "BHI_ERRDBG1", BHI_ERRDBG1, bhi_base}, + { "BHI_ERRDBG2", BHI_ERRDBG2, bhi_base}, + { "BHI_ERRDBG3", BHI_ERRDBG3, bhi_base}, + { "BHIE_TXVEC_DB", BHIE_TXVECDB_OFFS, bhie_base}, + { "BHIE_TXVEC_STATUS", BHIE_TXVECSTATUS_OFFS, bhie_base}, + { "BHIE_RXVEC_DB", BHIE_RXVECDB_OFFS, bhie_base}, + { "BHIE_RXVEC_STATUS", BHIE_RXVECSTATUS_OFFS, bhie_base}, + { NULL }, + }; + + if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) + return -EIO; + + seq_printf(m, "host pm_state:%s dev_state:%s ee:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + TO_MHI_STATE_STR(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(mhi_cntrl->ee)); + + state = mhi_get_mhi_state(mhi_cntrl); + ee = mhi_get_exec_env(mhi_cntrl); + + seq_printf(m, "device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), + TO_MHI_STATE_STR(state)); + + for (i = 0; debug_reg[i].name; i++) { + if (!debug_reg[i].base) + continue; + ret = mhi_read_reg(mhi_cntrl, debug_reg[i].base, + debug_reg[i].offset, &val); + seq_printf(m, "reg:%s val:0x%x, ret:%d\n", debug_reg[i].name, + val, ret); + } + + return 0; +} + int mhi_debugfs_mhi_states_show(struct seq_file *m, void *d) { struct mhi_controller *mhi_cntrl = m->private; diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index ff265b8947f2..30a2679528df 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -716,6 +716,17 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, mutex_unlock(&mhi_cntrl->pm_mutex); } +int mhi_debugfs_trigger_soc_reset(void *data, u64 val) +{ + struct mhi_controller *mhi_cntrl = data; + + MHI_LOG("Trigger MHI SOC Reset\n"); + + mhi_perform_soc_reset(mhi_cntrl); + + return 0; +} + int mhi_debugfs_trigger_reset(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data;