From d0737d448db37f9b12d1311db796bfe799e7be17 Mon Sep 17 00:00:00 2001 From: Vivek Pernamitta Date: Mon, 27 Sep 2021 14:03:30 -0700 Subject: [PATCH] bus: mhi: host: Provide an API to perform host reset request Adding new API to perform host reset request to device to collect device side dumps. Use mhi_soc_reset() API in place of register write Currently, a direct register write is used when ramdump collection in panic path occurs. Replace that with new mhi_soc_reset() API such that a controller defined reset() function is exercised if one is present and the regular SOC reset is done if it is not. Change-Id: Ibd15b231072a9b811ced0031387d605184806e9a Signed-off-by: Bhaumik Bhatt Signed-off-by: Vivek Pernamitta Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 56 ++++++++++++++++++++++----------- drivers/bus/mhi/host/internal.h | 3 +- drivers/bus/mhi/host/misc.c | 18 +++++++++++ 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 49bf041cd3e0..6b30eb14d619 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -59,17 +59,48 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, return 0; } +/* check RDDM image is downloaded */ +int mhi_rddm_download_status(struct mhi_controller *mhi_cntrl) +{ + u32 rx_status; + enum mhi_ee_type ee; + const u32 delayus = 5000; + void __iomem *base = mhi_cntrl->bhie; + u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret = 0; + + while (retry--) { + ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, + BHIE_RXVECSTATUS_STATUS_BMSK, + &rx_status); + if (ret) + return -EIO; + + if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) { + MHI_LOG(dev, "RDDM dumps collected successfully"); + return 0; + } + + udelay(delayus); + } + + ee = mhi_get_exec_env(mhi_cntrl); + ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status); + MHI_ERR(dev, "ret: %d, RXVEC_STATUS: 0x%x, EE:%s\n", ret, rx_status, + TO_MHI_EXEC_STR(ee)); + + return -EIO; +} + /* Collect RDDM buffer during kernel panic */ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) { int ret; - u32 rx_status; enum mhi_ee_type ee; const u32 delayus = 2000; - u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; const u32 rddm_timeout_us = 200000; int rddm_retry = rddm_timeout_us / delayus; - void __iomem *base = mhi_cntrl->bhie; struct device *dev = &mhi_cntrl->mhi_dev->dev; dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", @@ -129,23 +160,12 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) "Waiting for RDDM image download via BHIe, current EE:%s\n", TO_MHI_EXEC_STR(ee)); - while (retry--) { - ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, - BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status); - if (ret) - return -EIO; - - if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) - return 0; - - udelay(delayus); + ret = mhi_rddm_download_status(mhi_cntrl); + if (!ret) { + MHI_LOG(dev, "RDDM dumps collected successfully"); + return 0; } - ee = mhi_get_exec_env(mhi_cntrl); - ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status); - - dev_err(dev, "RXVEC_STATUS: 0x%x\n", rx_status); - error_exit_rddm: dev_err(dev, "RDDM transfer failed. Current EE: %s\n", TO_MHI_EXEC_STR(ee)); diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index b88330658270..07fdf4ac063a 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -296,6 +296,7 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl); int mhi_send_cmd(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, enum mhi_cmd_type cmd); int mhi_download_amss_image(struct mhi_controller *mhi_cntrl); +int mhi_rddm_download_status(struct mhi_controller *mhi_cntrl); static inline bool mhi_is_active(struct mhi_controller *mhi_cntrl) { return (mhi_cntrl->dev_state >= MHI_STATE_M0 && diff --git a/drivers/bus/mhi/host/misc.c b/drivers/bus/mhi/host/misc.c index 511502d88f9f..1f8ca24854b6 100644 --- a/drivers/bus/mhi/host/misc.c +++ b/drivers/bus/mhi/host/misc.c @@ -1890,6 +1890,24 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, } EXPORT_SYMBOL(mhi_get_remote_time); +/* MHI host reset request*/ +int mhi_force_reset(struct mhi_controller *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + + MHI_VERB(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + mhi_state_str(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(mhi_cntrl->ee)); + + /* notify critical clients in absence of RDDM */ + mhi_report_error(mhi_cntrl); + + mhi_soc_reset(mhi_cntrl); + return mhi_rddm_download_status(mhi_cntrl); +} +EXPORT_SYMBOL(mhi_force_reset); + /* Get SoC info before registering mhi controller */ int mhi_get_soc_info(struct mhi_controller *mhi_cntrl) {