From 8b9699ddeeb3e1d0cdeafecd67d73eddcdd99d13 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Mon, 28 May 2018 13:57:53 +0530 Subject: [PATCH] drivers: cpuidle: lpm-levels: Move local_irq_enable Cancelling histtimer after enabling local irqs can cause low sleep length to get calculated during next low power mode entry. Enable local irqs after cancelling histtimer. Use hrtimer_get_remaining before cancelling timer. Change-Id: I735770f779c5760acc6b62cb65811b21244d0e99 Signed-off-by: Maulik Shah --- drivers/cpuidle/lpm-levels.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 883a30cff944..39a8f78fe9d3 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -195,6 +195,11 @@ static void histtimer_cancel(void) { unsigned int cpu = raw_smp_processor_id(); struct hrtimer *cpu_histtimer = &per_cpu(histtimer, cpu); + ktime_t time_rem; + + time_rem = hrtimer_get_remaining(cpu_histtimer); + if (ktime_to_us(time_rem) <= 0) + return; hrtimer_try_to_cancel(cpu_histtimer); } @@ -240,11 +245,21 @@ static void clusttimer_cancel(void) { int cpu = raw_smp_processor_id(); struct lpm_cluster *cluster = per_cpu(cpu_lpm, cpu)->parent; + ktime_t time_rem; - hrtimer_try_to_cancel(&cluster->histtimer); + time_rem = hrtimer_get_remaining(&cluster->histtimer); + if (ktime_to_us(time_rem) > 0) + hrtimer_try_to_cancel(&cluster->histtimer); + + if (cluster->parent) { + time_rem = hrtimer_get_remaining( + &cluster->parent->histtimer); + + if (ktime_to_us(time_rem) <= 0) + return; - if (cluster->parent) hrtimer_try_to_cancel(&cluster->parent->histtimer); + } } static enum hrtimer_restart clusttimer_fn(struct hrtimer *h) @@ -1197,11 +1212,11 @@ exit: dev->last_residency = ktime_us_delta(ktime_get(), start); update_history(dev, idx); trace_cpu_idle_exit(idx, success); - local_irq_enable(); if (lpm_prediction && cpu->lpm_prediction) { histtimer_cancel(); clusttimer_cancel(); } + local_irq_enable(); return idx; }