2020-08-10 22:04:49

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v7 00/11] Introduce features and debugfs/sysfs entries for MHI

Save hardware information from BHI.
Allow reading and modifying some MHI variables for debug, test, and
informational purposes using debugfs.
Read values for device specific hardware information to be used by OEMs in
factory testing such as serial number and PK hash using sysfs.

This set of patches was tested on arm64 and x86.

v7:
-Added suggested-by and reviewed-by tags
-Fixed nitpick on removal of M3_fast counter as it was unused
-Updated sysfs documentation dates and intended kernel version
-Fixed minor debugfs formatting by removing an extra newline character

v6:
-Introduced APIs for allocating and freeing the MHI controller so as to ensure
that it is always zero-initialized
-Moved gerrits around for counter introduction
-Fixed documentation for sysfs

v5:
-Removed the debug entry to trigger reset and will be addressed in a seperate
patch
-Added patch bus: mhi: core: Use counters to track MHI device state transitions
-Updated helper API to trigger a non-blocking host resume
-Minor nitpicks also fixed

v4:
-Removed bus: mhi: core: Introduce independent voting mechanism patch
-Removed bus vote function from debugfs due to independent voting removal
-Added helper resume APIs to aid consolidation of spread out code
-Added a clean-up patch and a missing host resume in voting API

v3:
-Add patch to check for pending packets in suspend as a dependency for the
independent voting mechanism introduction
-Include register dump entry for debugfs to dump MHI, BHI, and BHIe registers
-Update commit message for the debugfs patch
-Updated Documentation/ABI with the required info for sysfs
-Updated debugfs patch to include a new KConfig entry and dependencies
-Updated reviewed-by for some patches

v2:
-Added a new debugfs.c file for specific debugfs entries and code
-Updated commit text and addressed some comments for voting change
-Made sure sysfs is only used for serial number and OEM PK hash usage

Bhaumik Bhatt (11):
bus: mhi: core: Remove double occurrence for mhi_ctrl_ev_task()
declaration
bus: mhi: core: Abort suspends due to outgoing pending packets
bus: mhi: core: Use helper API to trigger a non-blocking host resume
bus: mhi: core: Trigger host resume if suspended during
mhi_device_get()
bus: mhi: core: Use generic name field for an MHI device
bus: mhi: core: Introduce helper function to check device state
bus: mhi: core: Introduce counters to track MHI device state
transitions
bus: mhi: core: Introduce debugfs entries for MHI
bus: mhi: core: Read and save device hardware information from BHI
bus: mhi: core: Introduce APIs to allocate and free the MHI controller
bus: mhi: core: Introduce sysfs entries for MHI

Documentation/ABI/stable/sysfs-bus-mhi | 21 ++
MAINTAINERS | 1 +
drivers/bus/mhi/Kconfig | 8 +
drivers/bus/mhi/core/Makefile | 5 +-
drivers/bus/mhi/core/boot.c | 17 +-
drivers/bus/mhi/core/debugfs.c | 409 +++++++++++++++++++++++++++++++++
drivers/bus/mhi/core/init.c | 81 ++++++-
drivers/bus/mhi/core/internal.h | 37 ++-
drivers/bus/mhi/core/main.c | 27 +--
drivers/bus/mhi/core/pm.c | 26 ++-
include/linux/mhi.h | 30 ++-
11 files changed, 623 insertions(+), 39 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-bus-mhi
create mode 100644 drivers/bus/mhi/core/debugfs.c

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


2020-08-10 22:05:11

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v7 01/11] bus: mhi: core: Remove double occurrence for mhi_ctrl_ev_task() declaration

mhi_ctrl_ev_task() in the internal header file occurred twice.
Remove one of the occurrences for clean-up.

Signed-off-by: Bhaumik Bhatt <[email protected]>
Reviewed-by: Manivannan Sadhasivam <[email protected]>
---
drivers/bus/mhi/core/internal.h | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
index b1f640b..bcfa7b6 100644
--- a/drivers/bus/mhi/core/internal.h
+++ b/drivers/bus/mhi/core/internal.h
@@ -592,7 +592,6 @@ void mhi_pm_st_worker(struct work_struct *work);
void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl);
void mhi_fw_load_worker(struct work_struct *work);
int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl);
-void mhi_ctrl_ev_task(unsigned long data);
int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl);
void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl);
int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2020-08-10 22:05:27

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v7 08/11] bus: mhi: core: Introduce debugfs entries for MHI

Introduce debugfs entries to show state, register, channel, device,
and event rings information. Allow the host to dump registers,
issue device wake, and change the MHI timeout to help in debug.

Signed-off-by: Bhaumik Bhatt <[email protected]>
---
drivers/bus/mhi/Kconfig | 8 +
drivers/bus/mhi/core/Makefile | 5 +-
drivers/bus/mhi/core/debugfs.c | 409 ++++++++++++++++++++++++++++++++++++++++
drivers/bus/mhi/core/init.c | 7 +
drivers/bus/mhi/core/internal.h | 24 +++
include/linux/mhi.h | 2 +
6 files changed, 452 insertions(+), 3 deletions(-)
create mode 100644 drivers/bus/mhi/core/debugfs.c

diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig
index a8bd9bd..6a217ff 100644
--- a/drivers/bus/mhi/Kconfig
+++ b/drivers/bus/mhi/Kconfig
@@ -12,3 +12,11 @@ config MHI_BUS
communication protocol used by the host processors to control
and communicate with modem devices over a high speed peripheral
bus or shared memory.
+
+config MHI_BUS_DEBUG
+ bool "Debugfs support for the MHI bus"
+ depends on MHI_BUS && DEBUG_FS
+ help
+ Enable debugfs support for use with the MHI transport. Allows
+ reading and/or modifying some values within the MHI controller
+ for debug and test purposes.
diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
index 66e2700..460a548 100644
--- a/drivers/bus/mhi/core/Makefile
+++ b/drivers/bus/mhi/core/Makefile
@@ -1,3 +1,2 @@
-obj-$(CONFIG_MHI_BUS) := mhi.o
-
-mhi-y := init.o main.o pm.o boot.o
+obj-$(CONFIG_MHI_BUS) := init.o main.o pm.o boot.o
+obj-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/core/debugfs.c
new file mode 100644
index 0000000..a249aa6
--- /dev/null
+++ b/drivers/bus/mhi/core/debugfs.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mhi.h>
+#include "internal.h"
+
+static int mhi_debugfs_states_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+
+ /* states */
+ seq_printf(m, "PM state: %s Device: %s MHI state: %s EE: %s wake: %s\n",
+ to_mhi_pm_state_str(mhi_cntrl->pm_state),
+ mhi_is_active(mhi_cntrl) ? "Active" : "Inactive",
+ TO_MHI_STATE_STR(mhi_cntrl->dev_state),
+ TO_MHI_EXEC_STR(mhi_cntrl->ee),
+ mhi_cntrl->wake_set ? "true" : "false");
+
+ /* counters */
+ seq_printf(m, "M0: %u M2: %u M3: %u", mhi_cntrl->M0, mhi_cntrl->M2,
+ mhi_cntrl->M3);
+
+ seq_printf(m, " device wake: %u pending packets: %u\n",
+ atomic_read(&mhi_cntrl->dev_wake),
+ atomic_read(&mhi_cntrl->pending_pkts));
+
+ return 0;
+}
+
+static int mhi_debugfs_events_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+ struct mhi_event *mhi_event;
+ struct mhi_event_ctxt *er_ctxt;
+ int i;
+
+ if (!mhi_is_active(mhi_cntrl)) {
+ seq_puts(m, "Device not ready\n");
+ return -ENODEV;
+ }
+
+ er_ctxt = mhi_cntrl->mhi_ctxt->er_ctxt;
+ mhi_event = mhi_cntrl->mhi_event;
+ for (i = 0; i < mhi_cntrl->total_ev_rings;
+ i++, er_ctxt++, mhi_event++) {
+ struct mhi_ring *ring = &mhi_event->ring;
+
+ if (mhi_event->offload_ev) {
+ seq_printf(m, "Index: %d is an offload event ring\n",
+ i);
+ continue;
+ }
+
+ seq_printf(m, "Index: %d intmod count: %lu time: %lu",
+ i, (er_ctxt->intmod & EV_CTX_INTMODC_MASK) >>
+ EV_CTX_INTMODC_SHIFT,
+ (er_ctxt->intmod & EV_CTX_INTMODT_MASK) >>
+ EV_CTX_INTMODT_SHIFT);
+
+ seq_printf(m, " base: 0x%0llx len: 0x%llx", er_ctxt->rbase,
+ er_ctxt->rlen);
+
+ seq_printf(m, " rp: 0x%llx wp: 0x%llx", er_ctxt->rp,
+ er_ctxt->wp);
+
+ seq_printf(m, " local rp: 0x%llx db: 0x%llx\n", (u64)ring->rp,
+ mhi_event->db_cfg.db_val);
+ }
+
+ return 0;
+}
+
+static int mhi_debugfs_channels_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+ struct mhi_chan *mhi_chan;
+ struct mhi_chan_ctxt *chan_ctxt;
+ int i;
+
+ if (!mhi_is_active(mhi_cntrl)) {
+ seq_puts(m, "Device not ready\n");
+ return -ENODEV;
+ }
+
+ mhi_chan = mhi_cntrl->mhi_chan;
+ chan_ctxt = mhi_cntrl->mhi_ctxt->chan_ctxt;
+ for (i = 0; i < mhi_cntrl->max_chan; i++, chan_ctxt++, mhi_chan++) {
+ struct mhi_ring *ring = &mhi_chan->tre_ring;
+
+ if (mhi_chan->offload_ch) {
+ seq_printf(m, "%s(%u) is an offload channel\n",
+ mhi_chan->name, mhi_chan->chan);
+ continue;
+ }
+
+ if (!mhi_chan->mhi_dev)
+ continue;
+
+ seq_printf(m,
+ "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx",
+ mhi_chan->name, mhi_chan->chan, (chan_ctxt->chcfg &
+ CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT,
+ (chan_ctxt->chcfg & CHAN_CTX_BRSTMODE_MASK) >>
+ CHAN_CTX_BRSTMODE_SHIFT, (chan_ctxt->chcfg &
+ CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT);
+
+ seq_printf(m, " type: 0x%x event ring: %u", chan_ctxt->chtype,
+ chan_ctxt->erindex);
+
+ seq_printf(m, " base: 0x%llx len: 0x%llx wp: 0x%llx",
+ chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->wp);
+
+ seq_printf(m, " local rp: 0x%llx local wp: 0x%llx db: 0x%llx\n",
+ (u64)ring->rp, (u64)ring->wp,
+ mhi_chan->db_cfg.db_val);
+ }
+
+ return 0;
+}
+
+static int mhi_device_info_show(struct device *dev, void *data)
+{
+ struct mhi_device *mhi_dev;
+
+ if (dev->bus != &mhi_bus_type)
+ return 0;
+
+ mhi_dev = to_mhi_device(dev);
+
+ seq_printf((struct seq_file *)data, "%s: type: %s dev_wake: %u",
+ mhi_dev->name, mhi_dev->dev_type ? "Controller" : "Transfer",
+ mhi_dev->dev_wake);
+
+ /* for transfer device types only */
+ if (mhi_dev->dev_type == MHI_DEVICE_XFER)
+ seq_printf((struct seq_file *)data, " channels: %u(UL)/%u(DL)",
+ mhi_dev->ul_chan_id, mhi_dev->dl_chan_id);
+
+ seq_puts((struct seq_file *)data, "\n");
+
+ return 0;
+}
+
+static int mhi_debugfs_devices_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+
+ if (!mhi_is_active(mhi_cntrl)) {
+ seq_puts(m, "Device not ready\n");
+ return -ENODEV;
+ }
+
+ device_for_each_child(mhi_cntrl->cntrl_dev, m, mhi_device_info_show);
+
+ return 0;
+}
+
+static int mhi_debugfs_regdump_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+ enum mhi_state state;
+ enum mhi_ee_type ee;
+ int i, ret = -EIO;
+ 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;
+ } regs[] = {
+ { "MHI_REGLEN", MHIREGLEN, mhi_base},
+ { "MHI_VER", MHIVER, mhi_base},
+ { "MHI_CFG", MHICFG, mhi_base},
+ { "MHI_CTRL", 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 ret;
+
+ seq_printf(m, "Host PM state: %s Device 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 state: %s\n", TO_MHI_EXEC_STR(ee),
+ TO_MHI_STATE_STR(state));
+
+ for (i = 0; regs[i].name; i++) {
+ if (!regs[i].base)
+ continue;
+ ret = mhi_read_reg(mhi_cntrl, regs[i].base, regs[i].offset,
+ &val);
+ if (ret)
+ continue;
+
+ seq_printf(m, "%s: 0x%x\n", regs[i].name, val);
+ }
+
+ return 0;
+}
+
+static int mhi_debugfs_device_wake_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+ struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
+
+ if (!mhi_is_active(mhi_cntrl)) {
+ seq_puts(m, "Device not ready\n");
+ return -ENODEV;
+ }
+
+ seq_printf(m,
+ "Wake count: %d\n%s\n", mhi_dev->dev_wake,
+ "Usage: echo get/put > device_wake to vote/unvote for M0");
+
+ return 0;
+}
+
+static ssize_t mhi_debugfs_device_wake_write(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *m = file->private_data;
+ struct mhi_controller *mhi_cntrl = m->private;
+ struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
+ char buf[16];
+ int ret = -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
+ if (!strncmp(buf, "get", 3)) {
+ ret = mhi_device_get_sync(mhi_dev);
+ } else if (!strncmp(buf, "put", 3)) {
+ mhi_device_put(mhi_dev);
+ ret = 0;
+ }
+
+ return ret ? ret : count;
+}
+
+static int mhi_debugfs_timeout_ms_show(struct seq_file *m, void *d)
+{
+ struct mhi_controller *mhi_cntrl = m->private;
+
+ seq_printf(m, "%u ms\n", mhi_cntrl->timeout_ms);
+
+ return 0;
+}
+
+static ssize_t mhi_debugfs_timeout_ms_write(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *m = file->private_data;
+ struct mhi_controller *mhi_cntrl = m->private;
+ u32 timeout_ms;
+
+ if (kstrtou32_from_user(ubuf, count, 0, &timeout_ms))
+ return -EINVAL;
+
+ mhi_cntrl->timeout_ms = timeout_ms;
+
+ return count;
+}
+
+static int mhi_debugfs_states_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_states_show, inode->i_private);
+}
+
+static int mhi_debugfs_events_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_events_show, inode->i_private);
+}
+
+static int mhi_debugfs_channels_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_channels_show, inode->i_private);
+}
+
+static int mhi_debugfs_devices_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_devices_show, inode->i_private);
+}
+
+static int mhi_debugfs_regdump_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_regdump_show, inode->i_private);
+}
+
+static int mhi_debugfs_device_wake_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_device_wake_show, inode->i_private);
+}
+
+static int mhi_debugfs_timeout_ms_open(struct inode *inode, struct file *fp)
+{
+ return single_open(fp, mhi_debugfs_timeout_ms_show, inode->i_private);
+}
+
+static const struct file_operations debugfs_states_fops = {
+ .open = mhi_debugfs_states_open,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_events_fops = {
+ .open = mhi_debugfs_events_open,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_channels_fops = {
+ .open = mhi_debugfs_channels_open,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_devices_fops = {
+ .open = mhi_debugfs_devices_open,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_regdump_fops = {
+ .open = mhi_debugfs_regdump_open,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_device_wake_fops = {
+ .open = mhi_debugfs_device_wake_open,
+ .write = mhi_debugfs_device_wake_write,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static const struct file_operations debugfs_timeout_ms_fops = {
+ .open = mhi_debugfs_timeout_ms_open,
+ .write = mhi_debugfs_timeout_ms_write,
+ .release = single_release,
+ .read = seq_read,
+};
+
+static struct dentry *mhi_debugfs_root;
+
+void mhi_create_debugfs(struct mhi_controller *mhi_cntrl)
+{
+ mhi_cntrl->debugfs_dentry =
+ debugfs_create_dir(dev_name(mhi_cntrl->cntrl_dev),
+ mhi_debugfs_root);
+
+ debugfs_create_file("states", 0444, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_states_fops);
+ debugfs_create_file("events", 0444, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_events_fops);
+ debugfs_create_file("channels", 0444, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_channels_fops);
+ debugfs_create_file("devices", 0444, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_devices_fops);
+ debugfs_create_file("regdump", 0444, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_regdump_fops);
+ debugfs_create_file("device_wake", 0644, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_device_wake_fops);
+ debugfs_create_file("timeout_ms", 0644, mhi_cntrl->debugfs_dentry,
+ mhi_cntrl, &debugfs_timeout_ms_fops);
+}
+
+void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl)
+{
+ debugfs_remove_recursive(mhi_cntrl->debugfs_dentry);
+ mhi_cntrl->debugfs_dentry = NULL;
+}
+
+void mhi_debugfs_init(void)
+{
+ mhi_debugfs_root = debugfs_create_dir(mhi_bus_type.name, NULL);
+}
+
+void mhi_debugfs_exit(void)
+{
+ debugfs_remove_recursive(mhi_debugfs_root);
+}
diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
index e2011ec..d2c0f6e 100644
--- a/drivers/bus/mhi/core/init.c
+++ b/drivers/bus/mhi/core/init.c
@@ -4,6 +4,7 @@
*
*/

+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
@@ -915,6 +916,8 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,

mhi_cntrl->mhi_dev = mhi_dev;

+ mhi_create_debugfs(mhi_cntrl);
+
return 0;

error_add_dev:
@@ -937,6 +940,8 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
struct mhi_chan *mhi_chan = mhi_cntrl->mhi_chan;
unsigned int i;

+ mhi_destroy_debugfs(mhi_cntrl);
+
kfree(mhi_cntrl->mhi_cmd);
kfree(mhi_cntrl->mhi_event);

@@ -1284,11 +1289,13 @@ struct bus_type mhi_bus_type = {

static int __init mhi_init(void)
{
+ mhi_debugfs_init();
return bus_register(&mhi_bus_type);
}

static void __exit mhi_exit(void)
{
+ mhi_debugfs_exit();
bus_unregister(&mhi_bus_type);
}

diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
index 5a81a42..7989269 100644
--- a/drivers/bus/mhi/core/internal.h
+++ b/drivers/bus/mhi/core/internal.h
@@ -570,6 +570,30 @@ struct mhi_chan {
/* Default MHI timeout */
#define MHI_TIMEOUT_MS (1000)

+/* debugfs related functions */
+#ifdef CONFIG_MHI_BUS_DEBUG
+void mhi_create_debugfs(struct mhi_controller *mhi_cntrl);
+void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl);
+void mhi_debugfs_init(void);
+void mhi_debugfs_exit(void);
+#else
+static inline void mhi_create_debugfs(struct mhi_controller *mhi_cntrl)
+{
+}
+
+static inline void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl)
+{
+}
+
+static inline void mhi_debugfs_init(void)
+{
+}
+
+static inline void mhi_debugfs_exit(void)
+{
+}
+#endif
+
struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl);

int mhi_destroy_device(struct device *dev, void *data);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index d360020..3a3e857 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -290,6 +290,7 @@ struct mhi_controller_config {
* @cntrl_dev: Pointer to the struct device of physical bus acting as the MHI
* controller (required)
* @mhi_dev: MHI device instance for the controller
+ * @debugfs_dentry: MHI controller debugfs directory
* @regs: Base address of MHI MMIO register space (required)
* @bhi: Points to base of MHI BHI register space
* @bhie: Points to base of MHI BHIe register space
@@ -367,6 +368,7 @@ struct mhi_controller_config {
struct mhi_controller {
struct device *cntrl_dev;
struct mhi_device *mhi_dev;
+ struct dentry *debugfs_dentry;
void __iomem *regs;
void __iomem *bhi;
void __iomem *bhie;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2020-08-10 22:06:37

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v7 10/11] bus: mhi: core: Introduce APIs to allocate and free the MHI controller

Client devices should use the APIs provided to allocate and free
the MHI controller structure. This will help ensure that the
structure is zero-initialized and there are no false positives
with respect to reading any values such as the serial number or
the OEM PK hash.

Signed-off-by: Bhaumik Bhatt <[email protected]>
Suggested-by: Manivannan Sadhasivam <[email protected]>
Reviewed-by: Manivannan Sadhasivam <[email protected]>
---
drivers/bus/mhi/core/init.c | 16 ++++++++++++++++
include/linux/mhi.h | 12 ++++++++++++
2 files changed, 28 insertions(+)

diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
index d2c0f6e..972dbf0 100644
--- a/drivers/bus/mhi/core/init.c
+++ b/drivers/bus/mhi/core/init.c
@@ -959,6 +959,22 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
}
EXPORT_SYMBOL_GPL(mhi_unregister_controller);

+struct mhi_controller *mhi_alloc_controller(void)
+{
+ struct mhi_controller *mhi_cntrl;
+
+ mhi_cntrl = kzalloc(sizeof(*mhi_cntrl), GFP_KERNEL);
+
+ return mhi_cntrl;
+}
+EXPORT_SYMBOL_GPL(mhi_alloc_controller);
+
+void mhi_free_controller(struct mhi_controller *mhi_cntrl)
+{
+ kfree(mhi_cntrl);
+}
+EXPORT_SYMBOL_GPL(mhi_free_controller);
+
int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl)
{
struct device *dev = &mhi_cntrl->mhi_dev->dev;
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 4065762..4955634 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -530,6 +530,18 @@ struct mhi_driver {
#define to_mhi_device(dev) container_of(dev, struct mhi_device, dev)

/**
+ * mhi_alloc_controller - Allocate the MHI Controller structure
+ * Allocate the mhi_controller structure using zero initialized memory
+ */
+struct mhi_controller *mhi_alloc_controller(void);
+
+/**
+ * mhi_free_controller - Free the MHI Controller structure
+ * Free the mhi_controller structure which was previously allocated
+ */
+void mhi_free_controller(struct mhi_controller *mhi_cntrl);
+
+/**
* mhi_register_controller - Register MHI controller
* @mhi_cntrl: MHI controller to register
* @config: Configuration to use for the controller
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2020-08-11 01:04:05

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v7 08/11] bus: mhi: core: Introduce debugfs entries for MHI

Hi Bhaumik,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.8 next-20200810]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Bhaumik-Bhatt/Introduce-features-and-debugfs-sysfs-entries-for-MHI/20200811-060436
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git fc80c51fd4b23ec007e88d4c688f2cac1b8648e7
config: arm64-randconfig-r001-20200810 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 3a34228bff6fdf45b50cb57cf5fb85d659eeb672)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm64 cross compiling tool for clang build
# apt-get install binutils-aarch64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>, old ones prefixed by <<):

WARNING: modpost: missing MODULE_LICENSE() in drivers/bus/mhi/core/main.o
WARNING: modpost: missing MODULE_LICENSE() in drivers/bus/mhi/core/pm.o
WARNING: modpost: missing MODULE_LICENSE() in drivers/bus/mhi/core/boot.o
>> ERROR: modpost: "mhi_ready_state_transition" [drivers/bus/mhi/core/boot.ko] undefined!
ERROR: modpost: "mhi_state_str" [drivers/bus/mhi/core/boot.ko] undefined!
ERROR: modpost: "to_mhi_pm_state_str" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_ee_str" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_read_reg" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_set_mhi_state" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_read_reg_field" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_get_exec_env" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_write_reg_field" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_write_reg" [drivers/bus/mhi/core/boot.ko] undefined!
>> ERROR: modpost: "mhi_free_bhie_table" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_write_db" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_get_mhi_state" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_init_dev_ctxt" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_deinit_dev_ctxt" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_deinit_free_irq" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_read_reg" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_init_irq_setup" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_state_str" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_destroy_device" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_write_reg" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "dev_state_tran_str" [drivers/bus/mhi/core/pm.ko] undefined!
>> ERROR: modpost: "mhi_create_devices" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_fw_load_handler" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_get_exec_env" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_ring_chan_db" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_ring_cmd_db" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "to_mhi_pm_state_str" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_ring_er_db" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_init_mmio" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_read_reg_field" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_write_reg_field" [drivers/bus/mhi/core/pm.ko] undefined!
ERROR: modpost: "mhi_init_chan_ctxt" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_deinit_chan_ctxt" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "to_mhi_pm_state_str" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_pm_m3_transition" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_pm_m0_transition" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_queue_state_transition" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_pm_m1_transition" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_pm_sys_err_handler" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_state_str" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_ee_str" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_tryset_pm_state" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_alloc_device" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_bus_type" [drivers/bus/mhi/core/main.ko] undefined!
ERROR: modpost: "mhi_reset_chan" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_prepare_channel" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_free_bhie_table" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_rddm_prepare" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_alloc_bhie_table" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_read_reg" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_unmap_single_no_bb" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_unmap_single_use_bb" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_map_single_no_bb" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_map_single_use_bb" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_ctrl_ev_task" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_ev_task" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_pm_st_worker" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_process_ctrl_ev_ring" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_process_data_event_ring" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_db_brstmode_disable" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_db_brstmode" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_write_reg_field" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_write_reg" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_read_reg_field" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_irq_handler" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_intvec_threaded_handler" [drivers/bus/mhi/core/init.ko] undefined!
ERROR: modpost: "mhi_intvec_handler" [drivers/bus/mhi/core/init.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (6.98 kB)
.config.gz (46.97 kB)
Download all attachments

2020-08-11 06:25:46

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 08/11] bus: mhi: core: Introduce debugfs entries for MHI

On Mon, Aug 10, 2020 at 03:01:02PM -0700, Bhaumik Bhatt wrote:
> Introduce debugfs entries to show state, register, channel, device,
> and event rings information. Allow the host to dump registers,
> issue device wake, and change the MHI timeout to help in debug.
>
> Signed-off-by: Bhaumik Bhatt <[email protected]>

Reviewed-by: Manivannan Sadhasivam <[email protected]>

Thanks,
Mani

> ---
> drivers/bus/mhi/Kconfig | 8 +
> drivers/bus/mhi/core/Makefile | 5 +-
> drivers/bus/mhi/core/debugfs.c | 409 ++++++++++++++++++++++++++++++++++++++++
> drivers/bus/mhi/core/init.c | 7 +
> drivers/bus/mhi/core/internal.h | 24 +++
> include/linux/mhi.h | 2 +
> 6 files changed, 452 insertions(+), 3 deletions(-)
> create mode 100644 drivers/bus/mhi/core/debugfs.c
>
> diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig
> index a8bd9bd..6a217ff 100644
> --- a/drivers/bus/mhi/Kconfig
> +++ b/drivers/bus/mhi/Kconfig
> @@ -12,3 +12,11 @@ config MHI_BUS
> communication protocol used by the host processors to control
> and communicate with modem devices over a high speed peripheral
> bus or shared memory.
> +
> +config MHI_BUS_DEBUG
> + bool "Debugfs support for the MHI bus"
> + depends on MHI_BUS && DEBUG_FS
> + help
> + Enable debugfs support for use with the MHI transport. Allows
> + reading and/or modifying some values within the MHI controller
> + for debug and test purposes.
> diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
> index 66e2700..460a548 100644
> --- a/drivers/bus/mhi/core/Makefile
> +++ b/drivers/bus/mhi/core/Makefile
> @@ -1,3 +1,2 @@
> -obj-$(CONFIG_MHI_BUS) := mhi.o
> -
> -mhi-y := init.o main.o pm.o boot.o
> +obj-$(CONFIG_MHI_BUS) := init.o main.o pm.o boot.o
> +obj-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
> diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/core/debugfs.c
> new file mode 100644
> index 0000000..a249aa6
> --- /dev/null
> +++ b/drivers/bus/mhi/core/debugfs.c
> @@ -0,0 +1,409 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
> + *
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/device.h>
> +#include <linux/interrupt.h>
> +#include <linux/list.h>
> +#include <linux/mhi.h>
> +#include "internal.h"
> +
> +static int mhi_debugfs_states_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> +
> + /* states */
> + seq_printf(m, "PM state: %s Device: %s MHI state: %s EE: %s wake: %s\n",
> + to_mhi_pm_state_str(mhi_cntrl->pm_state),
> + mhi_is_active(mhi_cntrl) ? "Active" : "Inactive",
> + TO_MHI_STATE_STR(mhi_cntrl->dev_state),
> + TO_MHI_EXEC_STR(mhi_cntrl->ee),
> + mhi_cntrl->wake_set ? "true" : "false");
> +
> + /* counters */
> + seq_printf(m, "M0: %u M2: %u M3: %u", mhi_cntrl->M0, mhi_cntrl->M2,
> + mhi_cntrl->M3);
> +
> + seq_printf(m, " device wake: %u pending packets: %u\n",
> + atomic_read(&mhi_cntrl->dev_wake),
> + atomic_read(&mhi_cntrl->pending_pkts));
> +
> + return 0;
> +}
> +
> +static int mhi_debugfs_events_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> + struct mhi_event *mhi_event;
> + struct mhi_event_ctxt *er_ctxt;
> + int i;
> +
> + if (!mhi_is_active(mhi_cntrl)) {
> + seq_puts(m, "Device not ready\n");
> + return -ENODEV;
> + }
> +
> + er_ctxt = mhi_cntrl->mhi_ctxt->er_ctxt;
> + mhi_event = mhi_cntrl->mhi_event;
> + for (i = 0; i < mhi_cntrl->total_ev_rings;
> + i++, er_ctxt++, mhi_event++) {
> + struct mhi_ring *ring = &mhi_event->ring;
> +
> + if (mhi_event->offload_ev) {
> + seq_printf(m, "Index: %d is an offload event ring\n",
> + i);
> + continue;
> + }
> +
> + seq_printf(m, "Index: %d intmod count: %lu time: %lu",
> + i, (er_ctxt->intmod & EV_CTX_INTMODC_MASK) >>
> + EV_CTX_INTMODC_SHIFT,
> + (er_ctxt->intmod & EV_CTX_INTMODT_MASK) >>
> + EV_CTX_INTMODT_SHIFT);
> +
> + seq_printf(m, " base: 0x%0llx len: 0x%llx", er_ctxt->rbase,
> + er_ctxt->rlen);
> +
> + seq_printf(m, " rp: 0x%llx wp: 0x%llx", er_ctxt->rp,
> + er_ctxt->wp);
> +
> + seq_printf(m, " local rp: 0x%llx db: 0x%llx\n", (u64)ring->rp,
> + mhi_event->db_cfg.db_val);
> + }
> +
> + return 0;
> +}
> +
> +static int mhi_debugfs_channels_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> + struct mhi_chan *mhi_chan;
> + struct mhi_chan_ctxt *chan_ctxt;
> + int i;
> +
> + if (!mhi_is_active(mhi_cntrl)) {
> + seq_puts(m, "Device not ready\n");
> + return -ENODEV;
> + }
> +
> + mhi_chan = mhi_cntrl->mhi_chan;
> + chan_ctxt = mhi_cntrl->mhi_ctxt->chan_ctxt;
> + for (i = 0; i < mhi_cntrl->max_chan; i++, chan_ctxt++, mhi_chan++) {
> + struct mhi_ring *ring = &mhi_chan->tre_ring;
> +
> + if (mhi_chan->offload_ch) {
> + seq_printf(m, "%s(%u) is an offload channel\n",
> + mhi_chan->name, mhi_chan->chan);
> + continue;
> + }
> +
> + if (!mhi_chan->mhi_dev)
> + continue;
> +
> + seq_printf(m,
> + "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx",
> + mhi_chan->name, mhi_chan->chan, (chan_ctxt->chcfg &
> + CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT,
> + (chan_ctxt->chcfg & CHAN_CTX_BRSTMODE_MASK) >>
> + CHAN_CTX_BRSTMODE_SHIFT, (chan_ctxt->chcfg &
> + CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT);
> +
> + seq_printf(m, " type: 0x%x event ring: %u", chan_ctxt->chtype,
> + chan_ctxt->erindex);
> +
> + seq_printf(m, " base: 0x%llx len: 0x%llx wp: 0x%llx",
> + chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->wp);
> +
> + seq_printf(m, " local rp: 0x%llx local wp: 0x%llx db: 0x%llx\n",
> + (u64)ring->rp, (u64)ring->wp,
> + mhi_chan->db_cfg.db_val);
> + }
> +
> + return 0;
> +}
> +
> +static int mhi_device_info_show(struct device *dev, void *data)
> +{
> + struct mhi_device *mhi_dev;
> +
> + if (dev->bus != &mhi_bus_type)
> + return 0;
> +
> + mhi_dev = to_mhi_device(dev);
> +
> + seq_printf((struct seq_file *)data, "%s: type: %s dev_wake: %u",
> + mhi_dev->name, mhi_dev->dev_type ? "Controller" : "Transfer",
> + mhi_dev->dev_wake);
> +
> + /* for transfer device types only */
> + if (mhi_dev->dev_type == MHI_DEVICE_XFER)
> + seq_printf((struct seq_file *)data, " channels: %u(UL)/%u(DL)",
> + mhi_dev->ul_chan_id, mhi_dev->dl_chan_id);
> +
> + seq_puts((struct seq_file *)data, "\n");
> +
> + return 0;
> +}
> +
> +static int mhi_debugfs_devices_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> +
> + if (!mhi_is_active(mhi_cntrl)) {
> + seq_puts(m, "Device not ready\n");
> + return -ENODEV;
> + }
> +
> + device_for_each_child(mhi_cntrl->cntrl_dev, m, mhi_device_info_show);
> +
> + return 0;
> +}
> +
> +static int mhi_debugfs_regdump_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> + enum mhi_state state;
> + enum mhi_ee_type ee;
> + int i, ret = -EIO;
> + 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;
> + } regs[] = {
> + { "MHI_REGLEN", MHIREGLEN, mhi_base},
> + { "MHI_VER", MHIVER, mhi_base},
> + { "MHI_CFG", MHICFG, mhi_base},
> + { "MHI_CTRL", 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 ret;
> +
> + seq_printf(m, "Host PM state: %s Device 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 state: %s\n", TO_MHI_EXEC_STR(ee),
> + TO_MHI_STATE_STR(state));
> +
> + for (i = 0; regs[i].name; i++) {
> + if (!regs[i].base)
> + continue;
> + ret = mhi_read_reg(mhi_cntrl, regs[i].base, regs[i].offset,
> + &val);
> + if (ret)
> + continue;
> +
> + seq_printf(m, "%s: 0x%x\n", regs[i].name, val);
> + }
> +
> + return 0;
> +}
> +
> +static int mhi_debugfs_device_wake_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> + struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
> +
> + if (!mhi_is_active(mhi_cntrl)) {
> + seq_puts(m, "Device not ready\n");
> + return -ENODEV;
> + }
> +
> + seq_printf(m,
> + "Wake count: %d\n%s\n", mhi_dev->dev_wake,
> + "Usage: echo get/put > device_wake to vote/unvote for M0");
> +
> + return 0;
> +}
> +
> +static ssize_t mhi_debugfs_device_wake_write(struct file *file,
> + const char __user *ubuf,
> + size_t count, loff_t *ppos)
> +{
> + struct seq_file *m = file->private_data;
> + struct mhi_controller *mhi_cntrl = m->private;
> + struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
> + char buf[16];
> + int ret = -EINVAL;
> +
> + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
> + return -EFAULT;
> +
> + if (!strncmp(buf, "get", 3)) {
> + ret = mhi_device_get_sync(mhi_dev);
> + } else if (!strncmp(buf, "put", 3)) {
> + mhi_device_put(mhi_dev);
> + ret = 0;
> + }
> +
> + return ret ? ret : count;
> +}
> +
> +static int mhi_debugfs_timeout_ms_show(struct seq_file *m, void *d)
> +{
> + struct mhi_controller *mhi_cntrl = m->private;
> +
> + seq_printf(m, "%u ms\n", mhi_cntrl->timeout_ms);
> +
> + return 0;
> +}
> +
> +static ssize_t mhi_debugfs_timeout_ms_write(struct file *file,
> + const char __user *ubuf,
> + size_t count, loff_t *ppos)
> +{
> + struct seq_file *m = file->private_data;
> + struct mhi_controller *mhi_cntrl = m->private;
> + u32 timeout_ms;
> +
> + if (kstrtou32_from_user(ubuf, count, 0, &timeout_ms))
> + return -EINVAL;
> +
> + mhi_cntrl->timeout_ms = timeout_ms;
> +
> + return count;
> +}
> +
> +static int mhi_debugfs_states_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_states_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_events_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_events_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_channels_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_channels_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_devices_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_devices_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_regdump_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_regdump_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_device_wake_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_device_wake_show, inode->i_private);
> +}
> +
> +static int mhi_debugfs_timeout_ms_open(struct inode *inode, struct file *fp)
> +{
> + return single_open(fp, mhi_debugfs_timeout_ms_show, inode->i_private);
> +}
> +
> +static const struct file_operations debugfs_states_fops = {
> + .open = mhi_debugfs_states_open,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_events_fops = {
> + .open = mhi_debugfs_events_open,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_channels_fops = {
> + .open = mhi_debugfs_channels_open,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_devices_fops = {
> + .open = mhi_debugfs_devices_open,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_regdump_fops = {
> + .open = mhi_debugfs_regdump_open,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_device_wake_fops = {
> + .open = mhi_debugfs_device_wake_open,
> + .write = mhi_debugfs_device_wake_write,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static const struct file_operations debugfs_timeout_ms_fops = {
> + .open = mhi_debugfs_timeout_ms_open,
> + .write = mhi_debugfs_timeout_ms_write,
> + .release = single_release,
> + .read = seq_read,
> +};
> +
> +static struct dentry *mhi_debugfs_root;
> +
> +void mhi_create_debugfs(struct mhi_controller *mhi_cntrl)
> +{
> + mhi_cntrl->debugfs_dentry =
> + debugfs_create_dir(dev_name(mhi_cntrl->cntrl_dev),
> + mhi_debugfs_root);
> +
> + debugfs_create_file("states", 0444, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_states_fops);
> + debugfs_create_file("events", 0444, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_events_fops);
> + debugfs_create_file("channels", 0444, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_channels_fops);
> + debugfs_create_file("devices", 0444, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_devices_fops);
> + debugfs_create_file("regdump", 0444, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_regdump_fops);
> + debugfs_create_file("device_wake", 0644, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_device_wake_fops);
> + debugfs_create_file("timeout_ms", 0644, mhi_cntrl->debugfs_dentry,
> + mhi_cntrl, &debugfs_timeout_ms_fops);
> +}
> +
> +void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl)
> +{
> + debugfs_remove_recursive(mhi_cntrl->debugfs_dentry);
> + mhi_cntrl->debugfs_dentry = NULL;
> +}
> +
> +void mhi_debugfs_init(void)
> +{
> + mhi_debugfs_root = debugfs_create_dir(mhi_bus_type.name, NULL);
> +}
> +
> +void mhi_debugfs_exit(void)
> +{
> + debugfs_remove_recursive(mhi_debugfs_root);
> +}
> diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
> index e2011ec..d2c0f6e 100644
> --- a/drivers/bus/mhi/core/init.c
> +++ b/drivers/bus/mhi/core/init.c
> @@ -4,6 +4,7 @@
> *
> */
>
> +#include <linux/debugfs.h>
> #include <linux/device.h>
> #include <linux/dma-direction.h>
> #include <linux/dma-mapping.h>
> @@ -915,6 +916,8 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
>
> mhi_cntrl->mhi_dev = mhi_dev;
>
> + mhi_create_debugfs(mhi_cntrl);
> +
> return 0;
>
> error_add_dev:
> @@ -937,6 +940,8 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
> struct mhi_chan *mhi_chan = mhi_cntrl->mhi_chan;
> unsigned int i;
>
> + mhi_destroy_debugfs(mhi_cntrl);
> +
> kfree(mhi_cntrl->mhi_cmd);
> kfree(mhi_cntrl->mhi_event);
>
> @@ -1284,11 +1289,13 @@ struct bus_type mhi_bus_type = {
>
> static int __init mhi_init(void)
> {
> + mhi_debugfs_init();
> return bus_register(&mhi_bus_type);
> }
>
> static void __exit mhi_exit(void)
> {
> + mhi_debugfs_exit();
> bus_unregister(&mhi_bus_type);
> }
>
> diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
> index 5a81a42..7989269 100644
> --- a/drivers/bus/mhi/core/internal.h
> +++ b/drivers/bus/mhi/core/internal.h
> @@ -570,6 +570,30 @@ struct mhi_chan {
> /* Default MHI timeout */
> #define MHI_TIMEOUT_MS (1000)
>
> +/* debugfs related functions */
> +#ifdef CONFIG_MHI_BUS_DEBUG
> +void mhi_create_debugfs(struct mhi_controller *mhi_cntrl);
> +void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl);
> +void mhi_debugfs_init(void);
> +void mhi_debugfs_exit(void);
> +#else
> +static inline void mhi_create_debugfs(struct mhi_controller *mhi_cntrl)
> +{
> +}
> +
> +static inline void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl)
> +{
> +}
> +
> +static inline void mhi_debugfs_init(void)
> +{
> +}
> +
> +static inline void mhi_debugfs_exit(void)
> +{
> +}
> +#endif
> +
> struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl);
>
> int mhi_destroy_device(struct device *dev, void *data);
> diff --git a/include/linux/mhi.h b/include/linux/mhi.h
> index d360020..3a3e857 100644
> --- a/include/linux/mhi.h
> +++ b/include/linux/mhi.h
> @@ -290,6 +290,7 @@ struct mhi_controller_config {
> * @cntrl_dev: Pointer to the struct device of physical bus acting as the MHI
> * controller (required)
> * @mhi_dev: MHI device instance for the controller
> + * @debugfs_dentry: MHI controller debugfs directory
> * @regs: Base address of MHI MMIO register space (required)
> * @bhi: Points to base of MHI BHI register space
> * @bhie: Points to base of MHI BHIe register space
> @@ -367,6 +368,7 @@ struct mhi_controller_config {
> struct mhi_controller {
> struct device *cntrl_dev;
> struct mhi_device *mhi_dev;
> + struct dentry *debugfs_dentry;
> void __iomem *regs;
> void __iomem *bhi;
> void __iomem *bhie;
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>

2020-08-11 06:29:46

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 00/11] Introduce features and debugfs/sysfs entries for MHI

Hi Bhaumik,

On Mon, Aug 10, 2020 at 03:00:54PM -0700, Bhaumik Bhatt wrote:
> Save hardware information from BHI.
> Allow reading and modifying some MHI variables for debug, test, and
> informational purposes using debugfs.
> Read values for device specific hardware information to be used by OEMs in
> factory testing such as serial number and PK hash using sysfs.
>
> This set of patches was tested on arm64 and x86.
>

Sorry for stretching the review so long. Will apply the series to mhi-next
once v5.9-rc1 is out.

Thanks,
Mani

> v7:
> -Added suggested-by and reviewed-by tags
> -Fixed nitpick on removal of M3_fast counter as it was unused
> -Updated sysfs documentation dates and intended kernel version
> -Fixed minor debugfs formatting by removing an extra newline character
>
> v6:
> -Introduced APIs for allocating and freeing the MHI controller so as to ensure
> that it is always zero-initialized
> -Moved gerrits around for counter introduction
> -Fixed documentation for sysfs
>
> v5:
> -Removed the debug entry to trigger reset and will be addressed in a seperate
> patch
> -Added patch bus: mhi: core: Use counters to track MHI device state transitions
> -Updated helper API to trigger a non-blocking host resume
> -Minor nitpicks also fixed
>
> v4:
> -Removed bus: mhi: core: Introduce independent voting mechanism patch
> -Removed bus vote function from debugfs due to independent voting removal
> -Added helper resume APIs to aid consolidation of spread out code
> -Added a clean-up patch and a missing host resume in voting API
>
> v3:
> -Add patch to check for pending packets in suspend as a dependency for the
> independent voting mechanism introduction
> -Include register dump entry for debugfs to dump MHI, BHI, and BHIe registers
> -Update commit message for the debugfs patch
> -Updated Documentation/ABI with the required info for sysfs
> -Updated debugfs patch to include a new KConfig entry and dependencies
> -Updated reviewed-by for some patches
>
> v2:
> -Added a new debugfs.c file for specific debugfs entries and code
> -Updated commit text and addressed some comments for voting change
> -Made sure sysfs is only used for serial number and OEM PK hash usage
>
> Bhaumik Bhatt (11):
> bus: mhi: core: Remove double occurrence for mhi_ctrl_ev_task()
> declaration
> bus: mhi: core: Abort suspends due to outgoing pending packets
> bus: mhi: core: Use helper API to trigger a non-blocking host resume
> bus: mhi: core: Trigger host resume if suspended during
> mhi_device_get()
> bus: mhi: core: Use generic name field for an MHI device
> bus: mhi: core: Introduce helper function to check device state
> bus: mhi: core: Introduce counters to track MHI device state
> transitions
> bus: mhi: core: Introduce debugfs entries for MHI
> bus: mhi: core: Read and save device hardware information from BHI
> bus: mhi: core: Introduce APIs to allocate and free the MHI controller
> bus: mhi: core: Introduce sysfs entries for MHI
>
> Documentation/ABI/stable/sysfs-bus-mhi | 21 ++
> MAINTAINERS | 1 +
> drivers/bus/mhi/Kconfig | 8 +
> drivers/bus/mhi/core/Makefile | 5 +-
> drivers/bus/mhi/core/boot.c | 17 +-
> drivers/bus/mhi/core/debugfs.c | 409 +++++++++++++++++++++++++++++++++
> drivers/bus/mhi/core/init.c | 81 ++++++-
> drivers/bus/mhi/core/internal.h | 37 ++-
> drivers/bus/mhi/core/main.c | 27 +--
> drivers/bus/mhi/core/pm.c | 26 ++-
> include/linux/mhi.h | 30 ++-
> 11 files changed, 623 insertions(+), 39 deletions(-)
> create mode 100644 Documentation/ABI/stable/sysfs-bus-mhi
> create mode 100644 drivers/bus/mhi/core/debugfs.c
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>

2020-08-11 17:56:39

by Bhaumik Bhatt

[permalink] [raw]
Subject: Re: [PATCH v7 00/11] Introduce features and debugfs/sysfs entries for MHI

On 2020-08-10 23:26, Manivannan Sadhasivam wrote:
> Hi Bhaumik,
>
> On Mon, Aug 10, 2020 at 03:00:54PM -0700, Bhaumik Bhatt wrote:
>> Save hardware information from BHI.
>> Allow reading and modifying some MHI variables for debug, test, and
>> informational purposes using debugfs.
>> Read values for device specific hardware information to be used by
>> OEMs in
>> factory testing such as serial number and PK hash using sysfs.
>>
>> This set of patches was tested on arm64 and x86.
>>
>
> Sorry for stretching the review so long. Will apply the series to
> mhi-next
> once v5.9-rc1 is out.
>
> Thanks,
> Mani
>
Awesome. Thank you for the thorough review.
>> v7:
>> -Added suggested-by and reviewed-by tags
>> -Fixed nitpick on removal of M3_fast counter as it was unused
>> -Updated sysfs documentation dates and intended kernel version
>> -Fixed minor debugfs formatting by removing an extra newline character
>>
>> v6:
>> -Introduced APIs for allocating and freeing the MHI controller so as
>> to ensure
>> that it is always zero-initialized
>> -Moved gerrits around for counter introduction
>> -Fixed documentation for sysfs
>>
>> v5:
>> -Removed the debug entry to trigger reset and will be addressed in a
>> seperate
>> patch
>> -Added patch bus: mhi: core: Use counters to track MHI device state
>> transitions
>> -Updated helper API to trigger a non-blocking host resume
>> -Minor nitpicks also fixed
>>
>> v4:
>> -Removed bus: mhi: core: Introduce independent voting mechanism patch
>> -Removed bus vote function from debugfs due to independent voting
>> removal
>> -Added helper resume APIs to aid consolidation of spread out code
>> -Added a clean-up patch and a missing host resume in voting API
>>
>> v3:
>> -Add patch to check for pending packets in suspend as a dependency for
>> the
>> independent voting mechanism introduction
>> -Include register dump entry for debugfs to dump MHI, BHI, and BHIe
>> registers
>> -Update commit message for the debugfs patch
>> -Updated Documentation/ABI with the required info for sysfs
>> -Updated debugfs patch to include a new KConfig entry and dependencies
>> -Updated reviewed-by for some patches
>>
>> v2:
>> -Added a new debugfs.c file for specific debugfs entries and code
>> -Updated commit text and addressed some comments for voting change
>> -Made sure sysfs is only used for serial number and OEM PK hash usage
>>
>> Bhaumik Bhatt (11):
>> bus: mhi: core: Remove double occurrence for mhi_ctrl_ev_task()
>> declaration
>> bus: mhi: core: Abort suspends due to outgoing pending packets
>> bus: mhi: core: Use helper API to trigger a non-blocking host resume
>> bus: mhi: core: Trigger host resume if suspended during
>> mhi_device_get()
>> bus: mhi: core: Use generic name field for an MHI device
>> bus: mhi: core: Introduce helper function to check device state
>> bus: mhi: core: Introduce counters to track MHI device state
>> transitions
>> bus: mhi: core: Introduce debugfs entries for MHI
>> bus: mhi: core: Read and save device hardware information from BHI
>> bus: mhi: core: Introduce APIs to allocate and free the MHI
>> controller
>> bus: mhi: core: Introduce sysfs entries for MHI
>>
>> Documentation/ABI/stable/sysfs-bus-mhi | 21 ++
>> MAINTAINERS | 1 +
>> drivers/bus/mhi/Kconfig | 8 +
>> drivers/bus/mhi/core/Makefile | 5 +-
>> drivers/bus/mhi/core/boot.c | 17 +-
>> drivers/bus/mhi/core/debugfs.c | 409
>> +++++++++++++++++++++++++++++++++
>> drivers/bus/mhi/core/init.c | 81 ++++++-
>> drivers/bus/mhi/core/internal.h | 37 ++-
>> drivers/bus/mhi/core/main.c | 27 +--
>> drivers/bus/mhi/core/pm.c | 26 ++-
>> include/linux/mhi.h | 30 ++-
>> 11 files changed, 623 insertions(+), 39 deletions(-)
>> create mode 100644 Documentation/ABI/stable/sysfs-bus-mhi
>> create mode 100644 drivers/bus/mhi/core/debugfs.c
>>
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>> Forum,
>> a Linux Foundation Collaborative Project
>>

2020-08-18 09:56:07

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 00/11] Introduce features and debugfs/sysfs entries for MHI

On Tue, Aug 11, 2020 at 11:56:25AM +0530, Manivannan Sadhasivam wrote:
> Hi Bhaumik,
>
> On Mon, Aug 10, 2020 at 03:00:54PM -0700, Bhaumik Bhatt wrote:
> > Save hardware information from BHI.
> > Allow reading and modifying some MHI variables for debug, test, and
> > informational purposes using debugfs.
> > Read values for device specific hardware information to be used by OEMs in
> > factory testing such as serial number and PK hash using sysfs.
> >
> > This set of patches was tested on arm64 and x86.
> >
>
> Sorry for stretching the review so long. Will apply the series to mhi-next
> once v5.9-rc1 is out.

Series applied to mhi-next!

Thanks,
Mani

>
> Thanks,
> Mani
>
> > v7:
> > -Added suggested-by and reviewed-by tags
> > -Fixed nitpick on removal of M3_fast counter as it was unused
> > -Updated sysfs documentation dates and intended kernel version
> > -Fixed minor debugfs formatting by removing an extra newline character
> >
> > v6:
> > -Introduced APIs for allocating and freeing the MHI controller so as to ensure
> > that it is always zero-initialized
> > -Moved gerrits around for counter introduction
> > -Fixed documentation for sysfs
> >
> > v5:
> > -Removed the debug entry to trigger reset and will be addressed in a seperate
> > patch
> > -Added patch bus: mhi: core: Use counters to track MHI device state transitions
> > -Updated helper API to trigger a non-blocking host resume
> > -Minor nitpicks also fixed
> >
> > v4:
> > -Removed bus: mhi: core: Introduce independent voting mechanism patch
> > -Removed bus vote function from debugfs due to independent voting removal
> > -Added helper resume APIs to aid consolidation of spread out code
> > -Added a clean-up patch and a missing host resume in voting API
> >
> > v3:
> > -Add patch to check for pending packets in suspend as a dependency for the
> > independent voting mechanism introduction
> > -Include register dump entry for debugfs to dump MHI, BHI, and BHIe registers
> > -Update commit message for the debugfs patch
> > -Updated Documentation/ABI with the required info for sysfs
> > -Updated debugfs patch to include a new KConfig entry and dependencies
> > -Updated reviewed-by for some patches
> >
> > v2:
> > -Added a new debugfs.c file for specific debugfs entries and code
> > -Updated commit text and addressed some comments for voting change
> > -Made sure sysfs is only used for serial number and OEM PK hash usage
> >
> > Bhaumik Bhatt (11):
> > bus: mhi: core: Remove double occurrence for mhi_ctrl_ev_task()
> > declaration
> > bus: mhi: core: Abort suspends due to outgoing pending packets
> > bus: mhi: core: Use helper API to trigger a non-blocking host resume
> > bus: mhi: core: Trigger host resume if suspended during
> > mhi_device_get()
> > bus: mhi: core: Use generic name field for an MHI device
> > bus: mhi: core: Introduce helper function to check device state
> > bus: mhi: core: Introduce counters to track MHI device state
> > transitions
> > bus: mhi: core: Introduce debugfs entries for MHI
> > bus: mhi: core: Read and save device hardware information from BHI
> > bus: mhi: core: Introduce APIs to allocate and free the MHI controller
> > bus: mhi: core: Introduce sysfs entries for MHI
> >
> > Documentation/ABI/stable/sysfs-bus-mhi | 21 ++
> > MAINTAINERS | 1 +
> > drivers/bus/mhi/Kconfig | 8 +
> > drivers/bus/mhi/core/Makefile | 5 +-
> > drivers/bus/mhi/core/boot.c | 17 +-
> > drivers/bus/mhi/core/debugfs.c | 409 +++++++++++++++++++++++++++++++++
> > drivers/bus/mhi/core/init.c | 81 ++++++-
> > drivers/bus/mhi/core/internal.h | 37 ++-
> > drivers/bus/mhi/core/main.c | 27 +--
> > drivers/bus/mhi/core/pm.c | 26 ++-
> > include/linux/mhi.h | 30 ++-
> > 11 files changed, 623 insertions(+), 39 deletions(-)
> > create mode 100644 Documentation/ABI/stable/sysfs-bus-mhi
> > create mode 100644 drivers/bus/mhi/core/debugfs.c
> >
> > --
> > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> > a Linux Foundation Collaborative Project
> >