--- /dev/null
+From 4884362f6977fc05cbec736625665241c0e0732f Mon Sep 17 00:00:00 2001
+From: Bhaumik Bhatt <bbhatt@codeaurora.org>
+Date: Wed, 24 Feb 2021 15:23:03 -0800
+Subject: bus: mhi: core: Download AMSS image from appropriate function
+
+From: Bhaumik Bhatt <bbhatt@codeaurora.org>
+
+commit 4884362f6977fc05cbec736625665241c0e0732f upstream.
+
+During full boot chain firmware download, the PM state worker
+downloads the AMSS image after a blocking wait for the SBL
+execution environment change when running in PBL transition
+itself. Improve this design by having the host download the AMSS
+image from the SBL transition of PM state worker thread when a
+DEV_ST_TRANSITION_SBL is queued instead of the blocking wait.
+
+Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
+Link: https://lore.kernel.org/r/1614208985-20851-3-git-send-email-bbhatt@codeaurora.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/core/boot.c | 51 ++++++++++++++++++----------------------
+ drivers/bus/mhi/core/internal.h | 1
+ drivers/bus/mhi/core/pm.c | 2 +
+ 3 files changed, 27 insertions(+), 27 deletions(-)
+
+--- a/drivers/bus/mhi/core/boot.c
++++ b/drivers/bus/mhi/core/boot.c
+@@ -389,7 +389,6 @@ static void mhi_firmware_copy(struct mhi
+ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
+ {
+ const struct firmware *firmware = NULL;
+- struct image_info *image_info;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
+ const char *fw_name;
+ void *buf;
+@@ -491,44 +490,42 @@ void mhi_fw_load_handler(struct mhi_cont
+ fw_load_ee_pthru:
+ /* Transitioning into MHI RESET->READY state */
+ ret = mhi_ready_state_transition(mhi_cntrl);
+-
+- if (!mhi_cntrl->fbc_download)
+- return;
+-
+ if (ret) {
+ dev_err(dev, "MHI did not enter READY state\n");
+ goto error_ready_state;
+ }
+
+- /* Wait for the SBL event */
+- ret = wait_event_timeout(mhi_cntrl->state_event,
+- mhi_cntrl->ee == MHI_EE_SBL ||
+- MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
+- msecs_to_jiffies(mhi_cntrl->timeout_ms));
++ dev_info(dev, "Wait for device to enter SBL or Mission mode\n");
++ return;
+
+- if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
+- dev_err(dev, "MHI did not enter SBL\n");
+- goto error_ready_state;
++error_ready_state:
++ if (mhi_cntrl->fbc_download) {
++ mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
++ mhi_cntrl->fbc_image = NULL;
+ }
+
+- /* Start full firmware image download */
+- image_info = mhi_cntrl->fbc_image;
++error_fw_load:
++ mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
++ wake_up_all(&mhi_cntrl->state_event);
++}
++
++int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
++{
++ struct image_info *image_info = mhi_cntrl->fbc_image;
++ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ int ret;
++
++ if (!image_info)
++ return -EIO;
++
+ ret = mhi_fw_load_bhie(mhi_cntrl,
+ /* Vector table is the last entry */
+ &image_info->mhi_buf[image_info->entries - 1]);
+ if (ret) {
+- dev_err(dev, "MHI did not load image over BHIe, ret: %d\n",
+- ret);
+- goto error_fw_load;
++ dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
++ mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
++ wake_up_all(&mhi_cntrl->state_event);
+ }
+
+- return;
+-
+-error_ready_state:
+- mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
+- mhi_cntrl->fbc_image = NULL;
+-
+-error_fw_load:
+- mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+- wake_up_all(&mhi_cntrl->state_event);
++ return ret;
+ }
+--- a/drivers/bus/mhi/core/internal.h
++++ b/drivers/bus/mhi/core/internal.h
+@@ -619,6 +619,7 @@ int mhi_pm_m3_transition(struct mhi_cont
+ 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);
+ static inline bool mhi_is_active(struct mhi_controller *mhi_cntrl)
+ {
+ return (mhi_cntrl->dev_state >= MHI_STATE_M0 &&
+--- a/drivers/bus/mhi/core/pm.c
++++ b/drivers/bus/mhi/core/pm.c
+@@ -759,6 +759,8 @@ void mhi_pm_st_worker(struct work_struct
+ * either SBL or AMSS states
+ */
+ mhi_create_devices(mhi_cntrl);
++ if (mhi_cntrl->fbc_download)
++ mhi_download_amss_image(mhi_cntrl);
+ break;
+ case DEV_ST_TRANSITION_MISSION_MODE:
+ mhi_pm_mission_mode_transition(mhi_cntrl);