Blame view

drivers/cpufreq/speedstep-smi.c 9.51 KB
4f19048fd   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   * Intel SpeedStep SMI driver.
   *
   * (C) 2003  Hiroshi Miura <miura@da-cha.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
   */
  
  
  /*********************************************************************
   *                        SPEEDSTEP - DEFINITIONS                    *
   *********************************************************************/
1c5864e26   Joe Perches   cpufreq: Use cons...
12
  #define pr_fmt(fmt) "cpufreq: " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
  #include <linux/kernel.h>
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
14
15
  #include <linux/module.h>
  #include <linux/moduleparam.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
  #include <linux/init.h>
  #include <linux/cpufreq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #include <linux/delay.h>
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
19
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include <asm/ist.h>
fa8031aef   Andi Kleen   cpufreq: Add supp...
21
  #include <asm/cpu_device_id.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
26
27
28
  
  #include "speedstep-lib.h"
  
  /* speedstep system management interface port/command.
   *
   * These parameters are got from IST-SMI BIOS call.
   * If user gives it, these are used.
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
29
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
   */
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
31
32
33
  static int smi_port;
  static int smi_cmd;
  static unsigned int smi_sig;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
  
  /* info about the processor */
1cce76c2a   Rusty Russell   [CPUFREQ] use an ...
36
  static enum speedstep_processor speedstep_processor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
