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

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

Merge "mhi: core: Prevent MHI reg read upon endpoint crash"

parents 5258ffaa 6acfe560
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1734,9 +1734,15 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev)
{

	struct mhi_controller *mhi_cntrl = dev;
	u32 in_reset = -1;

	/* wake up any events waiting for state change */
	MHI_VERB("Enter\n");
	if (unlikely(mhi_cntrl->initiate_mhi_reset)) {
		mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
			MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, &in_reset);
		mhi_cntrl->initiate_mhi_reset = !!in_reset;
	}
	wake_up_all(&mhi_cntrl->state_event);
	MHI_VERB("Exit\n");

+11 −8
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl,
	if (state == MHI_STATE_RESET) {
		mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
				    MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 1);
		mhi_cntrl->initiate_mhi_reset = true;
	} else {
		mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
				(state << MHICTRL_MHISTATE_SHIFT));
@@ -602,20 +603,18 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,

	/* trigger MHI RESET so device will not access host ddr */
	if (MHI_REG_ACCESS_VALID(prev_state)) {
		u32 in_reset = -1;
		unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms);

		MHI_LOG("Trigger device into MHI_RESET\n");

		write_lock_irq(&mhi_cntrl->pm_lock);
		mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);
		write_unlock_irq(&mhi_cntrl->pm_lock);

		/* wait for reset to be cleared */
		ret = wait_event_timeout(mhi_cntrl->state_event,
					 mhi_read_reg_field(mhi_cntrl,
						mhi_cntrl->regs, MHICTRL,
						MHICTRL_RESET_MASK,
						MHICTRL_RESET_SHIFT, &in_reset)
					 || !in_reset, timeout);
		if ((!ret || in_reset) && cur_state == MHI_PM_SYS_ERR_PROCESS) {
				!mhi_cntrl->initiate_mhi_reset, timeout);
		if (!ret && cur_state == MHI_PM_SYS_ERR_PROCESS) {
			MHI_CRITICAL("Device failed to exit RESET state\n");
			mutex_unlock(&mhi_cntrl->pm_mutex);
			return;
@@ -625,7 +624,11 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,
		 * device cleares INTVEC as part of RESET processing,
		 * re-program it
		 */
		mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
		if (!mhi_cntrl->initiate_mhi_reset)
			mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi,
				BHI_INTVEC, 0);

		mhi_cntrl->initiate_mhi_reset = false;
	}

	MHI_LOG("Waiting for all pending event ring processing to complete\n");
+1 −0
Original line number Diff line number Diff line
@@ -399,6 +399,7 @@ struct mhi_controller {
	/* controller specific data */
	const char *name;
	bool power_down;
	bool initiate_mhi_reset;
	void *priv_data;
	void *log_buf;
	struct dentry *dentry;