Blame view

drivers/idle/intel_idle.c 13.4 KB
267171726   Len Brown   intel_idle: nativ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  /*
   * intel_idle.c - native hardware idle loop for modern Intel processors
   *
   * Copyright (c) 2010, Intel Corporation.
   * Len Brown <len.brown@intel.com>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
   * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc.,
   * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   */
  
  /*
   * intel_idle is a cpuidle driver that loads on specific Intel processors
   * in lieu of the legacy ACPI processor_idle driver.  The intent is to
   * make Linux more efficient on these processors, as intel_idle knows
   * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs.
   */
  
  /*
   * Design Assumptions
   *
   * All CPUs have same idle states as boot CPU
   *
   * Chipset BM_STS (bus master status) bit is a NOP
   *	for preventing entry into deep C-stats
   */
  
  /*
   * Known limitations
   *
   * The driver currently initializes for_each_online_cpu() upon modprobe.
   * It it unaware of subsequent processors hot-added to the system.
   * This means that if you boot with maxcpus=n and later online
   * processors above n, those processors will use C1 only.
   *
   * ACPI has a .suspend hack to turn off deep c-statees during suspend
   * to avoid complications with the lapic timer workaround.
   * Have not seen issues with suspend, but may need same workaround here.
   *
   * There is currently no kernel-based automatic probing/loading mechanism
   * if the driver is built as a module.
   */
  
  /* un-comment DEBUG to enable pr_debug() statements */
  #define DEBUG
  
  #include <linux/kernel.h>
  #include <linux/cpuidle.h>
  #include <linux/clockchips.h>
  #include <linux/hrtimer.h>	/* ktime_get_real() */
  #include <trace/events/power.h>
  #include <linux/sched.h>
2a2d31c8d   Shaohua Li   intel_idle: open ...
62
63
  #include <linux/notifier.h>
  #include <linux/cpu.h>
bc83cccc7   H. Peter Anvin   x86, mwait: Move ...
64
  #include <asm/mwait.h>
14796fca2   Len Brown   intel_idle: disab...
65
  #include <asm/msr.h>
267171726   Len Brown   intel_idle: nativ...
66
67
68
  
  #define INTEL_IDLE_VERSION "0.4"
  #define PREFIX "intel_idle: "
267171726   Len Brown   intel_idle: nativ...
69
70
71
72
73
74
  static struct cpuidle_driver intel_idle_driver = {
  	.name = "intel_idle",
  	.owner = THIS_MODULE,
  };
  /* intel_idle.max_cstate=0 disables driver */
  static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1;
267171726   Len Brown   intel_idle: nativ...
75

c4236282e   Len Brown   intel_idle: delet...
76
  static unsigned int mwait_substates;
267171726   Len Brown   intel_idle: nativ...
77

2a2d31c8d   Shaohua Li   intel_idle: open ...
78
  #define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF
267171726   Len Brown   intel_idle: nativ...
79
  /* Reliable LAPIC Timer States, bit 1 for C1 etc.  */
d13780d43   Len Brown   intel_idle: add i...
80
  static unsigned int lapic_timer_reliable_states = (1 << 1);	 /* Default to only C1 */
267171726   Len Brown   intel_idle: nativ...
81

3265eba0b   Namhyung Kim   intel_idle: add m...
82
  static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
