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

Commit 6eec9af5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mhi: core: serialize execution environment and power off changes"

parents 9ee4f810 39215500
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -728,7 +728,6 @@ int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)
	}

	msm_pcie_l1ss_timeout_enable(pci_dev);
	mhi_cntrl->force_m3_done = true;

	MHI_LOG("Exited\n");

+0 −2
Original line number Diff line number Diff line
@@ -690,8 +690,6 @@ static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev)
	mhi_cntrl->iova_start = memblock_start_of_DRAM();
	mhi_cntrl->iova_stop = memblock_end_of_DRAM();

	mhi_cntrl->need_force_m3 = true;

	/* setup host support for SFR retreival */
	if (of_property_read_bool(of_node, "mhi,sfr-support"))
		mhi_cntrl->sfr_len = MHI_MAX_SFR_LEN;
+37 −28
Original line number Diff line number Diff line
@@ -1298,6 +1298,10 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
				TO_MHI_EXEC_STR(event));
			switch (event) {
			case MHI_EE_SBL:
				write_lock_irq(&mhi_cntrl->pm_lock);
				mhi_cntrl->ee = MHI_EE_SBL;
				write_unlock_irq(&mhi_cntrl->pm_lock);
				wake_up_all(&mhi_cntrl->state_event);
				st = MHI_ST_TRANSITION_SBL;
				break;
			case MHI_EE_WFW:
@@ -1305,13 +1309,6 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
				st = MHI_ST_TRANSITION_MISSION_MODE;
				break;
			case MHI_EE_RDDM:
				mhi_cntrl->status_cb(mhi_cntrl,
						     mhi_cntrl->priv_data,
						     MHI_CB_EE_RDDM);
				write_lock_irq(&mhi_cntrl->pm_lock);
				mhi_cntrl->ee = event;
				write_unlock_irq(&mhi_cntrl->pm_lock);
				wake_up_all(&mhi_cntrl->state_event);
				break;
			default:
				MHI_ERR("Unhandled EE event:%s\n",
@@ -1493,9 +1490,6 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
		goto exit_no_lock;
	}

	if (mhi_cntrl->need_force_m3 && !mhi_cntrl->force_m3_done)
		goto exit_no_lock;

	ret = __mhi_device_get_sync(mhi_cntrl);
	if (ret)
		goto exit_no_lock;
@@ -1670,14 +1664,21 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev)
	MHI_VERB("Enter\n");

	write_lock_irq(&mhi_cntrl->pm_lock);
	if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
	if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
		write_unlock_irq(&mhi_cntrl->pm_lock);
		goto exit_intvec;
	}

	state = mhi_get_mhi_state(mhi_cntrl);
		ee = mhi_cntrl->ee;
		mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
	ee = mhi_get_exec_env(mhi_cntrl);
	MHI_LOG("local ee:%s device ee:%s dev_state:%s\n",
			TO_MHI_EXEC_STR(ee),
		TO_MHI_EXEC_STR(mhi_cntrl->ee),
		TO_MHI_EXEC_STR(ee),
		TO_MHI_STATE_STR(state));

	if (mhi_cntrl->power_down) {
		write_unlock_irq(&mhi_cntrl->pm_lock);
		goto exit_intvec;
	}

	if (state == MHI_STATE_SYS_ERR) {
@@ -1687,20 +1688,28 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev)
	}
	write_unlock_irq(&mhi_cntrl->pm_lock);

	/* if device in rddm don't bother processing sys error */
	if (mhi_cntrl->ee == MHI_EE_RDDM && ee != MHI_EE_DISABLE_TRANSITION) {
		if (mhi_cntrl->ee != ee) {
	if (ee == MHI_EE_RDDM) {
		write_lock_irq(&mhi_cntrl->pm_lock);
		if (mhi_cntrl->ee == MHI_EE_RDDM) {
			write_unlock_irq(&mhi_cntrl->pm_lock);
			goto exit_intvec;
		}
		mhi_cntrl->ee = MHI_EE_RDDM;
		write_unlock_irq(&mhi_cntrl->pm_lock);

		MHI_ERR("RDDM event occurred!\n");
		mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
				     MHI_CB_EE_RDDM);
		wake_up_all(&mhi_cntrl->state_event);

		/* notify critical clients with early notifications */
		mhi_control_error(mhi_cntrl);
		}

		goto exit_intvec;
	}

	if (pm_state == MHI_PM_SYS_ERR_DETECT) {
	/* if device is in RDDM, don't bother processing SYS_ERR */
	if (ee != MHI_EE_RDDM && pm_state == MHI_PM_SYS_ERR_DETECT) {
		wake_up_all(&mhi_cntrl->state_event);

		/* for fatal errors, we let controller decide next step */
+19 −16
Original line number Diff line number Diff line
@@ -471,12 +471,16 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
		ee = mhi_get_exec_env(mhi_cntrl);
	write_unlock_irq(&mhi_cntrl->pm_lock);

	if (!MHI_IN_MISSION_MODE(ee))
	if (!MHI_IN_MISSION_MODE(ee)) {
		MHI_ERR("Invalid EE:%s\n", TO_MHI_EXEC_STR(ee));
		return -EIO;
	}

	mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
			     MHI_CB_EE_MISSION_MODE);
	write_lock_irq(&mhi_cntrl->pm_lock);
	mhi_cntrl->ee = ee;
	write_unlock_irq(&mhi_cntrl->pm_lock);

	wake_up_all(&mhi_cntrl->state_event);

@@ -583,8 +587,6 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,
		mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION;
		mhi_cntrl->dev_state = MHI_STATE_RESET;
	}
	/* notify controller of power down regardless of state transitions */
	mhi_cntrl->power_down = true;
	write_unlock_irq(&mhi_cntrl->pm_lock);

	/* wake up any threads waiting for state transitions */
