diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/core/boot.c
index 74295d3cc662..b0576ffc69c6 100644
--- a/drivers/bus/mhi/core/boot.c
+++ b/drivers/bus/mhi/core/boot.c
@@ -18,6 +18,17 @@
 #include <linux/wait.h>
 #include "internal.h"
 
+struct mhi_fw_load_callback_ctx {
+	const char *fw_name;
+	struct mhi_controller *mhi_cntrl;
+};
+
+enum mhi_fw_load_status {
+	MHI_FW_LOAD_READY_STATE,
+	MHI_FW_ERROR_READY_STATE,
+	MHI_FW_ERROR_FW_LOAD,
+};
+
 /* Setup RDDM vector table for RDDM transfer and program RXVEC */
 void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
 		      struct image_info *img_info)
@@ -386,55 +397,53 @@ static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
 	}
 }
 
-void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
+static void mhi_fw_load_finish(struct mhi_controller *mhi_cntrl, enum mhi_fw_load_status status)
 {
-	const struct firmware *firmware = NULL;
 	struct device *dev = &mhi_cntrl->mhi_dev->dev;
-	const char *fw_name;
-	void *buf;
-	dma_addr_t dma_addr;
-	size_t size;
-	int i, ret;
+	int ret;
 
-	if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
-		dev_err(dev, "Device MHI is not in valid state\n");
-		return;
+	switch (status) {
+	case MHI_FW_LOAD_READY_STATE:
+		break;
+	case MHI_FW_ERROR_READY_STATE:
+		goto error_ready_state;
+	case MHI_FW_ERROR_FW_LOAD:
+		goto error_fw_load;
 	}
 
-	/* save hardware info from BHI */
-	ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_SERIALNU,
-			   &mhi_cntrl->serial_number);
-	if (ret)
-		dev_err(dev, "Could not capture serial number via BHI\n");
-
-	for (i = 0; i < ARRAY_SIZE(mhi_cntrl->oem_pk_hash); i++) {
-		ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_OEMPKHASH(i),
-				   &mhi_cntrl->oem_pk_hash[i]);
-		if (ret) {
-			dev_err(dev, "Could not capture OEM PK HASH via BHI\n");
-			break;
-		}
+	/* Transitioning into MHI RESET->READY state */
+	ret = mhi_ready_state_transition(mhi_cntrl);
+	if (ret) {
+		dev_err(dev, "MHI did not enter READY state\n");
+		goto error_ready_state;
 	}
 
-	/* wait for ready on pass through or any other execution environment */
-	if (!MHI_FW_LOAD_CAPABLE(mhi_cntrl->ee))
-		goto fw_load_ready_state;
-
-	fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ?
-		mhi_cntrl->edl_image : mhi_cntrl->fw_image;
+	dev_info(dev, "Wait for device to enter SBL or Mission mode\n");
+	return;
 
-	if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size ||
-						     !mhi_cntrl->seg_len))) {
-		dev_err(dev,
-			"No firmware image defined or !sbl_size || !seg_len\n");
-		goto error_fw_load;
+error_ready_state:
+	if (mhi_cntrl->fbc_download) {
+		mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
+		mhi_cntrl->fbc_image = NULL;
 	}
 
-	ret = request_firmware(&firmware, fw_name, dev);
-	if (ret) {
-		dev_err(dev, "Error loading firmware: %d\n", ret);
-		goto error_fw_load;
-	}
+error_fw_load:
+	mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+	wake_up_all(&mhi_cntrl->state_event);
+}
+
+static void mhi_fw_load_callback(const struct firmware *firmware, void *context)
+{
+	struct mhi_fw_load_callback_ctx *ctx = context;
+	const char *fw_name = ctx->fw_name;
+	struct mhi_controller *mhi_cntrl = ctx->mhi_cntrl;
+	struct device *dev = &mhi_cntrl->mhi_dev->dev;
+	dma_addr_t dma_addr;
+	size_t size;
+	void *buf;
+	int ret;
+
+	kfree(context);
 
 	size = (mhi_cntrl->fbc_download) ? mhi_cntrl->sbl_size : firmware->size;
 
@@ -446,7 +455,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
 				 GFP_KERNEL);
 	if (!buf) {
 		release_firmware(firmware);
-		goto error_fw_load;
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_ERROR_FW_LOAD);
 	}
 
 	/* Download image using BHI */
