Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6431e60 authored by Bhaumik Bhatt's avatar Bhaumik Bhatt
Browse files

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: default avatarBhaumik Bhatt <bbhatt@codeaurora.org>
parent 2190df27
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -676,3 +676,10 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
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);
}
+20 −0
Original line number Diff line number Diff line
@@ -520,6 +520,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,
@@ -544,9 +550,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;
@@ -573,6 +588,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;
}

+3 −0
Original line number Diff line number Diff line
@@ -754,11 +754,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);
@@ -965,6 +967,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);
+58 −0
Original line number Diff line number Diff line
@@ -2108,6 +2108,64 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl,
	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;
+11 −0
Original line number Diff line number Diff line
@@ -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;