aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/idle/intel_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/idle/intel_idle.c')
-rw-r--r--drivers/idle/intel_idle.c296
1 files changed, 176 insertions, 120 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0f6b4c8ee14..1a38dd7dfe4e 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -56,7 +56,6 @@
56#include <linux/kernel.h> 56#include <linux/kernel.h>
57#include <linux/cpuidle.h> 57#include <linux/cpuidle.h>
58#include <linux/clockchips.h> 58#include <linux/clockchips.h>
59#include <linux/hrtimer.h> /* ktime_get_real() */
60#include <trace/events/power.h> 59#include <trace/events/power.h>
61#include <linux/sched.h> 60#include <linux/sched.h>
62#include <linux/notifier.h> 61#include <linux/notifier.h>
@@ -72,9 +71,10 @@
72static struct cpuidle_driver intel_idle_driver = { 71static struct cpuidle_driver intel_idle_driver = {
73 .name = "intel_idle", 72 .name = "intel_idle",
74 .owner = THIS_MODULE, 73 .owner = THIS_MODULE,
74 .en_core_tk_irqen = 1,
75}; 75};
76/* intel_idle.max_cstate=0 disables driver */ 76/* intel_idle.max_cstate=0 disables driver */
77static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1; 77static int max_cstate = CPUIDLE_STATE_MAX - 1;
78 78
79static unsigned int mwait_substates; 79static unsigned int mwait_substates;
80 80
@@ -90,6 +90,7 @@ struct idle_cpu {
90 * Indicate which enable bits to clear here. 90 * Indicate which enable bits to clear here.
91 */ 91 */
92 unsigned long auto_demotion_disable_flags; 92 unsigned long auto_demotion_disable_flags;
93 bool disable_promotion_to_c1e;
93}; 94};
94 95
95static const struct idle_cpu *icpu; 96static const struct idle_cpu *icpu;
@@ -109,162 +110,206 @@ static struct cpuidle_state *cpuidle_state_table;
109#define CPUIDLE_FLAG_TLB_FLUSHED 0x10000 110#define CPUIDLE_FLAG_TLB_FLUSHED 0x10000
110 111
111/* 112/*
113 * MWAIT takes an 8-bit "hint" in EAX "suggesting"
114 * the C-state (top nibble) and sub-state (bottom nibble)
115 * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc.
116 *
117 * We store the hint at the top of our "flags" for each state.
118 */
119#define flg2MWAIT(flags) (((flags) >> 24) & 0xFF)
120#define MWAIT2flg(eax) ((eax & 0xFF) << 24)
121
122/*
112 * States are indexed by the cstate number, 123 * States are indexed by the cstate number,
113 * which is also the index into the MWAIT hint array. 124 * which is also the index into the MWAIT hint array.
114 * Thus C0 is a dummy. 125 * Thus C0 is a dummy.
115 */ 126 */
116static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { 127static struct cpuidle_state nehalem_cstates[CPUIDLE_STATE_MAX] = {
117 { /* MWAIT C0 */ }, 128 {
118 { /* MWAIT C1 */
119 .name = "C1-NHM", 129 .name = "C1-NHM",
120 .desc = "MWAIT 0x00", 130 .desc = "MWAIT 0x00",
121 .flags = CPUIDLE_FLAG_TIME_VALID, 131 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
122 .exit_latency = 3, 132 .exit_latency = 3,
123 .target_residency = 6, 133 .target_residency = 6,
124 .enter = &intel_idle }, 134 .enter = &intel_idle },
125 { /* MWAIT C2 */ 135 {
136 .name = "C1E-NHM",
137 .desc = "MWAIT 0x01",
138 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
139 .exit_latency = 10,
140 .target_residency = 20,
141 .enter = &intel_idle },
142 {
126 .name = "C3-NHM", 143 .name = "C3-NHM",
127 .desc = "MWAIT 0x10", 144 .desc = "MWAIT 0x10",
128 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 145 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
129 .exit_latency = 20, 146 .exit_latency = 20,
130 .target_residency = 80, 147 .target_residency = 80,
131 .enter = &intel_idle }, 148 .enter = &intel_idle },
132 { /* MWAIT C3 */ 149 {
133 .name = "C6-NHM", 150 .name = "C6-NHM",
134 .desc = "MWAIT 0x20", 151 .desc = "MWAIT 0x20",
135 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 152 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
136 .exit_latency = 200, 153 .exit_latency = 200,
137 .target_residency = 800, 154 .target_residency = 800,
138 .enter = &intel_idle }, 155 .enter = &intel_idle },
156 {
157 .enter = NULL }
139}; 158};
140 159
141static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { 160static struct cpuidle_state snb_cstates[CPUIDLE_STATE_MAX] = {
142 { /* MWAIT C0 */ }, 161 {
143 { /* MWAIT C1 */
144 .name = "C1-SNB", 162 .name = "C1-SNB",
145 .desc = "MWAIT 0x00", 163 .desc = "MWAIT 0x00",
146 .flags = CPUIDLE_FLAG_TIME_VALID, 164 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
147 .exit_latency = 1, 165 .exit_latency = 2,
148 .target_residency = 1, 166 .target_residency = 2,
167 .enter = &intel_idle },
168 {
169 .name = "C1E-SNB",
170 .desc = "MWAIT 0x01",
171 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
172 .exit_latency = 10,
173 .target_residency = 20,
149 .enter = &intel_idle }, 174 .enter = &intel_idle },
150 { /* MWAIT C2 */ 175 {
151 .name = "C3-SNB", 176 .name = "C3-SNB",
152 .desc = "MWAIT 0x10", 177 .desc = "MWAIT 0x10",
153 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 178 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
154 .exit_latency = 80, 179 .exit_latency = 80,
155 .target_residency = 211, 180 .target_residency = 211,
156 .enter = &intel_idle }, 181 .enter = &intel_idle },
157 { /* MWAIT C3 */ 182 {
158 .name = "C6-SNB", 183 .name = "C6-SNB",
159 .desc = "MWAIT 0x20", 184 .desc = "MWAIT 0x20",
160 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 185 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
161 .exit_latency = 104, 186 .exit_latency = 104,
162 .target_residency = 345, 187 .target_residency = 345,
163 .enter = &intel_idle }, 188 .enter = &intel_idle },
164 { /* MWAIT C4 */ 189 {
165 .name = "C7-SNB", 190 .name = "C7-SNB",
166 .desc = "MWAIT 0x30", 191 .desc = "MWAIT 0x30",
167 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 192 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
168 .exit_latency = 109, 193 .exit_latency = 109,
169 .target_residency = 345, 194 .target_residency = 345,
170 .enter = &intel_idle }, 195 .enter = &intel_idle },
196 {
197 .enter = NULL }
171}; 198};
172 199
173static struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = { 200static struct cpuidle_state ivb_cstates[CPUIDLE_STATE_MAX] = {
174 { /* MWAIT C0 */ }, 201 {
175 { /* MWAIT C1 */
176 .name = "C1-IVB", 202 .name = "C1-IVB",
177 .desc = "MWAIT 0x00", 203 .desc = "MWAIT 0x00",
178 .flags = CPUIDLE_FLAG_TIME_VALID, 204 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
179 .exit_latency = 1, 205 .exit_latency = 1,
180 .target_residency = 1, 206 .target_residency = 1,
181 .enter = &intel_idle }, 207 .enter = &intel_idle },
182 { /* MWAIT C2 */ 208 {
209 .name = "C1E-IVB",
210 .desc = "MWAIT 0x01",
211 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
212 .exit_latency = 10,
213 .target_residency = 20,
214 .enter = &intel_idle },
215 {
183 .name = "C3-IVB", 216 .name = "C3-IVB",
184 .desc = "MWAIT 0x10", 217 .desc = "MWAIT 0x10",
185 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 218 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
186 .exit_latency = 59, 219 .exit_latency = 59,
187 .target_residency = 156, 220 .target_residency = 156,
188 .enter = &intel_idle }, 221 .enter = &intel_idle },
189 { /* MWAIT C3 */ 222 {
190 .name = "C6-IVB", 223 .name = "C6-IVB",
191 .desc = "MWAIT 0x20", 224 .desc = "MWAIT 0x20",
192 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 225 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
193 .exit_latency = 80, 226 .exit_latency = 80,
194 .target_residency = 300, 227 .target_residency = 300,
195 .enter = &intel_idle }, 228 .enter = &intel_idle },
196 { /* MWAIT C4 */ 229 {
197 .name = "C7-IVB", 230 .name = "C7-IVB",
198 .desc = "MWAIT 0x30", 231 .desc = "MWAIT 0x30",
199 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 232 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
200 .exit_latency = 87, 233 .exit_latency = 87,
201 .target_residency = 300, 234 .target_residency = 300,
202 .enter = &intel_idle }, 235 .enter = &intel_idle },
236 {
237 .enter = NULL }
203}; 238};
204 239
205static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { 240static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = {
206 { /* MWAIT C0 */ }, 241 {
207 { /* MWAIT C1 */ 242 .name = "C1-HSW",
208 .name = "C1-ATM",
209 .desc = "MWAIT 0x00", 243 .desc = "MWAIT 0x00",
210 .flags = CPUIDLE_FLAG_TIME_VALID, 244 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
211 .exit_latency = 1, 245 .exit_latency = 2,
212 .target_residency = 4, 246 .target_residency = 2,
247 .enter = &intel_idle },
248 {
249 .name = "C1E-HSW",
250 .desc = "MWAIT 0x01",
251 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
252 .exit_latency = 10,
253 .target_residency = 20,
254 .enter = &intel_idle },
255 {
256 .name = "C3-HSW",
257 .desc = "MWAIT 0x10",
258 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
259 .exit_latency = 33,
260 .target_residency = 100,
261 .enter = &intel_idle },
262 {
263 .name = "C6-HSW",
264 .desc = "MWAIT 0x20",
265 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
266 .exit_latency = 133,
267 .target_residency = 400,
213 .enter = &intel_idle }, 268 .enter = &intel_idle },
214 { /* MWAIT C2 */ 269 {
270 .name = "C7s-HSW",
271 .desc = "MWAIT 0x32",
272 .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
273 .exit_latency = 166,
274 .target_residency = 500,
275 .enter = &intel_idle },
276 {
277 .enter = NULL }
278};
279
280static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = {
281 {
282 .name = "C1E-ATM",
283 .desc = "MWAIT 0x00",
284 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
285 .exit_latency = 10,
286 .target_residency = 20,
287 .enter = &intel_idle },
288 {
215 .name = "C2-ATM", 289 .name = "C2-ATM",
216 .desc = "MWAIT 0x10", 290 .desc = "MWAIT 0x10",
217 .flags = CPUIDLE_FLAG_TIME_VALID, 291 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID,
218 .exit_latency = 20, 292 .exit_latency = 20,
219 .target_residency = 80, 293 .target_residency = 80,
220 .enter = &intel_idle }, 294 .enter = &intel_idle },
221 { /* MWAIT C3 */ }, 295 {
222 { /* MWAIT C4 */
223 .name = "C4-ATM", 296 .name = "C4-ATM",
224 .desc = "MWAIT 0x30", 297 .desc = "MWAIT 0x30",
225 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 298 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
226 .exit_latency = 100, 299 .exit_latency = 100,
227 .target_residency = 400, 300 .target_residency = 400,
228 .enter = &intel_idle }, 301 .enter = &intel_idle },
229 { /* MWAIT C5 */ }, 302 {
230 { /* MWAIT C6 */
231 .name = "C6-ATM", 303 .name = "C6-ATM",
232 .desc = "MWAIT 0x52", 304 .desc = "MWAIT 0x52",
233 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 305 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
234 .exit_latency = 140, 306 .exit_latency = 140,
235 .target_residency = 560, 307 .target_residency = 560,
236 .enter = &intel_idle }, 308 .enter = &intel_idle },
309 {
310 .enter = NULL }
237}; 311};
238 312
239static long get_driver_data(int cstate)
240{
241 int driver_data;
242 switch (cstate) {
243
244 case 1: /* MWAIT C1 */
245 driver_data = 0x00;
246 break;
247 case 2: /* MWAIT C2 */
248 driver_data = 0x10;
249 break;
250 case 3: /* MWAIT C3 */
251 driver_data = 0x20;
252 break;
253 case 4: /* MWAIT C4 */
254 driver_data = 0x30;
255 break;
256 case 5: /* MWAIT C5 */
257 driver_data = 0x40;
258 break;
259 case 6: /* MWAIT C6 */
260 driver_data = 0x52;
261 break;
262 default:
263 driver_data = 0x00;
264 }
265 return driver_data;
266}
267
268/** 313/**
269 * intel_idle 314 * intel_idle
270 * @dev: cpuidle_device 315 * @dev: cpuidle_device
@@ -278,11 +323,8 @@ static int intel_idle(struct cpuidle_device *dev,
278{ 323{
279 unsigned long ecx = 1; /* break on interrupt flag */ 324 unsigned long ecx = 1; /* break on interrupt flag */
280 struct cpuidle_state *state = &drv->states[index]; 325 struct cpuidle_state *state = &drv->states[index];
281 struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; 326 unsigned long eax = flg2MWAIT(state->flags);
282 unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
283 unsigned int cstate; 327 unsigned int cstate;
284 ktime_t kt_before, kt_after;
285 s64 usec_delta;
286 int cpu = smp_processor_id(); 328 int cpu = smp_processor_id();
287 329
288 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; 330 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
@@ -297,8 +339,6 @@ static int intel_idle(struct cpuidle_device *dev,
297 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 339 if (!(lapic_timer_reliable_states & (1 << (cstate))))
298 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); 340 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
299 341
300 kt_before = ktime_get_real();
301
302 stop_critical_timings(); 342 stop_critical_timings();
303 if (!need_resched()) { 343 if (!need_resched()) {
304 344
@@ -310,17 +350,9 @@ static int intel_idle(struct cpuidle_device *dev,
310 350
311 start_critical_timings(); 351 start_critical_timings();
312 352
313 kt_after = ktime_get_real();
314 usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
315
316 local_irq_enable();
317
318 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 353 if (!(lapic_timer_reliable_states & (1 << (cstate))))
319 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); 354 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
320 355
321 /* Update cpuidle counters */
322 dev->last_residency = (int)usec_delta;
323
324 return index; 356 return index;
325} 357}
326 358
@@ -374,10 +406,19 @@ static void auto_demotion_disable(void *dummy)
374 msr_bits &= ~(icpu->auto_demotion_disable_flags); 406 msr_bits &= ~(icpu->auto_demotion_disable_flags);
375 wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); 407 wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
376} 408}
409static void c1e_promotion_disable(void *dummy)
410{
411 unsigned long long msr_bits;
412
413 rdmsrl(MSR_IA32_POWER_CTL, msr_bits);
414 msr_bits &= ~0x2;
415 wrmsrl(MSR_IA32_POWER_CTL, msr_bits);
416}
377 417
378static const struct idle_cpu idle_cpu_nehalem = { 418static const struct idle_cpu idle_cpu_nehalem = {
379 .state_table = nehalem_cstates, 419 .state_table = nehalem_cstates,
380 .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 420 .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
421 .disable_promotion_to_c1e = true,
381}; 422};
382 423
383static const struct idle_cpu idle_cpu_atom = { 424static const struct idle_cpu idle_cpu_atom = {
@@ -391,10 +432,17 @@ static const struct idle_cpu idle_cpu_lincroft = {
391 432
392static const struct idle_cpu idle_cpu_snb = { 433static const struct idle_cpu idle_cpu_snb = {
393 .state_table = snb_cstates, 434 .state_table = snb_cstates,
435 .disable_promotion_to_c1e = true,
394}; 436};
395 437
396static const struct idle_cpu idle_cpu_ivb = { 438static const struct idle_cpu idle_cpu_ivb = {
397 .state_table = ivb_cstates, 439 .state_table = ivb_cstates,
440 .disable_promotion_to_c1e = true,
441};
442
443static const struct idle_cpu idle_cpu_hsw = {
444 .state_table = hsw_cstates,
445 .disable_promotion_to_c1e = true,
398}; 446};
399 447
400#define ICPU(model, cpu) \ 448#define ICPU(model, cpu) \
@@ -414,6 +462,10 @@ static const struct x86_cpu_id intel_idle_ids[] = {
414 ICPU(0x2d, idle_cpu_snb), 462 ICPU(0x2d, idle_cpu_snb),
415 ICPU(0x3a, idle_cpu_ivb), 463 ICPU(0x3a, idle_cpu_ivb),
416 ICPU(0x3e, idle_cpu_ivb), 464 ICPU(0x3e, idle_cpu_ivb),
465 ICPU(0x3c, idle_cpu_hsw),
466 ICPU(0x3f, idle_cpu_hsw),
467 ICPU(0x45, idle_cpu_hsw),
468 ICPU(0x46, idle_cpu_hsw),
417 {} 469 {}
418}; 470};
419MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); 471MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
@@ -460,8 +512,6 @@ static int intel_idle_probe(void)
460 else 512 else
461 on_each_cpu(__setup_broadcast_timer, (void *)true, 1); 513 on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
462 514
463 register_cpu_notifier(&cpu_hotplug_notifier);
464
465 pr_debug(PREFIX "v" INTEL_IDLE_VERSION 515 pr_debug(PREFIX "v" INTEL_IDLE_VERSION
466 " model 0x%X\n", boot_cpu_data.x86_model); 516 " model 0x%X\n", boot_cpu_data.x86_model);
467 517
@@ -498,32 +548,31 @@ static int intel_idle_cpuidle_driver_init(void)
498 548
499 drv->state_count = 1; 549 drv->state_count = 1;
500 550
501 for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { 551 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
502 int num_substates; 552 int num_substates, mwait_hint, mwait_cstate, mwait_substate;
553
554 if (cpuidle_state_table[cstate].enter == NULL)
555 break;
503 556
504 if (cstate > max_cstate) { 557 if (cstate + 1 > max_cstate) {
505 printk(PREFIX "max_cstate %d reached\n", 558 printk(PREFIX "max_cstate %d reached\n",
506 max_cstate); 559 max_cstate);
507 break; 560 break;
508 } 561 }
509 562
563 mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags);
564 mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint);
565 mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint);
566
510 /* does the state exist in CPUID.MWAIT? */ 567 /* does the state exist in CPUID.MWAIT? */
511 num_substates = (mwait_substates >> ((cstate) * 4)) 568 num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4))
512 & MWAIT_SUBSTATE_MASK; 569 & MWAIT_SUBSTATE_MASK;
513 if (num_substates == 0) 570
514 continue; 571 /* if sub-state in table is not enumerated by CPUID */
515 /* is the state not enabled? */ 572 if ((mwait_substate + 1) > num_substates)
516 if (cpuidle_state_table[cstate].enter == NULL) {
517 /* does the driver not know about the state? */
518 if (*cpuidle_state_table[cstate].name == '\0')
519 pr_debug(PREFIX "unaware of model 0x%x"
520 " MWAIT %d please"
521 " contact lenb@kernel.org",
522 boot_cpu_data.x86_model, cstate);
523 continue; 573 continue;
524 }
525 574
526 if ((cstate > 2) && 575 if (((mwait_cstate + 1) > 2) &&
527 !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) 576 !boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
528 mark_tsc_unstable("TSC halts in idle" 577 mark_tsc_unstable("TSC halts in idle"
529 " states deeper than C2"); 578 " states deeper than C2");
@@ -537,6 +586,9 @@ static int intel_idle_cpuidle_driver_init(void)
537 if (icpu->auto_demotion_disable_flags) 586 if (icpu->auto_demotion_disable_flags)
538 on_each_cpu(auto_demotion_disable, NULL, 1); 587 on_each_cpu(auto_demotion_disable, NULL, 1);
539 588
589 if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */
590 on_each_cpu(c1e_promotion_disable, NULL, 1);
591
540 return 0; 592 return 0;
541} 593}
542 594
@@ -555,25 +607,28 @@ static int intel_idle_cpu_init(int cpu)
555 607
556 dev->state_count = 1; 608 dev->state_count = 1;
557 609
558 for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { 610 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
559 int num_substates; 611 int num_substates, mwait_hint, mwait_cstate, mwait_substate;
612
613 if (cpuidle_state_table[cstate].enter == NULL)
614 continue;
560 615
561 if (cstate > max_cstate) { 616 if (cstate + 1 > max_cstate) {
562 printk(PREFIX "max_cstate %d reached\n", max_cstate); 617 printk(PREFIX "max_cstate %d reached\n", max_cstate);
563 break; 618 break;
564 } 619 }
565 620
621 mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags);
622 mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint);
623 mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint);
624
566 /* does the state exist in CPUID.MWAIT? */ 625 /* does the state exist in CPUID.MWAIT? */
567 num_substates = (mwait_substates >> ((cstate) * 4)) 626 num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4))
568 & MWAIT_SUBSTATE_MASK; 627 & MWAIT_SUBSTATE_MASK;
569 if (num_substates == 0)
570 continue;
571 /* is the state not enabled? */
572 if (cpuidle_state_table[cstate].enter == NULL)
573 continue;
574 628
575 dev->states_usage[dev->state_count].driver_data = 629 /* if sub-state in table is not enumerated by CPUID */
576 (void *)get_driver_data(cstate); 630 if ((mwait_substate + 1) > num_substates)
631 continue;
577 632
578 dev->state_count += 1; 633 dev->state_count += 1;
579 } 634 }
@@ -624,6 +679,7 @@ static int __init intel_idle_init(void)
624 return retval; 679 return retval;
625 } 680 }
626 } 681 }
682 register_cpu_notifier(&cpu_hotplug_notifier);
627 683
628 return 0; 684 return 0;
629} 685}