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

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

Merge "mhi: cntrl: qcom: force a suspend during boot"

parents 2fd9b6ce d75a8f83
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -292,9 +292,6 @@ static void mhi_boot_monitor(void *data, async_cookie_t cookie)
		if (boot_dev)
			mhi_unprepare_from_transfer(boot_dev);

		/* enable link inactivity timer to start auto suspend */
		msm_pcie_l1ss_timeout_enable(mhi_dev->pci_dev);

		if (!mhi_dev->drv_supported || arch_info->drv_connected)
			pm_runtime_allow(&mhi_dev->pci_dev->dev);
	}
+53 −0
Original line number Diff line number Diff line
@@ -389,6 +389,47 @@ int mhi_system_suspend(struct device *dev)
	return ret;
}

static int mhi_force_suspend(struct mhi_controller *mhi_cntrl)
{
	int ret = -EIO;
	const u32 delayms = 100;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms, delayms);

	MHI_LOG("Entered\n");

	mutex_lock(&mhi_cntrl->pm_mutex);

	for (; itr; itr--) {
		/*
		 * This function get called soon as device entered mission mode
		 * so most of the channels are still in disabled state. However,
		 * sbl channels are active and clients could be trying to close
		 * channels while we trying to suspend the link. So, we need to
		 * re-try if MHI is busy
		 */
		ret = mhi_pm_suspend(mhi_cntrl);
		if (!ret || ret != -EBUSY)
			break;

		MHI_LOG("MHI busy, sleeping and retry\n");
		msleep(delayms);
	}

	if (ret)
		goto exit_force_suspend;

	mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND;
	ret = mhi_arch_link_suspend(mhi_cntrl);

exit_force_suspend:
	MHI_LOG("Force suspend ret with %d\n", ret);

	mutex_unlock(&mhi_cntrl->pm_mutex);

	return ret;
}

/* checks if link is down */
static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv)
{
@@ -558,6 +599,7 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl,
{
	struct mhi_dev *mhi_dev = priv;
	struct device *dev = &mhi_dev->pci_dev->dev;
	int ret;

	switch (reason) {
	case MHI_CB_IDLE:
@@ -569,6 +611,17 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl,
		if (mhi_dev->bw_scale)
			mhi_dev->bw_scale(mhi_cntrl, mhi_dev);
		break;
	case MHI_CB_EE_MISSION_MODE:
		/*
		 * we need to force a suspend so device can switch to
		 * mission mode pcie phy settings.
		 */
		pm_runtime_get(dev);
		ret = mhi_force_suspend(mhi_cntrl);
		if (!ret)
			mhi_runtime_resume(dev);
		pm_runtime_put(dev);
		break;
	default:
		MHI_ERR("Unhandled cb:0x%x\n", reason);
	}
+14 −12
Original line number Diff line number Diff line
@@ -436,27 +436,31 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)

	MHI_LOG("Processing Mission Mode Transition\n");

	/* force MHI to be in M0 state before continuing */
	ret = __mhi_device_get_sync(mhi_cntrl);
	if (ret)
		return ret;

	ret = -EIO;

	write_lock_irq(&mhi_cntrl->pm_lock);
	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);

	read_lock_bh(&mhi_cntrl->pm_lock);
	if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee))
		goto error_mission_mode;
		return -EIO;

	wake_up_all(&mhi_cntrl->state_event);

	mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
			     MHI_CB_EE_MISSION_MODE);

	/* force MHI to be in M0 state before continuing */
	ret = __mhi_device_get_sync(mhi_cntrl);
	if (ret)
		return ret;

	read_lock_bh(&mhi_cntrl->pm_lock);

	/* add elements to all HW event rings */
	if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
	if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
		ret = -EIO;
		goto error_mission_mode;
	}

	mhi_event = mhi_cntrl->mhi_event;
	for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
@@ -490,8 +494,6 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
	/* setup sysfs nodes for userspace votes */
	mhi_create_vote_sysfs(mhi_cntrl);

	ret = 0;

	read_lock_bh(&mhi_cntrl->pm_lock);

error_mission_mode:
+1 −0
Original line number Diff line number Diff line
@@ -2259,6 +2259,7 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev,
	case MHI_CB_SYS_ERROR:
	case MHI_CB_FATAL_ERROR:
	case MHI_CB_BW_REQ:
	case MHI_CB_EE_MISSION_MODE:
		IPA_MPM_ERR("unexpected event %d\n", mhi_cb);
		break;
	}
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ struct mhi_buf_info;
 * @MHI_CB_LPM_ENTER: MHI host entered low power mode
 * @MHI_CB_LPM_EXIT: MHI host about to exit low power mode
 * @MHI_CB_EE_RDDM: MHI device entered RDDM execution enviornment
 * @MHI_CB_EE_MISSION_MODE: MHI device entered Mission Mode ee
 * @MHI_CB_SYS_ERROR: MHI device enter error state (may recover)
 * @MHI_CB_FATAL_ERROR: MHI device entered fatal error
 * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
@@ -30,6 +31,7 @@ enum MHI_CB {
	MHI_CB_LPM_ENTER,
	MHI_CB_LPM_EXIT,
	MHI_CB_EE_RDDM,
	MHI_CB_EE_MISSION_MODE,
	MHI_CB_SYS_ERROR,
	MHI_CB_FATAL_ERROR,
	MHI_CB_BW_REQ,