Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73928139 authored by Bhaumik Bhatt's avatar Bhaumik Bhatt
Browse files

mhi: core: Move to error state if firmware could not be loaded



Move MHI to a firmware download error state for any bootup
failures such as unable to find firmware files or load images via
BHI/BHIe. This helps detect an error state sooner and shortens
the wait for a synchronous power up timeout. It also negates the
need to provide additional callbacks due to any intermediate
bootup failures.

Change-Id: I3307e432063f59e978f1e055453155803a6475b2
Signed-off-by: default avatarBhaumik Bhatt <bbhatt@codeaurora.org>
parent 4141c875
Loading
Loading
Loading
Loading
+30 −20
Original line number Diff line number Diff line
@@ -444,6 +444,9 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
	int i;
	struct mhi_buf *mhi_buf = image_info->mhi_buf;

	if (!image_info)
		return;

	for (i = 0; i < image_info->entries; i++, mhi_buf++)
		mhi_free_contig_coherent(mhi_cntrl, mhi_buf->len, mhi_buf->buf,
				  mhi_buf->dma_addr);
@@ -571,14 +574,14 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
						     !mhi_cntrl->seg_len))) {
		MHI_CNTRL_ERR(
			"No firmware image defined or !sbl_size || !seg_len\n");
		return;
		goto fw_load_error;
	}

	ret = request_firmware(&firmware, fw_name, mhi_cntrl->dev);
	if (ret) {
		if (!mhi_cntrl->fw_image_fallback) {
			MHI_CNTRL_ERR("Error loading fw, ret:%d\n", ret);
			return;
			goto fw_load_error;
		}

		/* re-try with fall back fw image */
@@ -586,7 +589,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
				mhi_cntrl->dev);
		if (ret) {
			MHI_CNTRL_ERR("Error loading fw_fb, ret:%d\n", ret);
			return;
			goto fw_load_error;
		}

		mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
@@ -602,8 +605,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
	buf = mhi_alloc_coherent(mhi_cntrl, size, &dma_addr, GFP_KERNEL);
	if (!buf) {
		MHI_CNTRL_ERR("Could not allocate memory for image\n");
		release_firmware(firmware);
		return;
		goto fw_load_error_release;
	}

	/* load sbl or edl image via BHI */
@@ -611,17 +613,16 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
	ret = mhi_fw_load_bhi(mhi_cntrl, dma_addr, size);
	mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);

	if (!mhi_cntrl->fbc_download || ret || mhi_cntrl->ee == MHI_EE_EDL)
		release_firmware(firmware);

	if (ret) {
		MHI_CNTRL_ERR("MHI did not load SBL/EDL image, ret:%d\n", ret);
		return;
		goto fw_load_error_release;
	}

	/* we are done with FW load is EE is EDL */
	if (mhi_cntrl->ee == MHI_EE_EDL)
	if (mhi_cntrl->ee == MHI_EE_EDL) {
		release_firmware(firmware);
		return;
	}

	write_lock_irq(&mhi_cntrl->pm_lock);
	mhi_cntrl->dev_state = MHI_STATE_RESET;
@@ -636,7 +637,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
					   firmware->size);
		if (ret) {
			MHI_CNTRL_ERR("Error alloc size:%zu\n", firmware->size);
			goto error_alloc_fw_table;
			goto fw_load_error_ready;
		}

		MHI_CNTRL_LOG("Copying firmware image into vector table\n");
@@ -645,6 +646,9 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
		mhi_firmware_copy(mhi_cntrl, firmware, mhi_cntrl->fbc_image);
	}

	release_firmware(firmware);
	firmware = NULL;

fw_load_ee_pthru:
	/* transitioning into MHI RESET->READY state */
	ret = mhi_ready_state_transition(mhi_cntrl);
@@ -653,15 +657,14 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
			to_mhi_pm_state_str(mhi_cntrl->pm_state),
			TO_MHI_STATE_STR(mhi_cntrl->dev_state),
			TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);

	if (!mhi_cntrl->fbc_download)
		return;

	if (ret) {
		MHI_CNTRL_ERR("Did not transition to READY state\n");
		goto error_read;
		goto fw_load_error_ready;
	}

	if (!mhi_cntrl->fbc_download || mhi_cntrl->ee == MHI_EE_PTHRU)
		return;

	/* wait for SBL event */
	ret = wait_event_timeout(mhi_cntrl->state_event,
				 mhi_cntrl->ee == MHI_EE_SBL ||
@@ -670,7 +673,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)

	if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
		MHI_CNTRL_ERR("MHI did not enter BHIE\n");
		goto error_read;
		goto fw_load_error_ready;
	}

	/* start full firmware image download */
@@ -681,16 +684,23 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)

	MHI_CNTRL_LOG("amss fw_load ret:%d\n", ret);

	release_firmware(firmware);
	if (ret)
		goto fw_load_error;

	return;

error_read:
fw_load_error_ready:
	mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
	mhi_cntrl->fbc_image = NULL;

error_alloc_fw_table:
fw_load_error_release:
	release_firmware(firmware);

fw_load_error:
	write_lock_irq(&mhi_cntrl->pm_lock);
	mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
	wake_up_all(&mhi_cntrl->state_event);
	write_unlock_irq(&mhi_cntrl->pm_lock);
}

void mhi_perform_soc_reset(struct mhi_controller *mhi_cntrl)
+4 −1
Original line number Diff line number Diff line
@@ -481,12 +481,15 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
	write_lock_irq(&mhi_cntrl->pm_lock);
	if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
		ee = mhi_get_exec_env(mhi_cntrl);
	write_unlock_irq(&mhi_cntrl->pm_lock);

	if (!MHI_IN_MISSION_MODE(ee)) {
		MHI_CNTRL_ERR("Invalid EE:%s\n", TO_MHI_EXEC_STR(ee));
		mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
		wake_up_all(&mhi_cntrl->state_event);
		write_unlock_irq(&mhi_cntrl->pm_lock);
		return -EIO;
	}
	write_unlock_irq(&mhi_cntrl->pm_lock);

	mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
			     MHI_CB_EE_MISSION_MODE);