diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 448cfba9466e..5415d64745c9 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -354,6 +354,11 @@ static int mhi_init_debugfs_mhi_chan_open(struct inode *inode, struct file *fp) return single_open(fp, mhi_debugfs_mhi_chan_show, inode->i_private); } +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 const struct file_operations debugfs_state_ops = { .open = mhi_init_debugfs_mhi_states_open, .release = single_release, @@ -372,6 +377,12 @@ static const struct file_operations debugfs_chan_ops = { .read = seq_read, }; +static const struct file_operations debugfs_vote_ops = { + .open = mhi_init_debugfs_mhi_vote_open, + .release = single_release, + .read = seq_read, +}; + DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_reset_fops, NULL, mhi_debugfs_trigger_reset, "%llu\n"); @@ -397,6 +408,8 @@ void mhi_init_debugfs(struct mhi_controller *mhi_cntrl) &debugfs_ev_ops); debugfs_create_file_unsafe("chan", 0444, dentry, mhi_cntrl, &debugfs_chan_ops); + debugfs_create_file_unsafe("vote", 0444, dentry, mhi_cntrl, + &debugfs_vote_ops); debugfs_create_file_unsafe("reset", 0444, dentry, mhi_cntrl, &debugfs_trigger_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 fba758dc85da..1aac055944e8 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -751,6 +751,7 @@ 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_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); diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index b8ececaed85f..fac3dab5e382 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -2249,6 +2249,49 @@ int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d) return 0; } +/* show bus/device votes for a specific device */ +static int mhi_device_vote_show(struct device *dev, void *data) +{ + struct mhi_device *mhi_dev; + struct mhi_controller *mhi_cntrl; + + if (dev->bus != &mhi_bus_type) + return 0; + + mhi_dev = to_mhi_device(dev); + mhi_cntrl = mhi_dev->mhi_cntrl; + + /* we dont care about timesync or similar special devices */ + if (mhi_dev->dev_type == MHI_TIMESYNC_TYPE) + return 0; + + seq_printf((struct seq_file *)data, "%s: device:%u, bus:%u\n", + mhi_dev->chan_name, atomic_read(&mhi_dev->dev_vote), + atomic_read(&mhi_dev->bus_vote)); + + return 0; +} + +int mhi_debugfs_mhi_vote_show(struct seq_file *m, void *d) +{ + struct mhi_controller *mhi_cntrl = m->private; + struct mhi_device *mhi_dev; + + if (!mhi_cntrl) + return 0; + + mhi_dev = mhi_cntrl->mhi_dev; + + seq_printf(m, "At %llu ns:\n", sched_clock()); + seq_printf(m, "%s: device:%u, bus:%u\n", mhi_dev->chan_name, + atomic_read(&mhi_dev->dev_vote), + atomic_read(&mhi_dev->bus_vote)); + + device_for_each_child(mhi_cntrl->dev, m, mhi_device_vote_show); + + return 0; +} + /* move channel to start state */ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev) {