38
39
  /*
   * There are only two frequency states for each processor. Values
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
   * are in kHz for the time being.
   */
  static struct cpufreq_frequency_table speedstep_freqs[] = {
7f4b04614   Viresh Kumar   cpufreq: create a...
43
44
45
  	{0, SPEEDSTEP_HIGH,	0},
  	{0, SPEEDSTEP_LOW,	0},
  	{0, 0,			CPUFREQ_TABLE_END},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
55
  };
  
  #define GET_SPEEDSTEP_OWNER 0
  #define GET_SPEEDSTEP_STATE 1
  #define SET_SPEEDSTEP_STATE 2
  #define GET_SPEEDSTEP_FREQS 4
  
  /* how often shall the SMI call be tried if it failed, e.g. because
   * of DMA activity going on? */
  #define SMI_TRIES 5
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  /**
   * speedstep_smi_ownership
   */
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
59
  static int speedstep_smi_ownership(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  {
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
61
  	u32 command, result, magic, dummy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
65
66
  	u32 function = GET_SPEEDSTEP_OWNER;
  	unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
  
  	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
  	magic = virt_to_phys(magic_data);
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
67
68
  	pr_debug("trying to obtain ownership with command %x at port %x
  ",
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
69
  			command, smi_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  
  	__asm__ __volatile__(
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
72
73
  		"push %%ebp
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
  		"out %%al, (%%dx)
  "
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
76
77
  		"pop %%ebp
  "
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
78
79
80
  		: "=D" (result),
  		  "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
  		  "=S" (dummy)
f081a529f   Andrew Morton   [PATCH] cpufreq: ...
81
  		: "a" (command), "b" (function), "c" (0), "d" (smi_port),
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
82
  		  "D" (0), "S" (magic)
f081a529f   Andrew Morton   [PATCH] cpufreq: ...
83
  		: "memory"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	);
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
85
86
  	pr_debug("result is %x
  ", result);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
92
93
94
95
96
97
98
99
  
  	return result;
  }
  
  /**
   * speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
   * @low: the low frequency value is placed here
   * @high: the high frequency value is placed here
   *
   * Only available on later SpeedStep-enabled systems, returns false results or
   * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
   * shows that the latter occurs if !(ist_info.event & 0xFFFF).
   */
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
100
  static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  {
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
102
  	u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
103
  	u32 state = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
  	u32 function = GET_SPEEDSTEP_FREQS;
  
  	if (!(ist_info.event & 0xFFFF)) {
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
107
108
  		pr_debug("bug #1422 -- can't read freqs from BIOS
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
  		return -ENODEV;
  	}
  
  	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
113
114
  	pr_debug("trying to determine frequencies with command %x at port %x
  ",
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
115
  			command, smi_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116

c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
117
118
119
  	__asm__ __volatile__(
  		"push %%ebp
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  		"out %%al, (%%dx)
  "
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
122
  		"pop %%ebp"
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
123
124
125
126
127
128
129
130
  		: "=a" (result),
  		  "=b" (high_mhz),
  		  "=c" (low_mhz),
  		  "=d" (state), "=D" (edi), "=S" (dummy)
  		: "a" (command),
  		  "b" (function),
  		  "c" (state),
  		  "d" (smi_port), "S" (0), "D" (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  	);
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
132
133
  	pr_debug("result %x, low_freq %u, high_freq %u
  ",
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
134
  			result, low_mhz, high_mhz);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
138
139
140
141
142
143
  
  	/* abort if results are obviously incorrect... */
  	if ((high_mhz + low_mhz) < 600)
  		return -EINVAL;
  
  	*high = high_mhz * 1000;
  	*low  = low_mhz  * 1000;
  
  	return result;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
144
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
   * speedstep_set_state - set the SpeedStep state
   * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
   *
   */
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
151
  static void speedstep_set_state(unsigned int state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  {
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
153
  	unsigned int result = 0, command, new_state, dummy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  	unsigned long flags;
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
155
  	unsigned int function = SET_SPEEDSTEP_STATE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
  	unsigned int retry = 0;
  
  	if (state > 0x1)
  		return;
  
  	/* Disable IRQs */
d4d4eda23   Mikulas Patocka   cpufreq: speedste...
162
  	preempt_disable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
165
  	local_irq_save(flags);
  
  	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
166
  	pr_debug("trying to set frequency to state %u "
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
167
168
169
  		"with command %x at port %x
  ",
  		state, command, smi_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
  
  	do {
  		if (retry) {
d4d4eda23   Mikulas Patocka   cpufreq: speedste...
173
174
175
176
177
178
179
180
  			/*
  			 * We need to enable interrupts, otherwise the blockage
  			 * won't resolve.
  			 *
  			 * We disable preemption so that other processes don't
  			 * run. If other processes were running, they could
  			 * submit more DMA requests, making the blockage worse.
  			 */
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
181
182
  			pr_debug("retry %u, previous result %u, waiting...
  ",
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
183
  					retry, result);
d4d4eda23   Mikulas Patocka   cpufreq: speedste...
184
  			local_irq_enable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
  			mdelay(retry * 50);
d4d4eda23   Mikulas Patocka   cpufreq: speedste...
186
  			local_irq_disable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
  		}
  		retry++;
  		__asm__ __volatile__(
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
190
191
  			"push %%ebp
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
  			"out %%al, (%%dx)
  "
c6e8256a7   Stephan Diestelhorst   x86, cpufreq: fix...
194
  			"pop %%ebp"
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
195
196
197
198
199
  			: "=b" (new_state), "=D" (result),
  			  "=c" (dummy), "=a" (dummy),
  			  "=d" (dummy), "=S" (dummy)
  			: "a" (command), "b" (function), "c" (state),
  			  "d" (smi_port), "S" (0), "D" (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
  			);
  	} while ((new_state != state) && (retry <= SMI_TRIES));
  
  	/* enable IRQs */
  	local_irq_restore(flags);
d4d4eda23   Mikulas Patocka   cpufreq: speedste...
205
  	preempt_enable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206

bbfebd665   Dave Jones   [CPUFREQ] checkpa...
207
  	if (new_state == state)
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
208
  		pr_debug("change to %u MHz succeeded after %u tries "
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
209
210
211
212
213
  			"with result %u
  ",
  			(speedstep_freqs[new_state].frequency / 1000),
  			retry, result);
  	else
1c5864e26   Joe Perches   cpufreq: Use cons...
214
215
  		pr_err("change to state %u failed with new_state %u and result %u
  ",
b49c22a6c   Joe Perches   cpufreq: Convert ...
216
  		       state, new_state, result);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
222
223
224
  
  	return;
  }
  
  
  /**
   * speedstep_target - set a new CPUFreq policy
   * @policy: new policy
9c0ebcf78   Viresh Kumar   cpufreq: Implemen...
225
   * @index: index of new freq
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
228
   *
   * Sets a new CPUFreq policy/freq.
   */
9c0ebcf78   Viresh Kumar   cpufreq: Implemen...
229
  static int speedstep_target(struct cpufreq_policy *policy, unsigned int index)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
  {
9c0ebcf78   Viresh Kumar   cpufreq: Implemen...
231
  	speedstep_set_state(index);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
233
234
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
  static int speedstep_cpu_init(struct cpufreq_policy *policy)
  {
  	int result;
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
238
  	unsigned int *low, *high;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
241
242
243
244
245
  
  	/* capability check */
  	if (policy->cpu != 0)
  		return -ENODEV;
  
  	result = speedstep_smi_ownership();
  	if (result) {
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
246
247
  		pr_debug("fails in acquiring ownership of a SMI interface.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
250
251
  		return -EINVAL;
  	}
  
  	/* detect low and high frequency */
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
252
253
254
255
  	low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
  	high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
  
  	result = speedstep_smi_get_freqs(low, high);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	if (result) {
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
257
258
  		/* fall back to speedstep_lib.c dection mechanism:
  		 * try both states out */
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
259
  		pr_debug("could not detect low and high frequencies "
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
260
261
  				"by SMI call.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  		result = speedstep_get_freqs(speedstep_processor,
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
263
  				low, high,
1a10760c9   Mattia Dongili   [CPUFREQ] Measure...
264
  				NULL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
  				&speedstep_set_state);
  
  		if (result) {
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
268
  			pr_debug("could not detect two different speeds"
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
269
270
  					" -- aborting.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
  			return result;
  		} else
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
273
274
  			pr_debug("workaround worked.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  	}
2d28b0368   Viresh Kumar   cpufreq: speedste...
276
277
278
  	policy->freq_table = speedstep_freqs;
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
282
283
  static unsigned int speedstep_get(unsigned int cpu)
  {
  	if (cpu)
  		return -ENODEV;
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
284
  	return speedstep_get_frequency(speedstep_processor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
290
291
292
  }
  
  
  static int speedstep_resume(struct cpufreq_policy *policy)
  {
  	int result = speedstep_smi_ownership();
  
  	if (result)
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
293
294
  		pr_debug("fails in re-acquiring ownership of a SMI interface.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
296
297
  
  	return result;
  }
221dee285   Linus Torvalds   Revert "[CPUFREQ]...
298
  static struct cpufreq_driver speedstep_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  	.name		= "speedstep-smi",
fe829ed8e   Viresh Kumar   cpufreq: Add CPUF...
300
  	.flags		= CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
3be1394a6   Viresh Kumar   cpufreq: speedste...
301
  	.verify		= cpufreq_generic_frequency_table_verify,
9c0ebcf78   Viresh Kumar   cpufreq: Implemen...
302
  	.target_index	= speedstep_target,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	.init		= speedstep_cpu_init,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
  	.get		= speedstep_get,
  	.resume		= speedstep_resume,
3be1394a6   Viresh Kumar   cpufreq: speedste...
306
  	.attr		= cpufreq_generic_attr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  };
fa8031aef   Andi Kleen   cpufreq: Add supp...
308
  static const struct x86_cpu_id ss_smi_ids[] = {
b11d77fa3   Thomas Gleixner   cpufreq: Convert ...
309
310
311
  	X86_MATCH_VENDOR_FAM_MODEL(INTEL,  6, 0x8, 0),
  	X86_MATCH_VENDOR_FAM_MODEL(INTEL,  6, 0xb, 0),
  	X86_MATCH_VENDOR_FAM_MODEL(INTEL, 15, 0x2, 0),
fa8031aef   Andi Kleen   cpufreq: Add supp...
312
313
  	{}
  };
fa8031aef   Andi Kleen   cpufreq: Add supp...
314

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
318
319
320
321
322
323
  /**
   * speedstep_init - initializes the SpeedStep CPUFreq driver
   *
   *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
   * BIOS, -EINVAL on problems during initiatization, and zero on
   * success.
   */
  static int __init speedstep_init(void)
  {
fa8031aef   Andi Kleen   cpufreq: Add supp...
324
325
  	if (!x86_match_cpu(ss_smi_ids))
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
328
  	speedstep_processor = speedstep_detect_processor();
  
  	switch (speedstep_processor) {
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
329
330
331
  	case SPEEDSTEP_CPU_PIII_T:
  	case SPEEDSTEP_CPU_PIII_C:
  	case SPEEDSTEP_CPU_PIII_C_EARLY:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
334
335
336
337
  		break;
  	default:
  		speedstep_processor = 0;
  	}
  
  	if (!speedstep_processor) {
2d06d8c49   Dominik Brodowski   [CPUFREQ] use dyn...
338
339
  		pr_debug("No supported Intel CPU detected.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
  		return -ENODEV;
  	}
a5f30eba7   Hans Wennborg   cpufreq: speedste...
342
343
344
  	pr_debug("signature:0x%.8x, command:0x%.8x, "
  		"event:0x%.8x, perf_level:0x%.8x.
  ",
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
345
346
  		ist_info.signature, ist_info.command,
  		ist_info.event, ist_info.perf_level);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347

32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
348
  	/* Error if no IST-SMI BIOS or no PARM
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
  		 sig= 'ISGE' aka 'Intel Speedstep Gate E' */
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
350
  	if ((ist_info.signature !=  0x47534943) && (
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
354
355
356
357
358
359
  	    (smi_port == 0) || (smi_cmd == 0)))
  		return -ENODEV;
  
  	if (smi_sig == 1)
  		smi_sig = 0x47534943;
  	else
  		smi_sig = ist_info.signature;
  
  	/* setup smi_port from MODLULE_PARM or BIOS */
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
360
  	if ((smi_port > 0xff) || (smi_port < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  		return -EINVAL;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
362
  	else if (smi_port == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
  		smi_port = ist_info.command & 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
365
  	if ((smi_cmd > 0xff) || (smi_cmd < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  		return -EINVAL;
32ee8c3e4   Dave Jones   [CPUFREQ] Lots of...
367
  	else if (smi_cmd == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
  		smi_cmd = (ist_info.command >> 16) & 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
372
373
374
375
376
377
378
379
380
381
382
  
  	return cpufreq_register_driver(&speedstep_driver);
  }
  
  
  /**
   * speedstep_exit - unregisters SpeedStep support
   *
   *   Unregisters SpeedStep support.
   */
  static void __exit speedstep_exit(void)
  {
  	cpufreq_unregister_driver(&speedstep_driver);
  }
40059ec67   David Howells   Annotate hardware...
383
  module_param_hw(smi_port, int, ioport, 0444);
bbfebd665   Dave Jones   [CPUFREQ] checkpa...
384
385
  module_param(smi_cmd,  int, 0444);
  module_param(smi_sig, uint, 0444);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386

bbfebd665   Dave Jones   [CPUFREQ] checkpa...
387
388
389
390
391
392
  MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value "
  		"-- Intel's default setting is 0xb2");
  MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value "
  		"-- Intel's default setting is 0x82");
  MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the "
  		"SMI interface.");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393

bbfebd665   Dave Jones   [CPUFREQ] checkpa...
394
395
396
  MODULE_AUTHOR("Hiroshi Miura");
  MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
  MODULE_LICENSE("GPL");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
  
  module_init(speedstep_init);
  module_exit(speedstep_exit);