267171726   Len Brown   intel_idle: nativ...
83
84
85
86
87
  static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
  
  static struct cpuidle_state *cpuidle_state_table;
  
  /*
14796fca2   Len Brown   intel_idle: disab...
88
89
90
91
92
93
   * Hardware C-state auto-demotion may not always be optimal.
   * Indicate which enable bits to clear here.
   */
  static unsigned long long auto_demotion_disable_flags;
  
  /*
956d033fb   Len Brown   cpuidle: CPUIDLE_...
94
95
96
97
98
99
100
101
   * Set this flag for states where the HW flushes the TLB for us
   * and so we don't need cross-calls to keep it consistent.
   * If this flag is set, SW flushes the TLB, so even if the
   * HW doesn't do the flushing, this flag is safe to use.
   */
  #define CPUIDLE_FLAG_TLB_FLUSHED	0x10000
  
  /*
267171726   Len Brown   intel_idle: nativ...
102
103
104
105
106
107
108
   * States are indexed by the cstate number,
   * which is also the index into the MWAIT hint array.
   * Thus C0 is a dummy.
   */
  static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
  	{ /* MWAIT C0 */ },
  	{ /* MWAIT C1 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
109
  		.name = "C1-NHM",
267171726   Len Brown   intel_idle: nativ...
110
111
112
113
  		.desc = "MWAIT 0x00",
  		.driver_data = (void *) 0x00,
  		.flags = CPUIDLE_FLAG_TIME_VALID,
  		.exit_latency = 3,
267171726   Len Brown   intel_idle: nativ...
114
115
116
  		.target_residency = 6,
  		.enter = &intel_idle },
  	{ /* MWAIT C2 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
117
  		.name = "C3-NHM",
267171726   Len Brown   intel_idle: nativ...
118
119
  		.desc = "MWAIT 0x10",
  		.driver_data = (void *) 0x10,
6110a1f43   Suresh Siddha   intel_idle: Volun...
120
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
267171726   Len Brown   intel_idle: nativ...
121
  		.exit_latency = 20,
267171726   Len Brown   intel_idle: nativ...
122
123
124
  		.target_residency = 80,
  		.enter = &intel_idle },
  	{ /* MWAIT C3 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
125
  		.name = "C6-NHM",
267171726   Len Brown   intel_idle: nativ...
126
127
  		.desc = "MWAIT 0x20",
  		.driver_data = (void *) 0x20,
6110a1f43   Suresh Siddha   intel_idle: Volun...
128
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
267171726   Len Brown   intel_idle: nativ...
129
  		.exit_latency = 200,
267171726   Len Brown   intel_idle: nativ...
130
131
132
  		.target_residency = 800,
  		.enter = &intel_idle },
  };
d13780d43   Len Brown   intel_idle: add i...
133
134
135
  static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
  	{ /* MWAIT C0 */ },
  	{ /* MWAIT C1 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
136
  		.name = "C1-SNB",
d13780d43   Len Brown   intel_idle: add i...
137
138
139
140
  		.desc = "MWAIT 0x00",
  		.driver_data = (void *) 0x00,
  		.flags = CPUIDLE_FLAG_TIME_VALID,
  		.exit_latency = 1,
ddbd550d5   Len Brown   intel_idle: updat...
141
  		.target_residency = 1,
d13780d43   Len Brown   intel_idle: add i...
142
143
  		.enter = &intel_idle },
  	{ /* MWAIT C2 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
144
  		.name = "C3-SNB",
d13780d43   Len Brown   intel_idle: add i...
145
146
  		.desc = "MWAIT 0x10",
  		.driver_data = (void *) 0x10,
00527cc6b   Len Brown   Merge branch 'int...
147
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
d13780d43   Len Brown   intel_idle: add i...
148
  		.exit_latency = 80,
ddbd550d5   Len Brown   intel_idle: updat...
149
  		.target_residency = 211,
d13780d43   Len Brown   intel_idle: add i...
150
151
  		.enter = &intel_idle },
  	{ /* MWAIT C3 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
152
  		.name = "C6-SNB",
d13780d43   Len Brown   intel_idle: add i...
153
154
  		.desc = "MWAIT 0x20",
  		.driver_data = (void *) 0x20,
00527cc6b   Len Brown   Merge branch 'int...
155
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
d13780d43   Len Brown   intel_idle: add i...
156
  		.exit_latency = 104,
ddbd550d5   Len Brown   intel_idle: updat...
157
  		.target_residency = 345,
d13780d43   Len Brown   intel_idle: add i...
158
159
  		.enter = &intel_idle },
  	{ /* MWAIT C4 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
160
  		.name = "C7-SNB",
d13780d43   Len Brown   intel_idle: add i...
161
162
  		.desc = "MWAIT 0x30",
  		.driver_data = (void *) 0x30,
00527cc6b   Len Brown   Merge branch 'int...
163
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
d13780d43   Len Brown   intel_idle: add i...
164
  		.exit_latency = 109,
ddbd550d5   Len Brown   intel_idle: updat...
165
  		.target_residency = 345,
d13780d43   Len Brown   intel_idle: add i...
166
167
  		.enter = &intel_idle },
  };
267171726   Len Brown   intel_idle: nativ...
168
169
170
  static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
  	{ /* MWAIT C0 */ },
  	{ /* MWAIT C1 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
171
  		.name = "C1-ATM",
267171726   Len Brown   intel_idle: nativ...
172
173
174
175
  		.desc = "MWAIT 0x00",
  		.driver_data = (void *) 0x00,
  		.flags = CPUIDLE_FLAG_TIME_VALID,
  		.exit_latency = 1,
267171726   Len Brown   intel_idle: nativ...
176
177
178
  		.target_residency = 4,
  		.enter = &intel_idle },
  	{ /* MWAIT C2 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
179
  		.name = "C2-ATM",
267171726   Len Brown   intel_idle: nativ...
180
181
182
183
  		.desc = "MWAIT 0x10",
  		.driver_data = (void *) 0x10,
  		.flags = CPUIDLE_FLAG_TIME_VALID,
  		.exit_latency = 20,
267171726   Len Brown   intel_idle: nativ...
184
185
186
187
  		.target_residency = 80,
  		.enter = &intel_idle },
  	{ /* MWAIT C3 */ },
  	{ /* MWAIT C4 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
188
  		.name = "C4-ATM",
267171726   Len Brown   intel_idle: nativ...
189
190
  		.desc = "MWAIT 0x30",
  		.driver_data = (void *) 0x30,
6110a1f43   Suresh Siddha   intel_idle: Volun...
191
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
267171726   Len Brown   intel_idle: nativ...
192
  		.exit_latency = 100,
267171726   Len Brown   intel_idle: nativ...
193
194
195
196
  		.target_residency = 400,
  		.enter = &intel_idle },
  	{ /* MWAIT C5 */ },
  	{ /* MWAIT C6 */
15e123e5d   Thomas Renninger   intel_idle: Renam...
197
  		.name = "C6-ATM",
7fcca7d90   Len Brown   intel_idle: enabl...
198
199
  		.desc = "MWAIT 0x52",
  		.driver_data = (void *) 0x52,
6110a1f43   Suresh Siddha   intel_idle: Volun...
200
  		.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
7fcca7d90   Len Brown   intel_idle: enabl...
201
  		.exit_latency = 140,
7fcca7d90   Len Brown   intel_idle: enabl...
202
203
  		.target_residency = 560,
  		.enter = &intel_idle },
