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

Commit ba427d47 authored by Hemant Kumar's avatar Hemant Kumar
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 9d4b29a3
Loading
Loading
Loading
Loading
+2 −13
Original line number Diff line number Diff line
@@ -523,10 +523,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;
	struct image_info *image_info;
@@ -534,17 +533,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
@@ -1341,7 +1341,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
@@ -908,6 +908,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);

+1 −5
Original line number Diff line number Diff line
@@ -629,7 +629,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);

	mutex_lock(&mhi_cntrl->pm_mutex);
@@ -837,7 +836,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);
@@ -946,9 +945,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);