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

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

Merge "mhi: core: fix bandwidth scaling initialization failure"

parents ad91fff0 6275ce75
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */

#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -321,6 +321,9 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
			mhi_buf->len);

	mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
	if (unlikely(!mhi_cntrl->sequence_id))
		mhi_cntrl->sequence_id = 1;

	mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS,
			    BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT,
			    mhi_cntrl->sequence_id);
@@ -383,6 +386,9 @@ static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
		      lower_32_bits(dma_addr));
	mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGSIZE, size);
	mhi_cntrl->session_id = prandom_u32() & BHI_TXDB_SEQNUM_BMSK;
	if (unlikely(!mhi_cntrl->session_id))
		mhi_cntrl->session_id = 1;

	mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGTXDB,
			mhi_cntrl->session_id);
	read_unlock_bh(pm_lock);
+1 −1
Original line number Diff line number Diff line
@@ -703,7 +703,7 @@ static int mhi_init_bw_scale(struct mhi_controller *mhi_cntrl)

	/* No ER configured to support BW scale */
	er_index = mhi_get_er_index(mhi_cntrl, MHI_ER_BW_SCALE_ELEMENT_TYPE);
	if (ret < 0)
	if (er_index < 0)
		return er_index;

	bw_cfg_offset += BW_SCALE_CFG_OFFSET;
+30 −21
Original line number Diff line number Diff line
@@ -1294,6 +1294,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:
@@ -1301,13 +1305,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",
@@ -1674,13 +1671,17 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev)
	}

	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) {
		MHI_ERR("MHI system error detected\n");
		pm_state = mhi_tryset_pm_state(mhi_cntrl,
@@ -1688,20 +1689,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 −14
Original line number Diff line number Diff line
@@ -474,12 +474,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);

@@ -585,8 +589,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 */
@@ -830,6 +832,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);
}

@@ -855,14 +861,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:
@@ -949,6 +950,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);
@@ -976,6 +978,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:
@@ -1034,21 +1037,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);