267171726   Len Brown   intel_idle: nativ...
204
  };
267171726   Len Brown   intel_idle: nativ...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  /**
   * intel_idle
   * @dev: cpuidle_device
   * @state: cpuidle state
   *
   */
  static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
  {
  	unsigned long ecx = 1; /* break on interrupt flag */
  	unsigned long eax = (unsigned long)cpuidle_get_statedata(state);
  	unsigned int cstate;
  	ktime_t kt_before, kt_after;
  	s64 usec_delta;
  	int cpu = smp_processor_id();
  
  	cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
267171726   Len Brown   intel_idle: nativ...
221
  	local_irq_disable();
6110a1f43   Suresh Siddha   intel_idle: Volun...
222
  	/*
c8381cc3d   Len Brown   intel_idle: simpl...
223
224
  	 * leave_mm() to avoid costly and often unnecessary wakeups
  	 * for flushing the user TLB's associated with the active mm.
6110a1f43   Suresh Siddha   intel_idle: Volun...
225
  	 */
c8381cc3d   Len Brown   intel_idle: simpl...
226
  	if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
6110a1f43   Suresh Siddha   intel_idle: Volun...
227
  		leave_mm(cpu);
267171726   Len Brown   intel_idle: nativ...
228
229
230
231
232
233
  	if (!(lapic_timer_reliable_states & (1 << (cstate))))
  		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
  
  	kt_before = ktime_get_real();
  
  	stop_critical_timings();
267171726   Len Brown   intel_idle: nativ...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  	if (!need_resched()) {
  
  		__monitor((void *)&current_thread_info()->flags, 0, 0);
  		smp_mb();
  		if (!need_resched())
  			__mwait(eax, ecx);
  	}
  
  	start_critical_timings();
  
  	kt_after = ktime_get_real();
  	usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
  
  	local_irq_enable();
  
  	if (!(lapic_timer_reliable_states & (1 << (cstate))))
  		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
  
  	return usec_delta;
  }
