From 38dced66d3b8803488f055b1e3cf3145497c61b7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Wed, 13 Oct 2021 12:51:30 -0700 Subject: [PATCH] bus: mhi: host: Add RDDM check in mhi_pm_resume() If a device crash occurs when in suspended state, the interrupt handler cannot access registers to act on it. Once controller is done with PCIe resume and calls mhi_pm_resume(), MHI host can check for the RDDM entry and handle it as needed. Change-Id: I6127b75b51c3ef932e601391daebd0657e1a04eb Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 4841984fefc4..d6a15e370166 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -820,6 +820,28 @@ void mhi_pm_st_worker(struct work_struct *work) } } +static bool mhi_in_rddm(struct mhi_controller *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + + if (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM + && mhi_is_active(mhi_cntrl)) { + mhi_cntrl->ee = MHI_EE_RDDM; + + MHI_ERR(dev, "RDDM event occurred!\n"); + + /* notify critical clients with early notifications */ + mhi_report_error(mhi_cntrl); + + mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM); + wake_up_all(&mhi_cntrl->state_event); + + return true; + } + + return false; +} + int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) { struct mhi_chan *itr, *tmp; @@ -935,6 +957,9 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) panic("mhi_pm_state != M3"); + if (mhi_in_rddm(mhi_cntrl)) + return 0; + /* Notify clients about exiting LPM */ list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { mutex_lock(&itr->mutex); @@ -965,6 +990,8 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { + if (mhi_in_rddm(mhi_cntrl)) + return 0; dev_err(dev, "Did not enter M0 state, MHI state: %s, PM state: %s\n", mhi_state_str(mhi_cntrl->dev_state),