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

Commit 1809440f authored by Sujeev Dias's avatar Sujeev Dias
Browse files

mhi: core: keep MHI in M0 while entering suspend



During MHI suspend, host must keep MHI wake asserted to prevent
device from entering any other low power states.

CRs-Fixed: 2361072
Change-Id: Ib68ec62294eab4727c6bb8e356b6aa59b9ca99cf
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 67e96864
Loading
Loading
Loading
Loading
+18 −9
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */


#include <linux/debugfs.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/delay.h>
@@ -922,24 +922,23 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl)
				 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
				 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
				 msecs_to_jiffies(mhi_cntrl->timeout_ms));
				 msecs_to_jiffies(mhi_cntrl->timeout_ms));


	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
	if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
		MHI_ERR(
		MHI_ERR(
			"Did not enter M0||M1 state, cur_state:%s pm_state:%s\n",
			"Did not enter M0||M1 state, cur_state:%s pm_state:%s\n",
			TO_MHI_STATE_STR(mhi_cntrl->dev_state),
			TO_MHI_STATE_STR(mhi_cntrl->dev_state),
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		return -EIO;
		ret = -EIO;
		goto error_m0_entry;
	}
	}


	write_lock_irq(&mhi_cntrl->pm_lock);
	write_lock_irq(&mhi_cntrl->pm_lock);


	if (atomic_read(&mhi_cntrl->dev_wake)) {
	/* we're asserting wake so count would be @ least 1 */
	if (atomic_read(&mhi_cntrl->dev_wake) > 1) {
		MHI_VERB("Busy, aborting M3\n");
		MHI_VERB("Busy, aborting M3\n");
		write_unlock_irq(&mhi_cntrl->pm_lock);
		write_unlock_irq(&mhi_cntrl->pm_lock);
		return -EBUSY;
		ret = -EBUSY;
		goto error_m0_entry;
	}
	}


	/* anytime after this, we will resume thru runtime pm framework */
	/* anytime after this, we will resume thru runtime pm framework */
@@ -950,11 +949,14 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl)
		MHI_ERR("Error setting to pm_state:%s from pm_state:%s\n",
		MHI_ERR("Error setting to pm_state:%s from pm_state:%s\n",
			to_mhi_pm_state_str(MHI_PM_M3_ENTER),
			to_mhi_pm_state_str(MHI_PM_M3_ENTER),
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		return -EIO;

		ret = -EIO;
		goto error_m0_entry;
	}
	}


	/* set dev to M3 and wait for completion */
	/* set dev to M3 and wait for completion */
	mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M3);
	mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M3);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	write_unlock_irq(&mhi_cntrl->pm_lock);
	write_unlock_irq(&mhi_cntrl->pm_lock);
	MHI_LOG("Wait for M3 completion\n");
	MHI_LOG("Wait for M3 completion\n");


@@ -979,6 +981,13 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl)
	}
	}


	return 0;
	return 0;

error_m0_entry:
	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	return ret;
}
}
EXPORT_SYMBOL(mhi_pm_suspend);
EXPORT_SYMBOL(mhi_pm_suspend);