aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorDeepthi Dharwar <deepthi@linux.vnet.ibm.com>2011-10-28 06:50:09 -0400
committerLen Brown <len.brown@intel.com>2011-11-06 21:13:30 -0500
commite978aa7d7d57d04eb5f88a7507c4fb98577def77 (patch)
treed6d6dfe1dba4d4749c7eafe348351aa499c3c5eb /arch/sh
parentc3b92c8787367a8bb53d57d9789b558f1295cc96 (diff)
cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state
Cpuidle governor only suggests the state to enter using the governor->select() interface, but allows the low level driver to override the recommended state. The actual entered state may be different because of software or hardware demotion. Software demotion is done by the back-end cpuidle driver and can be accounted correctly. Current cpuidle code uses last_state field to capture the actual state entered and based on that updates the statistics for the state entered. Ideally the driver enter routine should update the counters, and it should return the state actually entered rather than the time spent there. The generic cpuidle code should simply handle where the counters live in the sysfs namespace, not updating the counters. Reference: https://lkml.org/lkml/2011/3/25/52 Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Tested-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/cpu/shmobile/cpuidle.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index e4469e7233cb..7be50d4c4268 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -25,11 +25,11 @@ static unsigned long cpuidle_mode[] = {
25}; 25};
26 26
27static int cpuidle_sleep_enter(struct cpuidle_device *dev, 27static int cpuidle_sleep_enter(struct cpuidle_device *dev,
28 struct cpuidle_state *state) 28 int index)
29{ 29{
30 unsigned long allowed_mode = arch_hwblk_sleep_mode(); 30 unsigned long allowed_mode = arch_hwblk_sleep_mode();
31 ktime_t before, after; 31 ktime_t before, after;
32 int requested_state = state - &dev->states[0]; 32 int requested_state = index;
33 int allowed_state; 33 int allowed_state;
34 int k; 34 int k;
35 35
@@ -46,11 +46,13 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
46 */ 46 */
47 k = min_t(int, allowed_state, requested_state); 47 k = min_t(int, allowed_state, requested_state);
48 48
49 dev->last_state = &dev->states[k];
50 before = ktime_get(); 49 before = ktime_get();
51 sh_mobile_call_standby(cpuidle_mode[k]); 50 sh_mobile_call_standby(cpuidle_mode[k]);
52 after = ktime_get(); 51 after = ktime_get();
53 return ktime_to_ns(ktime_sub(after, before)) >> 10; 52
53 dev->last_residency = (int)ktime_to_ns(ktime_sub(after, before)) >> 10;
54
55 return k;
54} 56}
55 57
56static struct cpuidle_device cpuidle_dev; 58static struct cpuidle_device cpuidle_dev;
@@ -84,7 +86,7 @@ void sh_mobile_setup_cpuidle(void)
84 state->flags |= CPUIDLE_FLAG_TIME_VALID; 86 state->flags |= CPUIDLE_FLAG_TIME_VALID;
85 state->enter = cpuidle_sleep_enter; 87 state->enter = cpuidle_sleep_enter;
86 88
87 dev->safe_state = state; 89 dev->safe_state_index = i-1;
88 90
89 if (sh_mobile_sleep_supported & SUSP_SH_SF) { 91 if (sh_mobile_sleep_supported & SUSP_SH_SF) {
90 state = &dev->states[i++]; 92 state = &dev->states[i++];