diff options
-rw-r--r-- | arch/arm/mach-at91/cpuidle.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-davinci/cpuidle.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/cpuidle.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/cpuidle.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle34xx.c | 67 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/cpuidle.c | 12 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 75 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 32 | ||||
-rw-r--r-- | drivers/cpuidle/governors/ladder.c | 13 | ||||
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 7 | ||||
-rw-r--r-- | drivers/idle/intel_idle.c | 12 | ||||
-rw-r--r-- | include/linux/cpuidle.h | 7 |
12 files changed, 164 insertions, 99 deletions
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c index 1cfeac1483d6..4696a0d61e2e 100644 --- a/arch/arm/mach-at91/cpuidle.c +++ b/arch/arm/mach-at91/cpuidle.c | |||
@@ -33,7 +33,7 @@ static struct cpuidle_driver at91_idle_driver = { | |||
33 | 33 | ||
34 | /* Actual code that puts the SoC in different idle states */ | 34 | /* Actual code that puts the SoC in different idle states */ |
35 | static int at91_enter_idle(struct cpuidle_device *dev, | 35 | static int at91_enter_idle(struct cpuidle_device *dev, |
36 | struct cpuidle_state *state) | 36 | int index) |
37 | { | 37 | { |
38 | struct timeval before, after; | 38 | struct timeval before, after; |
39 | int idle_time; | 39 | int idle_time; |
@@ -41,10 +41,10 @@ static int at91_enter_idle(struct cpuidle_device *dev, | |||
41 | 41 | ||
42 | local_irq_disable(); | 42 | local_irq_disable(); |
43 | do_gettimeofday(&before); | 43 | do_gettimeofday(&before); |
44 | if (state == &dev->states[0]) | 44 | if (index == 0) |
45 | /* Wait for interrupt state */ | 45 | /* Wait for interrupt state */ |
46 | cpu_do_idle(); | 46 | cpu_do_idle(); |
47 | else if (state == &dev->states[1]) { | 47 | else if (index == 1) { |
48 | asm("b 1f; .align 5; 1:"); | 48 | asm("b 1f; .align 5; 1:"); |
49 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | 49 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ |
50 | saved_lpr = sdram_selfrefresh_enable(); | 50 | saved_lpr = sdram_selfrefresh_enable(); |
@@ -55,7 +55,9 @@ static int at91_enter_idle(struct cpuidle_device *dev, | |||
55 | local_irq_enable(); | 55 | local_irq_enable(); |
56 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 56 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
57 | (after.tv_usec - before.tv_usec); | 57 | (after.tv_usec - before.tv_usec); |
58 | return idle_time; | 58 | |
59 | dev->last_residency = idle_time; | ||
60 | return index; | ||
59 | } | 61 | } |
60 | 62 | ||
61 | /* Initialize CPU idle by registering the idle states */ | 63 | /* Initialize CPU idle by registering the idle states */ |
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index bd59f31b8a95..ca8582a95ad9 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c | |||
@@ -78,9 +78,9 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { | |||
78 | 78 | ||
79 | /* Actual code that puts the SoC in different idle states */ | 79 | /* Actual code that puts the SoC in different idle states */ |
80 | static int davinci_enter_idle(struct cpuidle_device *dev, | 80 | static int davinci_enter_idle(struct cpuidle_device *dev, |
81 | struct cpuidle_state *state) | 81 | int index) |
82 | { | 82 | { |
83 | struct davinci_ops *ops = cpuidle_get_statedata(state); | 83 | struct davinci_ops *ops = cpuidle_get_statedata(&dev->states[index]); |
84 | struct timeval before, after; | 84 | struct timeval before, after; |
85 | int idle_time; | 85 | int idle_time; |
86 | 86 | ||
@@ -98,7 +98,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev, | |||
98 | local_irq_enable(); | 98 | local_irq_enable(); |
99 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 99 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
100 | (after.tv_usec - before.tv_usec); | 100 | (after.tv_usec - before.tv_usec); |
101 | return idle_time; | 101 | |
102 | dev->last_residency = idle_time; | ||
103 | |||
104 | return index; | ||
102 | } | 105 | } |
103 | 106 | ||
104 | static int __init davinci_cpuidle_probe(struct platform_device *pdev) | 107 | static int __init davinci_cpuidle_probe(struct platform_device *pdev) |
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c index bf7e96f2793a..ea026e72b977 100644 --- a/arch/arm/mach-exynos4/cpuidle.c +++ b/arch/arm/mach-exynos4/cpuidle.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <asm/proc-fns.h> | 16 | #include <asm/proc-fns.h> |
17 | 17 | ||
18 | static int exynos4_enter_idle(struct cpuidle_device *dev, | 18 | static int exynos4_enter_idle(struct cpuidle_device *dev, |
19 | struct cpuidle_state *state); | 19 | int index); |
20 | 20 | ||
21 | static struct cpuidle_state exynos4_cpuidle_set[] = { | 21 | static struct cpuidle_state exynos4_cpuidle_set[] = { |
22 | [0] = { | 22 | [0] = { |
@@ -37,7 +37,7 @@ static struct cpuidle_driver exynos4_idle_driver = { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | static int exynos4_enter_idle(struct cpuidle_device *dev, | 39 | static int exynos4_enter_idle(struct cpuidle_device *dev, |
40 | struct cpuidle_state *state) | 40 | int index) |
41 | { | 41 | { |
42 | struct timeval before, after; | 42 | struct timeval before, after; |
43 | int idle_time; | 43 | int idle_time; |
@@ -52,7 +52,8 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, | |||
52 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 52 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
53 | (after.tv_usec - before.tv_usec); | 53 | (after.tv_usec - before.tv_usec); |
54 | 54 | ||
55 | return idle_time; | 55 | dev->last_residency = idle_time; |
56 | return index; | ||
56 | } | 57 | } |
57 | 58 | ||
58 | static int __init exynos4_init_cpuidle(void) | 59 | static int __init exynos4_init_cpuidle(void) |
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c index f68d33f1f396..358dd80b3a07 100644 --- a/arch/arm/mach-kirkwood/cpuidle.c +++ b/arch/arm/mach-kirkwood/cpuidle.c | |||
@@ -32,17 +32,17 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); | |||
32 | 32 | ||
33 | /* Actual code that puts the SoC in different idle states */ | 33 | /* Actual code that puts the SoC in different idle states */ |
34 | static int kirkwood_enter_idle(struct cpuidle_device *dev, | 34 | static int kirkwood_enter_idle(struct cpuidle_device *dev, |
35 | struct cpuidle_state *state) | 35 | int index) |
36 | { | 36 | { |
37 | struct timeval before, after; | 37 | struct timeval before, after; |
38 | int idle_time; | 38 | int idle_time; |
39 | 39 | ||
40 | local_irq_disable(); | 40 | local_irq_disable(); |
41 | do_gettimeofday(&before); | 41 | do_gettimeofday(&before); |
42 | if (state == &dev->states[0]) | 42 | if (index == 0) |
43 | /* Wait for interrupt state */ | 43 | /* Wait for interrupt state */ |
44 | cpu_do_idle(); | 44 | cpu_do_idle(); |
45 | else if (state == &dev->states[1]) { | 45 | else if (index == 1) { |
46 | /* | 46 | /* |
47 | * Following write will put DDR in self refresh. | 47 | * Following write will put DDR in self refresh. |
48 | * Note that we have 256 cycles before DDR puts it | 48 | * Note that we have 256 cycles before DDR puts it |
@@ -57,7 +57,11 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev, | |||
57 | local_irq_enable(); | 57 | local_irq_enable(); |
58 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 58 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
59 | (after.tv_usec - before.tv_usec); | 59 | (after.tv_usec - before.tv_usec); |
60 | return idle_time; | 60 | |
61 | /* Update last residency */ | ||
62 | dev->last_residency = idle_time; | ||
63 | |||
64 | return index; | ||
61 | } | 65 | } |
62 | 66 | ||
63 | /* Initialize CPU idle by registering the idle states */ | 67 | /* Initialize CPU idle by registering the idle states */ |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 4bf6e6e8b100..58425c75f1b8 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -88,17 +88,19 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm, | |||
88 | /** | 88 | /** |
89 | * omap3_enter_idle - Programs OMAP3 to enter the specified state | 89 | * omap3_enter_idle - Programs OMAP3 to enter the specified state |
90 | * @dev: cpuidle device | 90 | * @dev: cpuidle device |
91 | * @state: The target state to be programmed | 91 | * @index: the index of state to be entered |
92 | * | 92 | * |
93 | * Called from the CPUidle framework to program the device to the | 93 | * Called from the CPUidle framework to program the device to the |
94 | * specified target state selected by the governor. | 94 | * specified target state selected by the governor. |
95 | */ | 95 | */ |
96 | static int omap3_enter_idle(struct cpuidle_device *dev, | 96 | static int omap3_enter_idle(struct cpuidle_device *dev, |
97 | struct cpuidle_state *state) | 97 | int index) |
98 | { | 98 | { |
99 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(state); | 99 | struct omap3_idle_statedata *cx = |
100 | cpuidle_get_statedata(&dev->states[index]); | ||
100 | struct timespec ts_preidle, ts_postidle, ts_idle; | 101 | struct timespec ts_preidle, ts_postidle, ts_idle; |
101 | u32 mpu_state = cx->mpu_state, core_state = cx->core_state; | 102 | u32 mpu_state = cx->mpu_state, core_state = cx->core_state; |
103 | int idle_time; | ||
102 | 104 | ||
103 | /* Used to keep track of the total time in idle */ | 105 | /* Used to keep track of the total time in idle */ |
104 | getnstimeofday(&ts_preidle); | 106 | getnstimeofday(&ts_preidle); |
@@ -113,7 +115,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, | |||
113 | goto return_sleep_time; | 115 | goto return_sleep_time; |
114 | 116 | ||
115 | /* Deny idle for C1 */ | 117 | /* Deny idle for C1 */ |
116 | if (state == &dev->states[0]) { | 118 | if (index == 0) { |
117 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); | 119 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); |
118 | pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); | 120 | pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); |
119 | } | 121 | } |
@@ -122,7 +124,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, | |||
122 | omap_sram_idle(); | 124 | omap_sram_idle(); |
123 | 125 | ||
124 | /* Re-allow idle for C1 */ | 126 | /* Re-allow idle for C1 */ |
125 | if (state == &dev->states[0]) { | 127 | if (index == 0) { |
126 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); | 128 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); |
127 | pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); | 129 | pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); |
128 | } | 130 | } |
@@ -134,28 +136,35 @@ return_sleep_time: | |||
134 | local_irq_enable(); | 136 | local_irq_enable(); |
135 | local_fiq_enable(); | 137 | local_fiq_enable(); |
136 | 138 | ||
137 | return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC; | 139 | idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ |
140 | USEC_PER_SEC; | ||
141 | |||
142 | /* Update cpuidle counters */ | ||
143 | dev->last_residency = idle_time; | ||
144 | |||
145 | return index; | ||
138 | } | 146 | } |
139 | 147 | ||
140 | /** | 148 | /** |
141 | * next_valid_state - Find next valid C-state | 149 | * next_valid_state - Find next valid C-state |
142 | * @dev: cpuidle device | 150 | * @dev: cpuidle device |
143 | * @state: Currently selected C-state | 151 | * @index: Index of currently selected c-state |
144 | * | 152 | * |
145 | * If the current state is valid, it is returned back to the caller. | 153 | * If the state corresponding to index is valid, index is returned back |
146 | * Else, this function searches for a lower c-state which is still | 154 | * to the caller. Else, this function searches for a lower c-state which is |
147 | * valid. | 155 | * still valid (as defined in omap3_power_states[]) and returns its index. |
148 | * | 156 | * |
149 | * A state is valid if the 'valid' field is enabled and | 157 | * A state is valid if the 'valid' field is enabled and |
150 | * if it satisfies the enable_off_mode condition. | 158 | * if it satisfies the enable_off_mode condition. |
151 | */ | 159 | */ |
152 | static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, | 160 | static int next_valid_state(struct cpuidle_device *dev, |
153 | struct cpuidle_state *curr) | 161 | int index) |
154 | { | 162 | { |
155 | struct cpuidle_state *next = NULL; | 163 | struct cpuidle_state *curr = &dev->states[index]; |
156 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); | 164 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); |
157 | u32 mpu_deepest_state = PWRDM_POWER_RET; | 165 | u32 mpu_deepest_state = PWRDM_POWER_RET; |
158 | u32 core_deepest_state = PWRDM_POWER_RET; | 166 | u32 core_deepest_state = PWRDM_POWER_RET; |
167 | int next_index = -1; | ||
159 | 168 | ||
160 | if (enable_off_mode) { | 169 | if (enable_off_mode) { |
161 | mpu_deepest_state = PWRDM_POWER_OFF; | 170 | mpu_deepest_state = PWRDM_POWER_OFF; |
@@ -172,20 +181,20 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, | |||
172 | if ((cx->valid) && | 181 | if ((cx->valid) && |
173 | (cx->mpu_state >= mpu_deepest_state) && | 182 | (cx->mpu_state >= mpu_deepest_state) && |
174 | (cx->core_state >= core_deepest_state)) { | 183 | (cx->core_state >= core_deepest_state)) { |
175 | return curr; | 184 | return index; |
176 | } else { | 185 | } else { |
177 | int idx = OMAP3_NUM_STATES - 1; | 186 | int idx = OMAP3_NUM_STATES - 1; |
178 | 187 | ||
179 | /* Reach the current state starting at highest C-state */ | 188 | /* Reach the current state starting at highest C-state */ |
180 | for (; idx >= 0; idx--) { | 189 | for (; idx >= 0; idx--) { |
181 | if (&dev->states[idx] == curr) { | 190 | if (&dev->states[idx] == curr) { |
182 | next = &dev->states[idx]; | 191 | next_index = idx; |
183 | break; | 192 | break; |
184 | } | 193 | } |
185 | } | 194 | } |
186 | 195 | ||
187 | /* Should never hit this condition */ | 196 | /* Should never hit this condition */ |
188 | WARN_ON(next == NULL); | 197 | WARN_ON(next_index == -1); |
189 | 198 | ||
190 | /* | 199 | /* |
191 | * Drop to next valid state. | 200 | * Drop to next valid state. |
@@ -197,37 +206,39 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, | |||
197 | if ((cx->valid) && | 206 | if ((cx->valid) && |
198 | (cx->mpu_state >= mpu_deepest_state) && | 207 | (cx->mpu_state >= mpu_deepest_state) && |
199 | (cx->core_state >= core_deepest_state)) { | 208 | (cx->core_state >= core_deepest_state)) { |
200 | next = &dev->states[idx]; | 209 | next_index = idx; |
201 | break; | 210 | break; |
202 | } | 211 | } |
203 | } | 212 | } |
204 | /* | 213 | /* |
205 | * C1 is always valid. | 214 | * C1 is always valid. |
206 | * So, no need to check for 'next==NULL' outside this loop. | 215 | * So, no need to check for 'next_index == -1' outside |
216 | * this loop. | ||
207 | */ | 217 | */ |
208 | } | 218 | } |
209 | 219 | ||
210 | return next; | 220 | return next_index; |
211 | } | 221 | } |
212 | 222 | ||
213 | /** | 223 | /** |
214 | * omap3_enter_idle_bm - Checks for any bus activity | 224 | * omap3_enter_idle_bm - Checks for any bus activity |
215 | * @dev: cpuidle device | 225 | * @dev: cpuidle device |
216 | * @state: The target state to be programmed | 226 | * @index: array index of target state to be programmed |
217 | * | 227 | * |
218 | * This function checks for any pending activity and then programs | 228 | * This function checks for any pending activity and then programs |
219 | * the device to the specified or a safer state. | 229 | * the device to the specified or a safer state. |
220 | */ | 230 | */ |
221 | static int omap3_enter_idle_bm(struct cpuidle_device *dev, | 231 | static int omap3_enter_idle_bm(struct cpuidle_device *dev, |
222 | struct cpuidle_state *state) | 232 | int index) |
223 | { | 233 | { |
224 | struct cpuidle_state *new_state; | 234 | struct cpuidle_state *state = &dev->states[index]; |
235 | int new_state_idx; | ||
225 | u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; | 236 | u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; |
226 | struct omap3_idle_statedata *cx; | 237 | struct omap3_idle_statedata *cx; |
227 | int ret; | 238 | int ret; |
228 | 239 | ||
229 | if (!omap3_can_sleep()) { | 240 | if (!omap3_can_sleep()) { |
230 | new_state = dev->safe_state; | 241 | new_state_idx = dev->safe_state_index; |
231 | goto select_state; | 242 | goto select_state; |
232 | } | 243 | } |
233 | 244 | ||
@@ -237,7 +248,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
237 | */ | 248 | */ |
238 | cam_state = pwrdm_read_pwrst(cam_pd); | 249 | cam_state = pwrdm_read_pwrst(cam_pd); |
239 | if (cam_state == PWRDM_POWER_ON) { | 250 | if (cam_state == PWRDM_POWER_ON) { |
240 | new_state = dev->safe_state; | 251 | new_state_idx = dev->safe_state_index; |
241 | goto select_state; | 252 | goto select_state; |
242 | } | 253 | } |
243 | 254 | ||
@@ -264,11 +275,10 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
264 | if (per_next_state != per_saved_state) | 275 | if (per_next_state != per_saved_state) |
265 | pwrdm_set_next_pwrst(per_pd, per_next_state); | 276 | pwrdm_set_next_pwrst(per_pd, per_next_state); |
266 | 277 | ||
267 | new_state = next_valid_state(dev, state); | 278 | new_state_idx = next_valid_state(dev, index); |
268 | 279 | ||
269 | select_state: | 280 | select_state: |
270 | dev->last_state = new_state; | 281 | ret = omap3_enter_idle(dev, new_state_idx); |
271 | ret = omap3_enter_idle(dev, new_state); | ||
272 | 282 | ||
273 | /* Restore original PER state if it was modified */ | 283 | /* Restore original PER state if it was modified */ |
274 | if (per_next_state != per_saved_state) | 284 | if (per_next_state != per_saved_state) |
@@ -339,11 +349,12 @@ int __init omap3_idle_init(void) | |||
339 | 349 | ||
340 | cpuidle_register_driver(&omap3_idle_driver); | 350 | cpuidle_register_driver(&omap3_idle_driver); |
341 | dev = &per_cpu(omap3_idle_dev, smp_processor_id()); | 351 | dev = &per_cpu(omap3_idle_dev, smp_processor_id()); |
352 | dev->safe_state_index = -1; | ||
342 | 353 | ||
343 | /* C1 . MPU WFI + Core active */ | 354 | /* C1 . MPU WFI + Core active */ |
344 | cx = _fill_cstate(dev, 0, "MPU ON + CORE ON"); | 355 | cx = _fill_cstate(dev, 0, "MPU ON + CORE ON"); |
345 | (&dev->states[0])->enter = omap3_enter_idle; | 356 | (&dev->states[0])->enter = omap3_enter_idle; |
346 | dev->safe_state = &dev->states[0]; | 357 | dev->safe_state_index = 0; |
347 | cx->valid = 1; /* C1 is always valid */ | 358 | cx->valid = 1; /* C1 is always valid */ |
348 | cx->mpu_state = PWRDM_POWER_ON; | 359 | cx->mpu_state = PWRDM_POWER_ON; |
349 | cx->core_state = PWRDM_POWER_ON; | 360 | cx->core_state = PWRDM_POWER_ON; |
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 | ||
27 | static int cpuidle_sleep_enter(struct cpuidle_device *dev, | 27 | static 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 | ||
56 | static struct cpuidle_device cpuidle_dev; | 58 | static 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++]; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 431ab11c8c1b..9cd08cecb347 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -741,22 +741,24 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | |||
741 | /** | 741 | /** |
742 | * acpi_idle_enter_c1 - enters an ACPI C1 state-type | 742 | * acpi_idle_enter_c1 - enters an ACPI C1 state-type |
743 | * @dev: the target CPU | 743 | * @dev: the target CPU |
744 | * @state: the state data | 744 | * @index: index of target state |
745 | * | 745 | * |
746 | * This is equivalent to the HALT instruction. | 746 | * This is equivalent to the HALT instruction. |
747 | */ | 747 | */ |
748 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, | 748 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, |
749 | struct cpuidle_state *state) | 749 | int index) |
750 | { | 750 | { |
751 | ktime_t kt1, kt2; | 751 | ktime_t kt1, kt2; |
752 | s64 idle_time; | 752 | s64 idle_time; |
753 | struct acpi_processor *pr; | 753 | struct acpi_processor *pr; |
754 | struct cpuidle_state *state = &dev->states[index]; | ||
754 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 755 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
755 | 756 | ||
756 | pr = __this_cpu_read(processors); | 757 | pr = __this_cpu_read(processors); |
758 | dev->last_residency = 0; | ||
757 | 759 | ||
758 | if (unlikely(!pr)) | 760 | if (unlikely(!pr)) |
759 | return 0; | 761 | return -EINVAL; |
760 | 762 | ||
761 | local_irq_disable(); | 763 | local_irq_disable(); |
762 | 764 | ||
@@ -764,7 +766,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
764 | if (acpi_idle_suspend) { | 766 | if (acpi_idle_suspend) { |
765 | local_irq_enable(); | 767 | local_irq_enable(); |
766 | cpu_relax(); | 768 | cpu_relax(); |
767 | return 0; | 769 | return -EINVAL; |
768 | } | 770 | } |
769 | 771 | ||
770 | lapic_timer_state_broadcast(pr, cx, 1); | 772 | lapic_timer_state_broadcast(pr, cx, 1); |
@@ -773,37 +775,46 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
773 | kt2 = ktime_get_real(); | 775 | kt2 = ktime_get_real(); |
774 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | 776 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); |
775 | 777 | ||
778 | /* Update device last_residency*/ | ||
779 | dev->last_residency = (int)idle_time; | ||
780 | |||
776 | local_irq_enable(); | 781 | local_irq_enable(); |
777 | cx->usage++; | 782 | cx->usage++; |
778 | lapic_timer_state_broadcast(pr, cx, 0); | 783 | lapic_timer_state_broadcast(pr, cx, 0); |
779 | 784 | ||
780 | return idle_time; | 785 | return index; |
781 | } | 786 | } |
782 | 787 | ||
783 | /** | 788 | /** |
784 | * acpi_idle_enter_simple - enters an ACPI state without BM handling | 789 | * acpi_idle_enter_simple - enters an ACPI state without BM handling |
785 | * @dev: the target CPU | 790 | * @dev: the target CPU |
786 | * @state: the state data | 791 | * @index: the index of suggested state |
787 | */ | 792 | */ |
788 | static int acpi_idle_enter_simple(struct cpuidle_device *dev, | 793 | static int acpi_idle_enter_simple(struct cpuidle_device *dev, |
789 | struct cpuidle_state *state) | 794 | int index) |
790 | { | 795 | { |
791 | struct acpi_processor *pr; | 796 | struct acpi_processor *pr; |
797 | struct cpuidle_state *state = &dev->states[index]; | ||
792 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 798 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
793 | ktime_t kt1, kt2; | 799 | ktime_t kt1, kt2; |
794 | s64 idle_time_ns; | 800 | s64 idle_time_ns; |
795 | s64 idle_time; | 801 | s64 idle_time; |
796 | 802 | ||
797 | pr = __this_cpu_read(processors); | 803 | pr = __this_cpu_read(processors); |
804 | dev->last_residency = 0; | ||
798 | 805 | ||
799 | if (unlikely(!pr)) | 806 | if (unlikely(!pr)) |
800 | return 0; | 807 | return -EINVAL; |
801 | |||
802 | if (acpi_idle_suspend) | ||
803 | return(acpi_idle_enter_c1(dev, state)); | ||
804 | 808 | ||
805 | local_irq_disable(); | 809 | local_irq_disable(); |
806 | 810 | ||
811 | if (acpi_idle_suspend) { | ||
812 | local_irq_enable(); | ||
813 | cpu_relax(); | ||
814 | return -EINVAL; | ||
815 | } | ||
816 | |||
817 | |||
807 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 818 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
808 | current_thread_info()->status &= ~TS_POLLING; | 819 | current_thread_info()->status &= ~TS_POLLING; |
809 | /* | 820 | /* |
@@ -815,7 +826,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
815 | if (unlikely(need_resched())) { | 826 | if (unlikely(need_resched())) { |
816 | current_thread_info()->status |= TS_POLLING; | 827 | current_thread_info()->status |= TS_POLLING; |
817 | local_irq_enable(); | 828 | local_irq_enable(); |
818 | return 0; | 829 | return -EINVAL; |
819 | } | 830 | } |
820 | } | 831 | } |
821 | 832 | ||
@@ -837,6 +848,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
837 | idle_time = idle_time_ns; | 848 | idle_time = idle_time_ns; |
838 | do_div(idle_time, NSEC_PER_USEC); | 849 | do_div(idle_time, NSEC_PER_USEC); |
839 | 850 | ||
851 | /* Update device last_residency*/ | ||
852 | dev->last_residency = (int)idle_time; | ||
853 | |||
840 | /* Tell the scheduler how much we idled: */ | 854 | /* Tell the scheduler how much we idled: */ |
841 | sched_clock_idle_wakeup_event(idle_time_ns); | 855 | sched_clock_idle_wakeup_event(idle_time_ns); |
842 | 856 | ||
@@ -848,7 +862,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
848 | 862 | ||
849 | lapic_timer_state_broadcast(pr, cx, 0); | 863 | lapic_timer_state_broadcast(pr, cx, 0); |
850 | cx->time += idle_time; | 864 | cx->time += idle_time; |
851 | return idle_time; | 865 | return index; |
852 | } | 866 | } |
853 | 867 | ||
854 | static int c3_cpu_count; | 868 | static int c3_cpu_count; |
@@ -857,14 +871,15 @@ static DEFINE_SPINLOCK(c3_lock); | |||
857 | /** | 871 | /** |
858 | * acpi_idle_enter_bm - enters C3 with proper BM handling | 872 | * acpi_idle_enter_bm - enters C3 with proper BM handling |
859 | * @dev: the target CPU | 873 | * @dev: the target CPU |
860 | * @state: the state data | 874 | * @index: the index of suggested state |
861 | * | 875 | * |
862 | * If BM is detected, the deepest non-C3 idle state is entered instead. | 876 | * If BM is detected, the deepest non-C3 idle state is entered instead. |
863 | */ | 877 | */ |
864 | static int acpi_idle_enter_bm(struct cpuidle_device *dev, | 878 | static int acpi_idle_enter_bm(struct cpuidle_device *dev, |
865 | struct cpuidle_state *state) | 879 | int index) |
866 | { | 880 | { |
867 | struct acpi_processor *pr; | 881 | struct acpi_processor *pr; |
882 | struct cpuidle_state *state = &dev->states[index]; | ||
868 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 883 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
869 | ktime_t kt1, kt2; | 884 | ktime_t kt1, kt2; |
870 | s64 idle_time_ns; | 885 | s64 idle_time_ns; |
@@ -872,22 +887,26 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
872 | 887 | ||
873 | 888 | ||
874 | pr = __this_cpu_read(processors); | 889 | pr = __this_cpu_read(processors); |
890 | dev->last_residency = 0; | ||
875 | 891 | ||
876 | if (unlikely(!pr)) | 892 | if (unlikely(!pr)) |
877 | return 0; | 893 | return -EINVAL; |
878 | 894 | ||
879 | if (acpi_idle_suspend) | 895 | |
880 | return(acpi_idle_enter_c1(dev, state)); | 896 | if (acpi_idle_suspend) { |
897 | cpu_relax(); | ||
898 | return -EINVAL; | ||
899 | } | ||
881 | 900 | ||
882 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { | 901 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { |
883 | if (dev->safe_state) { | 902 | if (dev->safe_state_index >= 0) { |
884 | dev->last_state = dev->safe_state; | 903 | return dev->states[dev->safe_state_index].enter(dev, |
885 | return dev->safe_state->enter(dev, dev->safe_state); | 904 | dev->safe_state_index); |
886 | } else { | 905 | } else { |
887 | local_irq_disable(); | 906 | local_irq_disable(); |
888 | acpi_safe_halt(); | 907 | acpi_safe_halt(); |
889 | local_irq_enable(); | 908 | local_irq_enable(); |
890 | return 0; | 909 | return -EINVAL; |
891 | } | 910 | } |
892 | } | 911 | } |
893 | 912 | ||
@@ -904,7 +923,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
904 | if (unlikely(need_resched())) { | 923 | if (unlikely(need_resched())) { |
905 | current_thread_info()->status |= TS_POLLING; | 924 | current_thread_info()->status |= TS_POLLING; |
906 | local_irq_enable(); | 925 | local_irq_enable(); |
907 | return 0; | 926 | return -EINVAL; |
908 | } | 927 | } |
909 | } | 928 | } |
910 | 929 | ||
@@ -954,6 +973,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
954 | idle_time = idle_time_ns; | 973 | idle_time = idle_time_ns; |
955 | do_div(idle_time, NSEC_PER_USEC); | 974 | do_div(idle_time, NSEC_PER_USEC); |
956 | 975 | ||
976 | /* Update device last_residency*/ | ||
977 | dev->last_residency = (int)idle_time; | ||
978 | |||
957 | /* Tell the scheduler how much we idled: */ | 979 | /* Tell the scheduler how much we idled: */ |
958 | sched_clock_idle_wakeup_event(idle_time_ns); | 980 | sched_clock_idle_wakeup_event(idle_time_ns); |
959 | 981 | ||
@@ -965,7 +987,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
965 | 987 | ||
966 | lapic_timer_state_broadcast(pr, cx, 0); | 988 | lapic_timer_state_broadcast(pr, cx, 0); |
967 | cx->time += idle_time; | 989 | cx->time += idle_time; |
968 | return idle_time; | 990 | return index; |
969 | } | 991 | } |
970 | 992 | ||
971 | struct cpuidle_driver acpi_idle_driver = { | 993 | struct cpuidle_driver acpi_idle_driver = { |
@@ -992,6 +1014,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
992 | } | 1014 | } |
993 | 1015 | ||
994 | dev->cpu = pr->id; | 1016 | dev->cpu = pr->id; |
1017 | dev->safe_state_index = -1; | ||
995 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { | 1018 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { |
996 | dev->states[i].name[0] = '\0'; | 1019 | dev->states[i].name[0] = '\0'; |
997 | dev->states[i].desc[0] = '\0'; | 1020 | dev->states[i].desc[0] = '\0'; |
@@ -1027,13 +1050,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1027 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1050 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1028 | 1051 | ||
1029 | state->enter = acpi_idle_enter_c1; | 1052 | state->enter = acpi_idle_enter_c1; |
1030 | dev->safe_state = state; | 1053 | dev->safe_state_index = count; |
1031 | break; | 1054 | break; |
1032 | 1055 | ||
1033 | case ACPI_STATE_C2: | 1056 | case ACPI_STATE_C2: |
1034 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1057 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1035 | state->enter = acpi_idle_enter_simple; | 1058 | state->enter = acpi_idle_enter_simple; |
1036 | dev->safe_state = state; | 1059 | dev->safe_state_index = count; |
1037 | break; | 1060 | break; |
1038 | 1061 | ||
1039 | case ACPI_STATE_C3: | 1062 | case ACPI_STATE_C3: |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index d4c542372886..88bd12104396 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -62,7 +62,7 @@ int cpuidle_idle_call(void) | |||
62 | { | 62 | { |
63 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); | 63 | struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); |
64 | struct cpuidle_state *target_state; | 64 | struct cpuidle_state *target_state; |
65 | int next_state; | 65 | int next_state, entered_state; |
66 | 66 | ||
67 | if (off) | 67 | if (off) |
68 | return -ENODEV; | 68 | return -ENODEV; |
@@ -102,26 +102,27 @@ int cpuidle_idle_call(void) | |||
102 | 102 | ||
103 | target_state = &dev->states[next_state]; | 103 | target_state = &dev->states[next_state]; |
104 | 104 | ||
105 | /* enter the state and update stats */ | ||
106 | dev->last_state = target_state; | ||
107 | |||
108 | trace_power_start(POWER_CSTATE, next_state, dev->cpu); | 105 | trace_power_start(POWER_CSTATE, next_state, dev->cpu); |
109 | trace_cpu_idle(next_state, dev->cpu); | 106 | trace_cpu_idle(next_state, dev->cpu); |
110 | 107 | ||
111 | dev->last_residency = target_state->enter(dev, target_state); | 108 | entered_state = target_state->enter(dev, next_state); |
112 | 109 | ||
113 | trace_power_end(dev->cpu); | 110 | trace_power_end(dev->cpu); |
114 | trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); | 111 | trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); |
115 | 112 | ||
116 | if (dev->last_state) | 113 | if (entered_state >= 0) { |
117 | target_state = dev->last_state; | 114 | /* Update cpuidle counters */ |
118 | 115 | /* This can be moved to within driver enter routine | |
119 | target_state->time += (unsigned long long)dev->last_residency; | 116 | * but that results in multiple copies of same code. |
120 | target_state->usage++; | 117 | */ |
118 | dev->states[entered_state].time += | ||
119 | (unsigned long long)dev->last_residency; | ||
120 | dev->states[entered_state].usage++; | ||
121 | } | ||
121 | 122 | ||
122 | /* give the governor an opportunity to reflect on the outcome */ | 123 | /* give the governor an opportunity to reflect on the outcome */ |
123 | if (cpuidle_curr_governor->reflect) | 124 | if (cpuidle_curr_governor->reflect) |
124 | cpuidle_curr_governor->reflect(dev); | 125 | cpuidle_curr_governor->reflect(dev, entered_state); |
125 | 126 | ||
126 | return 0; | 127 | return 0; |
127 | } | 128 | } |
@@ -172,11 +173,10 @@ void cpuidle_resume_and_unlock(void) | |||
172 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); | 173 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); |
173 | 174 | ||
174 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | 175 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX |
175 | static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) | 176 | static int poll_idle(struct cpuidle_device *dev, int index) |
176 | { | 177 | { |
177 | ktime_t t1, t2; | 178 | ktime_t t1, t2; |
178 | s64 diff; | 179 | s64 diff; |
179 | int ret; | ||
180 | 180 | ||
181 | t1 = ktime_get(); | 181 | t1 = ktime_get(); |
182 | local_irq_enable(); | 182 | local_irq_enable(); |
@@ -188,8 +188,9 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) | |||
188 | if (diff > INT_MAX) | 188 | if (diff > INT_MAX) |
189 | diff = INT_MAX; | 189 | diff = INT_MAX; |
190 | 190 | ||
191 | ret = (int) diff; | 191 | dev->last_residency = (int) diff; |
192 | return ret; | 192 | |
193 | return index; | ||
193 | } | 194 | } |
194 | 195 | ||
195 | static void poll_idle_init(struct cpuidle_device *dev) | 196 | static void poll_idle_init(struct cpuidle_device *dev) |
@@ -248,7 +249,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
248 | dev->states[i].time = 0; | 249 | dev->states[i].time = 0; |
249 | } | 250 | } |
250 | dev->last_residency = 0; | 251 | dev->last_residency = 0; |
251 | dev->last_state = NULL; | ||
252 | 252 | ||
253 | smp_wmb(); | 253 | smp_wmb(); |
254 | 254 | ||
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 12c98900dcf8..6a686a76711f 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c | |||
@@ -153,11 +153,24 @@ static int ladder_enable_device(struct cpuidle_device *dev) | |||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
155 | 155 | ||
156 | /** | ||
157 | * ladder_reflect - update the correct last_state_idx | ||
158 | * @dev: the CPU | ||
159 | * @index: the index of actual state entered | ||
160 | */ | ||
161 | static void ladder_reflect(struct cpuidle_device *dev, int index) | ||
162 | { | ||
163 | struct ladder_device *ldev = &__get_cpu_var(ladder_devices); | ||
164 | if (index > 0) | ||
165 | ldev->last_state_idx = index; | ||
166 | } | ||
167 | |||
156 | static struct cpuidle_governor ladder_governor = { | 168 | static struct cpuidle_governor ladder_governor = { |
157 | .name = "ladder", | 169 | .name = "ladder", |
158 | .rating = 10, | 170 | .rating = 10, |
159 | .enable = ladder_enable_device, | 171 | .enable = ladder_enable_device, |
160 | .select = ladder_select_state, | 172 | .select = ladder_select_state, |
173 | .reflect = ladder_reflect, | ||
161 | .owner = THIS_MODULE, | 174 | .owner = THIS_MODULE, |
162 | }; | 175 | }; |
163 | 176 | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c47f3d09c1ee..e4b200c5b441 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -310,14 +310,17 @@ static int menu_select(struct cpuidle_device *dev) | |||
310 | /** | 310 | /** |
311 | * menu_reflect - records that data structures need update | 311 | * menu_reflect - records that data structures need update |
312 | * @dev: the CPU | 312 | * @dev: the CPU |
313 | * @index: the index of actual entered state | ||
313 | * | 314 | * |
314 | * NOTE: it's important to be fast here because this operation will add to | 315 | * NOTE: it's important to be fast here because this operation will add to |
315 | * the overall exit latency. | 316 | * the overall exit latency. |
316 | */ | 317 | */ |
317 | static void menu_reflect(struct cpuidle_device *dev) | 318 | static void menu_reflect(struct cpuidle_device *dev, int index) |
318 | { | 319 | { |
319 | struct menu_device *data = &__get_cpu_var(menu_devices); | 320 | struct menu_device *data = &__get_cpu_var(menu_devices); |
320 | data->needs_update = 1; | 321 | data->last_state_idx = index; |
322 | if (index >= 0) | ||
323 | data->needs_update = 1; | ||
321 | } | 324 | } |
322 | 325 | ||
323 | /** | 326 | /** |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a46dddf61078..a1c888d2216a 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -81,7 +81,7 @@ static unsigned int mwait_substates; | |||
81 | static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ | 81 | static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ |
82 | 82 | ||
83 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; | 83 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
84 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 84 | static int intel_idle(struct cpuidle_device *dev, int index); |
85 | 85 | ||
86 | static struct cpuidle_state *cpuidle_state_table; | 86 | static struct cpuidle_state *cpuidle_state_table; |
87 | 87 | ||
@@ -209,12 +209,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
209 | /** | 209 | /** |
210 | * intel_idle | 210 | * intel_idle |
211 | * @dev: cpuidle_device | 211 | * @dev: cpuidle_device |
212 | * @state: cpuidle state | 212 | * @index: index of cpuidle state |
213 | * | 213 | * |
214 | */ | 214 | */ |
215 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | 215 | static int intel_idle(struct cpuidle_device *dev, int index) |
216 | { | 216 | { |
217 | unsigned long ecx = 1; /* break on interrupt flag */ | 217 | unsigned long ecx = 1; /* break on interrupt flag */ |
218 | struct cpuidle_state *state = &dev->states[index]; | ||
218 | unsigned long eax = (unsigned long)cpuidle_get_statedata(state); | 219 | unsigned long eax = (unsigned long)cpuidle_get_statedata(state); |
219 | unsigned int cstate; | 220 | unsigned int cstate; |
220 | ktime_t kt_before, kt_after; | 221 | ktime_t kt_before, kt_after; |
@@ -256,7 +257,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
256 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 257 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
257 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | 258 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); |
258 | 259 | ||
259 | return usec_delta; | 260 | /* Update cpuidle counters */ |
261 | dev->last_residency = (int)usec_delta; | ||
262 | |||
263 | return index; | ||
260 | } | 264 | } |
261 | 265 | ||
262 | static void __setup_broadcast_timer(void *arg) | 266 | static void __setup_broadcast_timer(void *arg) |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index b51629e15cfc..8da811bcdbdb 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -42,7 +42,7 @@ struct cpuidle_state { | |||
42 | unsigned long long time; /* in US */ | 42 | unsigned long long time; /* in US */ |
43 | 43 | ||
44 | int (*enter) (struct cpuidle_device *dev, | 44 | int (*enter) (struct cpuidle_device *dev, |
45 | struct cpuidle_state *state); | 45 | int index); |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* Idle State Flags */ | 48 | /* Idle State Flags */ |
@@ -87,13 +87,12 @@ struct cpuidle_device { | |||
87 | int state_count; | 87 | int state_count; |
88 | struct cpuidle_state states[CPUIDLE_STATE_MAX]; | 88 | struct cpuidle_state states[CPUIDLE_STATE_MAX]; |
89 | struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; | 89 | struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; |
90 | struct cpuidle_state *last_state; | ||
91 | 90 | ||
92 | struct list_head device_list; | 91 | struct list_head device_list; |
93 | struct kobject kobj; | 92 | struct kobject kobj; |
94 | struct completion kobj_unregister; | 93 | struct completion kobj_unregister; |
95 | void *governor_data; | 94 | void *governor_data; |
96 | struct cpuidle_state *safe_state; | 95 | int safe_state_index; |
97 | 96 | ||
98 | int (*prepare) (struct cpuidle_device *dev); | 97 | int (*prepare) (struct cpuidle_device *dev); |
99 | }; | 98 | }; |
@@ -169,7 +168,7 @@ struct cpuidle_governor { | |||
169 | void (*disable) (struct cpuidle_device *dev); | 168 | void (*disable) (struct cpuidle_device *dev); |
170 | 169 | ||
171 | int (*select) (struct cpuidle_device *dev); | 170 | int (*select) (struct cpuidle_device *dev); |
172 | void (*reflect) (struct cpuidle_device *dev); | 171 | void (*reflect) (struct cpuidle_device *dev, int index); |
173 | 172 | ||
174 | struct module *owner; | 173 | struct module *owner; |
175 | }; | 174 | }; |