2a2d31c8d   Shaohua Li   intel_idle: open ...
254
255
256
257
258
259
260
261
262
263
  static void __setup_broadcast_timer(void *arg)
  {
  	unsigned long reason = (unsigned long)arg;
  	int cpu = smp_processor_id();
  
  	reason = reason ?
  		CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
  
  	clockevents_notify(reason, &cpu);
  }
ec30f343d   Shaohua Li   fix a shutdown re...
264
  static int setup_broadcast_cpuhp_notify(struct notifier_block *n,
2a2d31c8d   Shaohua Li   intel_idle: open ...
265
266
267
268
269
270
271
272
273
  		unsigned long action, void *hcpu)
  {
  	int hotcpu = (unsigned long)hcpu;
  
  	switch (action & 0xf) {
  	case CPU_ONLINE:
  		smp_call_function_single(hotcpu, __setup_broadcast_timer,
  			(void *)true, 1);
  		break;
2a2d31c8d   Shaohua Li   intel_idle: open ...
274
275
276
  	}
  	return NOTIFY_OK;
  }
ec30f343d   Shaohua Li   fix a shutdown re...
277
  static struct notifier_block setup_broadcast_notifier = {
2a2d31c8d   Shaohua Li   intel_idle: open ...
278
279
  	.notifier_call = setup_broadcast_cpuhp_notify,
  };
14796fca2   Len Brown   intel_idle: disab...
280
281
282
283
284
285
286
287
  static void auto_demotion_disable(void *dummy)
  {
  	unsigned long long msr_bits;
  
  	rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
  	msr_bits &= ~auto_demotion_disable_flags;
  	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
  }
