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

Commit d75a8f83 authored by Sujeev Dias's avatar Sujeev Dias
Browse files

mhi: cntrl: qcom: force a suspend during boot



Soon as device transition to mission mode force a PCIe link
suspend and a resume so device can update PCIe phy sequence.

CRs-Fixed: 2457211
Change-Id: Ic9de5f69c425f7a1a5b8a931930882a9da80c2ad
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 536f885c
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -255,9 +255,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);
	}