From ce4a25729be4ee4ccfd83539350e43424f25fbd5 Mon Sep 17 00:00:00 2001 From: Vivek Pernamitta Date: Thu, 2 Sep 2021 13:03:20 +0530 Subject: [PATCH] bus: mhi: core: Add device hardware reset support The MHI specification allows to perform a hard reset of the device when writing to the SOC_RESET register. It can be used to completely restart the device (e.g. in case of unrecoverable MHI error). This is up to the MHI controller driver to determine when this hard reset should be used, and in case of MHI errors, should be used as a reset of last resort (after standard MHI stack reset). This function is a stateless function, the MHI layer do nothing except triggering the reset by writing into the right register(s), this is up to the caller to ensure right mhi_controller state (e.g. unregister the controller if necessary). Change-Id: I84a7c02b243301fd6e7d61fe8d23443aa4f8a171 Signed-off-by: Loic Poulain Reviewed-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam Git-commit: b5a8d233a588b3acf2a7a3a8da30f8f68f376626 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Bhaumik Bhatt Signed-off-by: Vivek Pernamitta --- drivers/bus/mhi/core/mhi_main.c | 15 ++++++++++++++- include/linux/mhi.h | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 2315552b831b..0ddbbeec7b8d 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include #include @@ -266,6 +266,19 @@ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL(mhi_get_mhi_state); +void mhi_soc_reset(struct mhi_controller *mhi_cntrl) +{ + if (mhi_cntrl->reset) { + mhi_cntrl->reset(mhi_cntrl); + return; + } + + /* Generic MHI SoC reset */ + mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, MHI_SOC_RESET_REQ_OFFSET, + MHI_SOC_RESET_REQ); +} +EXPORT_SYMBOL(mhi_soc_reset); + int mhi_queue_sclist(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan, void *buf, diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 9e96d615dfd5..d4dc08370cf0 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -258,6 +258,7 @@ struct reg_write_info { * @time_get: Return host time in us * @lpm_disable: Request controller to disable link level low power modes * @lpm_enable: Controller may enable link level low power modes again + * @reset: Controller specific reset function (optional) * @priv_data: Points to bus master's private data */ struct mhi_controller { @@ -390,6 +391,7 @@ struct mhi_controller { struct mhi_link_info *link_info); void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 val); + void (*reset)(struct mhi_controller *mhi_cntrl); /* channel to control DTR messaging */ struct mhi_device *dtr_dev; @@ -887,6 +889,13 @@ enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl); */ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); +/** + * mhi_soc_reset - Trigger a device reset. This can be used as a last resort + * to reset and recover a device. + * @mhi_cntrl: MHI controller + */ +void mhi_soc_reset(struct mhi_controller *mhi_cntrl); + /** * mhi_set_mhi_state - Set device state * @mhi_cntrl: MHI controller