267171726   Len Brown   intel_idle: nativ...
288
289
290
291
292
  /*
   * intel_idle_probe()
   */
  static int intel_idle_probe(void)
  {
c4236282e   Len Brown   intel_idle: delet...
293
  	unsigned int eax, ebx, ecx;
267171726   Len Brown   intel_idle: nativ...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  
  	if (max_cstate == 0) {
  		pr_debug(PREFIX "disabled
  ");
  		return -EPERM;
  	}
  
  	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
  		return -ENODEV;
  
  	if (!boot_cpu_has(X86_FEATURE_MWAIT))
  		return -ENODEV;
  
  	if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
  		return -ENODEV;
c4236282e   Len Brown   intel_idle: delet...
309
  	cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
267171726   Len Brown   intel_idle: nativ...
310
311
312
313
  
  	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
  		!(ecx & CPUID5_ECX_INTERRUPT_BREAK))
  			return -ENODEV;
267171726   Len Brown   intel_idle: nativ...
314

c4236282e   Len Brown   intel_idle: delet...
315
316
  	pr_debug(PREFIX "MWAIT substates: 0x%x
  ", mwait_substates);
267171726   Len Brown   intel_idle: nativ...
317

267171726   Len Brown   intel_idle: nativ...
318
319
320
321
322
323
324
325
326
327
  
  	if (boot_cpu_data.x86 != 6)	/* family 6 */
  		return -ENODEV;
  
  	switch (boot_cpu_data.x86_model) {
  
  	case 0x1A:	/* Core i7, Xeon 5500 series */
  	case 0x1E:	/* Core i7 and i5 Processor - Lynnfield Jasper Forest */
  	case 0x1F:	/* Core i7 and i5 Processor - Nehalem */
  	case 0x2E:	/* Nehalem-EX Xeon */
ec67a2ba3   Len Brown   intel_idle: add s...
328
  	case 0x2F:	/* Westmere-EX Xeon */
267171726   Len Brown   intel_idle: nativ...
329
330
331
  	case 0x25:	/* Westmere */
  	case 0x2C:	/* Westmere */
  		cpuidle_state_table = nehalem_cstates;
14796fca2   Len Brown   intel_idle: disab...
332
333
  		auto_demotion_disable_flags =
  			(NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
267171726   Len Brown   intel_idle: nativ...
334
335
336
  		break;
  
  	case 0x1C:	/* 28 - Atom Processor */
bfb53ccf1   Len Brown   intel_idle: disab...
337
338
  		cpuidle_state_table = atom_cstates;
  		break;
4725fd3ce   Arjan van de Ven   intel_idle: recog...
339
  	case 0x26:	/* 38 - Lincroft Atom Processor */
267171726   Len Brown   intel_idle: nativ...
340
  		cpuidle_state_table = atom_cstates;
bfb53ccf1   Len Brown   intel_idle: disab...
341
  		auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
267171726   Len Brown   intel_idle: nativ...
342
  		break;
d13780d43   Len Brown   intel_idle: add i...
343
344
345
346
  
  	case 0x2A:	/* SNB */
  	case 0x2D:	/* SNB Xeon */
  		cpuidle_state_table = snb_cstates;
d13780d43   Len Brown   intel_idle: add i...
347
  		break;
267171726   Len Brown   intel_idle: nativ...
348
349
350
351
352
353
354
  
  	default:
  		pr_debug(PREFIX "does not run on family %d model %d
  ",
  			boot_cpu_data.x86, boot_cpu_data.x86_model);
  		return -ENODEV;
  	}
56b9aea3b   Len Brown   intel_idle: recog...
355
  	if (boot_cpu_has(X86_FEATURE_ARAT))	/* Always Reliable APIC Timer */
2a2d31c8d   Shaohua Li   intel_idle: open ...
356
357
358
359
360
  		lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
  	else {
  		smp_call_function(__setup_broadcast_timer, (void *)true, 1);
  		register_cpu_notifier(&setup_broadcast_notifier);
  	}
56b9aea3b   Len Brown   intel_idle: recog...
361

267171726   Len Brown   intel_idle: nativ...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
  	pr_debug(PREFIX "v" INTEL_IDLE_VERSION
  		" model 0x%X
  ", boot_cpu_data.x86_model);
  
  	pr_debug(PREFIX "lapic_timer_reliable_states 0x%x
  ",
  		lapic_timer_reliable_states);
  	return 0;
  }
  
  /*
   * intel_idle_cpuidle_devices_uninit()
   * unregister, free cpuidle_devices
   */
  static void intel_idle_cpuidle_devices_uninit(void)
  {
  	int i;
  	struct cpuidle_device *dev;
  
  	for_each_online_cpu(i) {
  		dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
  		cpuidle_unregister_device(dev);
  	}
  
  	free_percpu(intel_idle_cpuidle_devices);
  	return;
  }
  /*
   * intel_idle_cpuidle_devices_init()
   * allocate, initialize, register cpuidle_devices
   */
  static int intel_idle_cpuidle_devices_init(void)
  {
  	int i, cstate;
  	struct cpuidle_device *dev;
  
  	intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
  	if (intel_idle_cpuidle_devices == NULL)
  		return -ENOMEM;
  
  	for_each_online_cpu(i) {
  		dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
  
  		dev->state_count = 1;
  
  		for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) {
  			int num_substates;
  
  			if (cstate > max_cstate) {
  				printk(PREFIX "max_cstate %d reached
  ",
  					max_cstate);
  				break;
  			}
  
  			/* does the state exist in CPUID.MWAIT? */
c4236282e   Len Brown   intel_idle: delet...
418
  			num_substates = (mwait_substates >> ((cstate) * 4))
267171726   Len Brown   intel_idle: nativ...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  						& MWAIT_SUBSTATE_MASK;
  			if (num_substates == 0)
  				continue;
  			/* is the state not enabled? */
  			if (cpuidle_state_table[cstate].enter == NULL) {
  				/* does the driver not know about the state? */
  				if (*cpuidle_state_table[cstate].name == '\0')
  					pr_debug(PREFIX "unaware of model 0x%x"
  						" MWAIT %d please"
  						" contact lenb@kernel.org",
  					boot_cpu_data.x86_model, cstate);
  				continue;
  			}
  
  			if ((cstate > 2) &&
  				!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
  				mark_tsc_unstable("TSC halts in idle"
  					" states deeper than C2");
  
  			dev->states[dev->state_count] =	/* structure copy */
  				cpuidle_state_table[cstate];
  
  			dev->state_count += 1;
  		}
  
  		dev->cpu = i;
  		if (cpuidle_register_device(dev)) {
  			pr_debug(PREFIX "cpuidle_register_device %d failed!
  ",
  				 i);
  			intel_idle_cpuidle_devices_uninit();
  			return -EIO;
  		}
  	}
14796fca2   Len Brown   intel_idle: disab...
453
454
  	if (auto_demotion_disable_flags)
  		smp_call_function(auto_demotion_disable, NULL, 1);
267171726   Len Brown   intel_idle: nativ...
455
456
457
458
459
460
461
462
  
  	return 0;
  }
  
  
  static int __init intel_idle_init(void)
  {
  	int retval;
d18960494   Thomas Renninger   ACPI, intel_idle:...
463
464
465
  	/* Do not load intel_idle at all for now if idle= is passed */
  	if (boot_option_idle_override != IDLE_NO_OVERRIDE)
  		return -ENODEV;
267171726   Len Brown   intel_idle: nativ...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
  	retval = intel_idle_probe();
  	if (retval)
  		return retval;
  
  	retval = cpuidle_register_driver(&intel_idle_driver);
  	if (retval) {
  		printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
  			cpuidle_get_driver()->name);
  		return retval;
  	}
  
  	retval = intel_idle_cpuidle_devices_init();
  	if (retval) {
  		cpuidle_unregister_driver(&intel_idle_driver);
  		return retval;
  	}
  
  	return 0;
  }
  
  static void __exit intel_idle_exit(void)
  {
  	intel_idle_cpuidle_devices_uninit();
  	cpuidle_unregister_driver(&intel_idle_driver);
2a2d31c8d   Shaohua Li   intel_idle: open ...
490
491
492
493
  	if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) {
  		smp_call_function(__setup_broadcast_timer, (void *)false, 1);
  		unregister_cpu_notifier(&setup_broadcast_notifier);
  	}
267171726   Len Brown   intel_idle: nativ...
494
495
496
497
498
  	return;
  }
  
  module_init(intel_idle_init);
  module_exit(intel_idle_exit);
267171726   Len Brown   intel_idle: nativ...
499
  module_param(max_cstate, int, 0444);
267171726   Len Brown   intel_idle: nativ...
500
501
502
503
  
  MODULE_AUTHOR("Len Brown <len.brown@intel.com>");
  MODULE_DESCRIPTION("Cpuidle driver for Intel Hardware v" INTEL_IDLE_VERSION);
  MODULE_LICENSE("GPL");