cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state
[pandora-kernel.git] / drivers / cpuidle / cpuidle.c
index d4c5423..88bd121 100644 (file)
@@ -62,7 +62,7 @@ int cpuidle_idle_call(void)
 {
        struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
        struct cpuidle_state *target_state;
-       int next_state;
+       int next_state, entered_state;
 
        if (off)
                return -ENODEV;
@@ -102,26 +102,27 @@ int cpuidle_idle_call(void)
 
        target_state = &dev->states[next_state];
 
-       /* enter the state and update stats */
-       dev->last_state = target_state;
-
        trace_power_start(POWER_CSTATE, next_state, dev->cpu);
        trace_cpu_idle(next_state, dev->cpu);
 
-       dev->last_residency = target_state->enter(dev, target_state);
+       entered_state = target_state->enter(dev, next_state);
 
        trace_power_end(dev->cpu);
        trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
 
-       if (dev->last_state)
-               target_state = dev->last_state;
-
-       target_state->time += (unsigned long long)dev->last_residency;
-       target_state->usage++;
+       if (entered_state >= 0) {
+               /* Update cpuidle counters */
+               /* This can be moved to within driver enter routine
+                * but that results in multiple copies of same code.
+                */
+               dev->states[entered_state].time +=
+                               (unsigned long long)dev->last_residency;
+               dev->states[entered_state].usage++;
+       }
 
        /* give the governor an opportunity to reflect on the outcome */
        if (cpuidle_curr_governor->reflect)
-               cpuidle_curr_governor->reflect(dev);
+               cpuidle_curr_governor->reflect(dev, entered_state);
 
        return 0;
 }
@@ -172,11 +173,10 @@ void cpuidle_resume_and_unlock(void)
 EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
 
 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
-static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
+static int poll_idle(struct cpuidle_device *dev, int index)
 {
        ktime_t t1, t2;
        s64 diff;
-       int ret;
 
        t1 = ktime_get();
        local_irq_enable();
@@ -188,8 +188,9 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
        if (diff > INT_MAX)
                diff = INT_MAX;
 
-       ret = (int) diff;
-       return ret;
+       dev->last_residency = (int) diff;
+
+       return index;
 }
 
 static void poll_idle_init(struct cpuidle_device *dev)
@@ -248,7 +249,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
                dev->states[i].time = 0;
        }
        dev->last_residency = 0;
-       dev->last_state = NULL;
 
        smp_wmb();