@@ -648,8 +650,6 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,
	wake_up_all(&mhi_cntrl->state_event);
	flush_work(&mhi_cntrl->special_work);

	mhi_cntrl->force_m3_done = false;

	if (sfr_info && sfr_info->buf_addr) {
		mhi_free_coherent(mhi_cntrl, sfr_info->len, sfr_info->buf_addr,
				  sfr_info->dma_addr);
@@ -833,6 +833,10 @@ void mhi_process_sys_err(struct mhi_controller *mhi_cntrl)
		return;
	}

	write_lock_irq(&mhi_cntrl->pm_lock);
	mhi_cntrl->power_down = true;
	write_unlock_irq(&mhi_cntrl->pm_lock);

	mhi_queue_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS);
}

@@ -858,14 +862,9 @@ void mhi_pm_st_worker(struct work_struct *work)
			if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
				mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
			write_unlock_irq(&mhi_cntrl->pm_lock);
			if (MHI_IN_PBL(mhi_cntrl->ee))
			mhi_fw_load_handler(mhi_cntrl);
			break;
		case MHI_ST_TRANSITION_SBL:
			write_lock_irq(&mhi_cntrl->pm_lock);
			mhi_cntrl->ee = MHI_EE_SBL;
			write_unlock_irq(&mhi_cntrl->pm_lock);
			wake_up_all(&mhi_cntrl->state_event);
			mhi_create_devices(mhi_cntrl);
			break;
		case MHI_ST_TRANSITION_MISSION_MODE:
@@ -952,6 +951,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
	}

	mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
	mhi_cntrl->power_down = false;
	mhi_cntrl->pm_state = MHI_PM_POR;
	mhi_cntrl->ee = MHI_EE_MAX;
	current_ee = mhi_get_exec_env(mhi_cntrl);
@@ -979,6 +979,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
	return 0;

error_bhi_offset:
	mhi_cntrl->power_down = true;
	mhi_deinit_free_irq(mhi_cntrl);

error_setup_irq:
@@ -1045,21 +1046,23 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
	enum MHI_PM_STATE cur_state;
	enum MHI_PM_STATE transition_state = MHI_PM_SHUTDOWN_PROCESS;

	/* if it's not graceful shutdown, force MHI to a linkdown state */
	if (!graceful) {
	mutex_lock(&mhi_cntrl->pm_mutex);

	write_lock_irq(&mhi_cntrl->pm_lock);
	mhi_cntrl->power_down = true;
	/* if it's not graceful shutdown, force MHI to a linkdown state */
	if (!graceful) {
		cur_state = mhi_tryset_pm_state(mhi_cntrl,
						MHI_PM_LD_ERR_FATAL_DETECT);
		write_unlock_irq(&mhi_cntrl->pm_lock);
		mutex_unlock(&mhi_cntrl->pm_mutex);
		if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT)
			MHI_ERR("Failed to move to state:%s from:%s\n",
				to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT),
				to_mhi_pm_state_str(mhi_cntrl->pm_state));

		transition_state = MHI_PM_SHUTDOWN_NO_ACCESS;
	}
	write_unlock_irq(&mhi_cntrl->pm_lock);

	mutex_unlock(&mhi_cntrl->pm_mutex);

	mhi_queue_disable_transition(mhi_cntrl, transition_state);

+0 −2
Original line number Diff line number Diff line
@@ -399,8 +399,6 @@ struct mhi_controller {
	/* controller specific data */
	const char *name;
	bool power_down;
	bool need_force_m3;
	bool force_m3_done;
	void *priv_data;
	void *log_buf;
	struct dentry *dentry;