@@ -458,13 +467,13 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
 	if (ret) {
 		dev_err(dev, "MHI did not load image over BHI, ret: %d\n", ret);
 		release_firmware(firmware);
-		goto error_fw_load;
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_ERROR_FW_LOAD);
 	}
 
 	/* Wait for ready since EDL image was loaded */
 	if (fw_name == mhi_cntrl->edl_image) {
 		release_firmware(firmware);
-		goto fw_load_ready_state;
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_LOAD_READY_STATE);
 	}
 
 	write_lock_irq(&mhi_cntrl->pm_lock);
@@ -480,7 +489,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
 					   firmware->size);
 		if (ret) {
 			release_firmware(firmware);
-			goto error_fw_load;
+			mhi_fw_load_finish(mhi_cntrl, MHI_FW_ERROR_FW_LOAD);
 		}
 
 		/* Load the firmware into BHIE vec table */
@@ -489,26 +498,60 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
 
 	release_firmware(firmware);
 
-fw_load_ready_state:
-	/* Transitioning into MHI RESET->READY state */
-	ret = mhi_ready_state_transition(mhi_cntrl);
-	if (ret) {
-		dev_err(dev, "MHI did not enter READY state\n");
-		goto error_ready_state;
+	mhi_fw_load_finish(mhi_cntrl, MHI_FW_LOAD_READY_STATE);
+}
+
+void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
+{
+	struct device *dev = &mhi_cntrl->mhi_dev->dev;
+	struct mhi_fw_load_callback_ctx *cb_ctx;
+	const char *fw_name;
+	int i, ret;
+
+	if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
+		dev_err(dev, "Device MHI is not in valid state\n");
+		return;
 	}
 
-	dev_info(dev, "Wait for device to enter SBL or Mission mode\n");
-	return;
+	/* save hardware info from BHI */
+	ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_SERIALNU,
+			   &mhi_cntrl->serial_number);
+	if (ret)
+		dev_err(dev, "Could not capture serial number via BHI\n");
 
-error_ready_state:
-	if (mhi_cntrl->fbc_download) {
-		mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
-		mhi_cntrl->fbc_image = NULL;
+	for (i = 0; i < ARRAY_SIZE(mhi_cntrl->oem_pk_hash); i++) {
+		ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_OEMPKHASH(i),
+				   &mhi_cntrl->oem_pk_hash[i]);
+		if (ret) {
+			dev_err(dev, "Could not capture OEM PK HASH via BHI\n");
+			break;
+		}
 	}
 
-error_fw_load:
-	mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
-	wake_up_all(&mhi_cntrl->state_event);
+	/* wait for ready on pass through or any other execution environment */
+	if (!MHI_FW_LOAD_CAPABLE(mhi_cntrl->ee))
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_LOAD_READY_STATE);
+
+	fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ?
+		mhi_cntrl->edl_image : mhi_cntrl->fw_image;
+
+	if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size ||
+						     !mhi_cntrl->seg_len))) {
+		dev_err(dev,
+			"No firmware image defined or !sbl_size || !seg_len\n");
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_ERROR_FW_LOAD);
+	}
+
+	cb_ctx = kzalloc(sizeof(*cb_ctx), GFP_KERNEL);
+	if (!cb_ctx)
+		return;
+
+	ret = request_firmware_nowait(THIS_MODULE, true, fw_name, dev, GFP_KERNEL, cb_ctx,
+				      mhi_fw_load_callback);
+	if (ret) {
+		dev_err(dev, "Error loading firmware: %d\n", ret);
+		mhi_fw_load_finish(mhi_cntrl, MHI_FW_ERROR_FW_LOAD);
+	}
 }
 
 int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
