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

Commit 0b6f7e48 authored by Rama Krishna Phani A's avatar Rama Krishna Phani A Committed by Siddartha Mohanadoss
Browse files

msm: mhi_dev: add reset separation support



Add reset separation support for mhi device.

Change-Id: Iac0c454931d5a4328bdb278acb7604c4095066dd
Signed-off-by: default avatarRama Krishna Phani A <rphani@codeaurora.org>
parent c65a6a0e
Loading
Loading
Loading
Loading
+70 −7
Original line number Diff line number Diff line
@@ -2669,6 +2669,64 @@ int mhi_dev_write_channel(struct mhi_req *wreq)
}
EXPORT_SYMBOL(mhi_dev_write_channel);

static int mhi_dev_recover(struct mhi_dev *mhi)
{
	int rc = 0;
	uint32_t syserr, max_cnt = 0, bhi_intvec = 0;
	bool mhi_reset;
	enum mhi_dev_state state;

	/* Check if MHI is in syserr */
	mhi_dev_mmio_masked_read(mhi, MHISTATUS,
				MHISTATUS_SYSERR_MASK,
				MHISTATUS_SYSERR_SHIFT, &syserr);

	mhi_log(MHI_MSG_VERBOSE, "mhi_syserr = 0x%X\n", syserr);
	if (syserr) {
		rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec);
		if (rc)
			return rc;

		if (bhi_intvec != 0xffffffff) {
			/* Indicate the host that the device is ready */
			rc = ep_pcie_trigger_msi(mhi->phandle, bhi_intvec);
			if (rc) {
				pr_err("%s: error sending msi\n", __func__);
				return rc;
			}
		}

		/* Poll for the host to set the reset bit */
		rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset);
		if (rc) {
			pr_err("%s: get mhi state failed\n", __func__);
			return rc;
		}
		while (mhi_reset != true && max_cnt < MHI_SUSPEND_TIMEOUT) {
			/* Wait for Host to set the reset */
			msleep(MHI_SUSPEND_MIN);
			rc = mhi_dev_mmio_get_mhi_state(mhi, &state,
								&mhi_reset);
			if (rc) {
				pr_err("%s: get mhi state failed\n", __func__);
				return rc;
			}
			max_cnt++;
		}

		if (!mhi_reset) {
			mhi_log(MHI_MSG_VERBOSE, "Host failed to set reset\n");
			return -EINVAL;
		}
	}
	/*
	 * Now mask the interrupts so that the state machine moves
	 * only after IPA is ready
	 */
	mhi_dev_mmio_mask_interrupts(mhi);
	return 0;
}

static void mhi_dev_enable(struct work_struct *work)
{
	int rc = 0;
@@ -3180,6 +3238,18 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx)
	mutex_init(&mhi_ctx->mhi_event_lock);
	mutex_init(&mhi_ctx->mhi_write_test);

	mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id);
	if (!mhi_ctx->phandle) {
		pr_err("PCIe driver get handle failed.\n");
		return -EINVAL;
	}

	rc = mhi_dev_recover(mhi_ctx);
	if (rc) {
		pr_err("%s: get mhi state failed\n", __func__);
		return rc;
	}

	rc = mhi_init(mhi_ctx);
	if (rc)
		return rc;
@@ -3209,13 +3279,6 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx)
		pr_err("Failed to update the MHI version\n");
		return rc;
	}

	mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id);
	if (!mhi_ctx->phandle) {
		pr_err("PCIe driver get handle failed.\n");
		return -EINVAL;
	}

	mhi_ctx->event_reg.events = EP_PCIE_EVENT_PM_D3_HOT |
		EP_PCIE_EVENT_PM_D3_COLD |
		EP_PCIE_EVENT_PM_D0 |
+6 −0
Original line number Diff line number Diff line
@@ -882,6 +882,12 @@ int mhi_dev_mmio_mask_erdb_interrupts(struct mhi_dev *dev);
 */
int mhi_dev_mmio_read_erdb_status_interrupts(struct mhi_dev *dev);

/**
 * mhi_dev_mmio_mask_interrupts() - Mask all MHI interrupts.
 * @dev:	MHI device structure.
 */
void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev);

/**
 * mhi_dev_mmio_clear_interrupts() - Clear all doorbell interrupts.
 * @dev:	MHI device structure.
+2 −1
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ int mhi_dev_mmio_disable_cmdb_interrupt(struct mhi_dev *dev)
}
EXPORT_SYMBOL(mhi_dev_mmio_disable_cmdb_interrupt);

static void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev)
void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev)
{
	mhi_dev_mmio_disable_ctrl_interrupt(dev);

@@ -399,6 +399,7 @@ static void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev)

	mhi_dev_mmio_mask_erdb_interrupts(dev);
}
EXPORT_SYMBOL(mhi_dev_mmio_mask_interrupts);

int mhi_dev_mmio_clear_interrupts(struct mhi_dev *dev)
{