diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/core/boot.c index dcc38bc5ec98..6ccfb6b7d69f 100644 --- a/drivers/bus/mhi/core/boot.c +++ b/drivers/bus/mhi/core/boot.c @@ -53,17 +53,49 @@ void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, &mhi_buf->dma_addr, mhi_buf->len, sequence_id); } +/* 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, + BHIE_RXVECSTATUS_STATUS_SHFT, + &rx_status); + if (ret) + return -EIO; + + if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) { + MHI_LOG("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("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; MHI_VERB("Entered with pm_state:%s dev_state:%s ee:%s\n", @@ -123,25 +155,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, - BHIE_RXVECSTATUS_STATUS_SHFT, - &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("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); - - MHI_ERR("RXVEC_STATUS: 0x%x\n", rx_status); - error_exit_rddm: MHI_ERR("RDDM transfer failed. Current EE: %s\n", TO_MHI_EXEC_STR(ee)); diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h index 1b14dc608d9b..b1e30eec2a5c 100644 --- a/drivers/bus/mhi/core/internal.h +++ b/drivers/bus/mhi/core/internal.h @@ -634,6 +634,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/core/misc.c b/drivers/bus/mhi/core/misc.c index 82e340737c60..609f96e0bf77 100644 --- a/drivers/bus/mhi/core/misc.c +++ b/drivers/bus/mhi/core/misc.c @@ -1814,3 +1814,18 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, return ret; } 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("Entered with 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)); + + mhi_soc_reset(mhi_cntrl); + return mhi_rddm_download_status(mhi_cntrl); +} +EXPORT_SYMBOL(mhi_force_reset); diff --git a/include/linux/mhi_misc.h b/include/linux/mhi_misc.h index b8ff0ff1ac0a..73d434117f7a 100644 --- a/include/linux/mhi_misc.h +++ b/include/linux/mhi_misc.h @@ -259,6 +259,13 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, u64 local_time, u64 remote_time)); +/** + * mhi_force_reset - does host reset request to collect device side dumps + * for debugging purpose + * @mhi_cntrl: MHI controller + */ +int mhi_force_reset(struct mhi_controller *mhi_cntrl); + #else /** @@ -557,6 +564,16 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, return -EPERM; } +/** + * mhi_force_reset - does host reset request to collect device side dumps + * for debugging purpose + * @mhi_cntrl: MHI controller + */ +int mhi_force_reset(struct mhi_controller *mhi_cntrl) +{ + return -EINVAL; +} + #endif /* CONFIG_MHI_BUS_MISC */ #endif /* _MHI_MISC_H_ */