bus: mhi: core: 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 <bbhatt@codeaurora.org>
Signed-off-by: Vivek Pernamitta <vpernami@codeaurora.org>
This commit is contained in:
Vivek Pernamitta 2021-09-27 14:03:30 -07:00 committed by Bhaumik Bhatt
parent d7a52a7bba
commit 9506a75404
4 changed files with 72 additions and 20 deletions

View File

@ -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));

View File

@ -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 &&

View File

@ -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);

View File

@ -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_ */