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

Commit 7978e38f authored by Sujeev Dias's avatar Sujeev Dias Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: add support to trigger modem into RDDM mode



RDDM mode (ramdump mode) allows host to collect external modem
ramdump for debugging purpose.

CRs-Fixed: 2220997
Change-Id: I88c38198f150716a3e997cdd424b19b7576aca20
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent fd523541
Loading
Loading
Loading
Loading
+71 −15
Original line number Diff line number Diff line
@@ -1065,23 +1065,10 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
	return 0;
}

void mhi_device_get(struct mhi_device *mhi_dev)
static int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl)
{
	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;

	atomic_inc(&mhi_dev->dev_wake);
	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_get(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);
}
EXPORT_SYMBOL(mhi_device_get);

int mhi_device_get_sync(struct mhi_device *mhi_dev)
{
	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
	int ret;

	atomic_inc(&mhi_dev->dev_wake);
	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_get(mhi_cntrl, false);
	if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) {
@@ -1099,7 +1086,6 @@ int mhi_device_get_sync(struct mhi_device *mhi_dev)
		MHI_ERR("Did not enter M0 state, cur_state:%s pm_state:%s\n",
			TO_MHI_STATE_STR(mhi_cntrl->dev_state),
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		atomic_dec(&mhi_dev->dev_wake);
		read_lock_bh(&mhi_cntrl->pm_lock);
		mhi_cntrl->wake_put(mhi_cntrl, false);
		read_unlock_bh(&mhi_cntrl->pm_lock);
@@ -1108,6 +1094,29 @@ int mhi_device_get_sync(struct mhi_device *mhi_dev)

	return 0;
}

void mhi_device_get(struct mhi_device *mhi_dev)
{
	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;

	atomic_inc(&mhi_dev->dev_wake);
	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_get(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);
}
EXPORT_SYMBOL(mhi_device_get);

int mhi_device_get_sync(struct mhi_device *mhi_dev)
{
	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
	int ret;

	ret = __mhi_device_get_sync(mhi_cntrl);
	if (!ret)
		atomic_inc(&mhi_dev->dev_wake);

	return ret;
}
EXPORT_SYMBOL(mhi_device_get_sync);

void mhi_device_put(struct mhi_device *mhi_dev)
@@ -1120,3 +1129,50 @@ void mhi_device_put(struct mhi_device *mhi_dev)
	read_unlock_bh(&mhi_cntrl->pm_lock);
}
EXPORT_SYMBOL(mhi_device_put);

int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl)
{
	int ret;

	MHI_LOG("Enter with pm_state:%s ee:%s\n",
		to_mhi_pm_state_str(mhi_cntrl->pm_state),
		TO_MHI_EXEC_STR(mhi_cntrl->ee));

	/* before rddm mode, we need to enter M0 state */
	ret = __mhi_device_get_sync(mhi_cntrl);
	if (ret)
		return ret;

	mutex_lock(&mhi_cntrl->pm_mutex);
	write_lock_irq(&mhi_cntrl->pm_lock);
	if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
		goto no_reg_access;

	MHI_LOG("Triggering SYS_ERR to force rddm state\n");

	mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	write_unlock_irq(&mhi_cntrl->pm_lock);
	mutex_unlock(&mhi_cntrl->pm_mutex);

	/* wait for rddm event */
	MHI_LOG("Waiting for device to enter RDDM state\n");
	ret = wait_event_timeout(mhi_cntrl->state_event,
				 mhi_cntrl->ee == MHI_EE_RDDM,
				 msecs_to_jiffies(mhi_cntrl->timeout_ms));
	ret = !ret ? 0 : -EIO;

	MHI_LOG("Exiting with pm_state:%s ee:%s ret:%d\n",
		to_mhi_pm_state_str(mhi_cntrl->pm_state),
		TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);

	return ret;

no_reg_access:
	mhi_cntrl->wake_put(mhi_cntrl, false);
	write_unlock_irq(&mhi_cntrl->pm_lock);
	mutex_unlock(&mhi_cntrl->pm_mutex);

	return -EIO;
}
EXPORT_SYMBOL(mhi_force_rddm_mode);
+13 −0
Original line number Diff line number Diff line
@@ -519,6 +519,14 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl);
 */
int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic);

/**
 * mhi_force_rddm_mode - Force external device into rddm mode
 * to collect device ramdump. This is useful if host driver assert
 * and we need to see device state as well.
 * @mhi_cntrl: MHI controller
 */
int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl);

#else

static inline int mhi_driver_register(struct mhi_driver *mhi_drv)
@@ -643,6 +651,11 @@ static inline int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl,
	return -EINVAL;
}

static inlint int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl)
{
	return -EINVAL;
}

#endif

#ifndef CONFIG_ARCH_QCOM