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

Commit f188b283 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

msm: pm-8x60: Fix suspend time tracking



Calls to sched_clock() after syscore devices have been suspend
will return the same value until the syscored devices are
resumed. Furthermore, the value won't jump forward to account for
the time left in suspend so we can't use it to calculate how much
time we spent in suspend.

We could expose the hardware directly to the pm code but it's
better to use generic interfaces. Move to using the timekeeping
APIs to determine how long we were in suspend. Unfortunately, we
can't use the timekeeping APIs this early in the resume path, so
we must read the current time of day before we suspend the
timekeeping core and after we resume the timekeeping core. Move
the calls to the suspend_late() and wake() callbacks so we can
properly read the amount of suspend time.

CRs-fixed: 536881
Change-Id: I3b47511afb75926e51e82fc83929f405404fbf07
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 3d9bc03f
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -670,8 +670,11 @@ static int64_t msm_pm_timer_enter_suspend(int64_t *period)
{
	int64_t time = 0;

	if (msm_pm_use_sync_timer)
		return sched_clock();
	if (msm_pm_use_sync_timer) {
		struct timespec ts;
		getnstimeofday(&ts);
		return timespec_to_ns(&ts);
	}

	time = msm_timer_get_sclk_time(period);
	if (!time)
@@ -682,8 +685,12 @@ static int64_t msm_pm_timer_enter_suspend(int64_t *period)

static int64_t msm_pm_timer_exit_suspend(int64_t time, int64_t period)
{
	if (msm_pm_use_sync_timer)
		return sched_clock() - time;
	if (msm_pm_use_sync_timer) {
		struct timespec ts;
		getnstimeofday(&ts);

		return timespec_to_ns(&ts) - time;
	}

	if (time != 0) {
		int64_t end_time = msm_timer_get_sclk_time(NULL);
@@ -1068,12 +1075,14 @@ void msm_pm_enable_retention(bool enable)
}
EXPORT_SYMBOL(msm_pm_enable_retention);

static int64_t suspend_time, suspend_period;
static int collapsed;
static int suspend_power_collapsed;

static int msm_pm_enter(suspend_state_t state)
{
	bool allow[MSM_PM_SLEEP_MODE_NR];
	int i;
	int64_t period = 0;
	int64_t time = msm_pm_timer_enter_suspend(&period);
	struct msm_pm_time_params time_param;

	time_param.latency_us = -1;
@@ -1101,7 +1110,6 @@ static int msm_pm_enter(suspend_state_t state)
		int ret = -ENODEV;
		uint32_t power;
		uint32_t msm_pm_max_sleep_time = 0;
		int collapsed = 0;

		if (MSM_PM_DEBUG_SUSPEND & msm_pm_debug_mask)
			pr_info("%s: power collapse\n", __func__);
@@ -1135,11 +1143,7 @@ static int msm_pm_enter(suspend_state_t state)
			pr_err("%s: cannot find the lowest power limit\n",
				__func__);
		}
		time = msm_pm_timer_exit_suspend(time, period);
		if (collapsed)
			msm_pm_add_stat(MSM_PM_STAT_SUSPEND, time);
		else
			msm_pm_add_stat(MSM_PM_STAT_FAILED_SUSPEND, time);
		suspend_power_collapsed = true;
	} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
		if (MSM_PM_DEBUG_SUSPEND & msm_pm_debug_mask)
			pr_info("%s: standalone power collapse\n", __func__);
@@ -1169,6 +1173,7 @@ void msm_pm_set_sleep_ops(struct msm_pm_sleep_ops *ops)

static int msm_suspend_prepare(void)
{
	suspend_time = msm_pm_timer_enter_suspend(&suspend_period);
	msm_mpm_suspend_prepare();
	return 0;
}
@@ -1176,6 +1181,16 @@ static int msm_suspend_prepare(void)
static void msm_suspend_wake(void)
{
	msm_mpm_suspend_wake();
	if (suspend_power_collapsed) {
		suspend_time = msm_pm_timer_exit_suspend(suspend_time,
				suspend_period);
		if (collapsed)
			msm_pm_add_stat(MSM_PM_STAT_SUSPEND, suspend_time);
		else
			msm_pm_add_stat(MSM_PM_STAT_FAILED_SUSPEND,
					suspend_time);
		suspend_power_collapsed = false;
	}
}

static const struct platform_suspend_ops msm_pm_ops = {