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

Commit b5aa5171 authored by Hemant Kumar's avatar Hemant Kumar Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: Handle firmware load through state worker



Upon power up driver queues firmware worker thread if ee is in PBL.
Firmware worker is blocked with a timeout until state worker gets a
chance to run and unblock firmware worker. In case state worker gets a
chance to run after firmware worker timed out results into endpoint
boot up failure. Fix this issue by directly handling firmware loading
from state worker thread.

Change-Id: Id28c5a3eaa3b8075a7eb0185f7e08f21174e1d0d
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 2e72d893
Loading
Loading
Loading
Loading
+2 −13
Original line number Diff line number Diff line
@@ -528,10 +528,9 @@ static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
	}
}

void mhi_fw_load_worker(struct work_struct *work)
void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
{
	int ret;
	struct mhi_controller *mhi_cntrl;
	const char *fw_name;
	const struct firmware *firmware = NULL;
	struct image_info *image_info;
@@ -539,17 +538,7 @@ void mhi_fw_load_worker(struct work_struct *work)
	dma_addr_t dma_addr;
	size_t size;

	mhi_cntrl = container_of(work, struct mhi_controller, fw_worker);

	MHI_LOG("Waiting for device to enter PBL from EE:%s\n",
		TO_MHI_EXEC_STR(mhi_cntrl->ee));

	ret = wait_event_timeout(mhi_cntrl->state_event,
				 MHI_IN_PBL(mhi_cntrl->ee) ||
				 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
				 msecs_to_jiffies(mhi_cntrl->timeout_ms));

	if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
	if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
		MHI_ERR("MHI is not in valid state\n");
		return;
	}
+0 −1
Original line number Diff line number Diff line
@@ -1360,7 +1360,6 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
	spin_lock_init(&mhi_cntrl->transition_lock);
	spin_lock_init(&mhi_cntrl->wlock);
	INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker);
	INIT_WORK(&mhi_cntrl->fw_worker, mhi_fw_load_worker);
	INIT_WORK(&mhi_cntrl->low_priority_worker, mhi_low_priority_worker);
	init_waitqueue_head(&mhi_cntrl->state_event);

+1 −0
Original line number Diff line number Diff line
@@ -911,6 +911,7 @@ void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl);
int mhi_dtr_init(void);
void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
		      struct image_info *img_info);
void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl);
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
			struct mhi_chan *mhi_chan);
void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl);
+1 −5
Original line number Diff line number Diff line
@@ -644,7 +644,6 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,

	MHI_LOG("Waiting for all pending threads to complete\n");
	wake_up_all(&mhi_cntrl->state_event);
	flush_work(&mhi_cntrl->fw_worker);
	flush_work(&mhi_cntrl->low_priority_worker);

	/* remove support for time sync */
@@ -852,7 +851,7 @@ void mhi_pm_st_worker(struct work_struct *work)
				mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
			write_unlock_irq(&mhi_cntrl->pm_lock);
			if (MHI_IN_PBL(mhi_cntrl->ee))
				wake_up_all(&mhi_cntrl->state_event);
				mhi_fw_load_handler(mhi_cntrl);
			break;
		case MHI_ST_TRANSITION_SBL:
			write_lock_irq(&mhi_cntrl->pm_lock);
@@ -961,9 +960,6 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
	next_state = MHI_IN_PBL(current_ee) ?
		MHI_ST_TRANSITION_PBL : MHI_ST_TRANSITION_READY;

	if (next_state == MHI_ST_TRANSITION_PBL)
		schedule_work(&mhi_cntrl->fw_worker);

	mhi_queue_state_transition(mhi_cntrl, next_state);

	mhi_init_debugfs(mhi_cntrl);