aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-09-27 14:57:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-27 14:57:54 -0400
commit2dc94310bd94d0906febea7d0f7c188da620c952 (patch)
tree6de4096f1887e2c00966177354b1c378e59bd632 /arch/i386
parentc06015148fa9a3cc452ec7121b8c3f59f4a7d6ac (diff)
parentfb60cf4ab52f3520c2119aa42f7d4ed8e7594eb6 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/tmlind/linux-omap-upstream into devel
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/crypto/Makefile3
-rw-r--r--arch/i386/crypto/aes.c3
-rw-r--r--arch/i386/crypto/twofish-i586-asm.S335
-rw-r--r--arch/i386/crypto/twofish.c97
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c39
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c186
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.h48
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c42
8 files changed, 677 insertions, 76 deletions
diff --git a/arch/i386/crypto/Makefile b/arch/i386/crypto/Makefile
index 103c353d0a63..3fd19af18e34 100644
--- a/arch/i386/crypto/Makefile
+++ b/arch/i386/crypto/Makefile
@@ -5,5 +5,8 @@
5# 5#
6 6
7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o 7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
8obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
8 9
9aes-i586-y := aes-i586-asm.o aes.o 10aes-i586-y := aes-i586-asm.o aes.o
11twofish-i586-y := twofish-i586-asm.o twofish.o
12
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
index d3806daa3de3..49aad9397f10 100644
--- a/arch/i386/crypto/aes.c
+++ b/arch/i386/crypto/aes.c
@@ -379,12 +379,13 @@ static void gen_tabs(void)
379} 379}
380 380
381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
382 unsigned int key_len, u32 *flags) 382 unsigned int key_len)
383{ 383{
384 int i; 384 int i;
385 u32 ss[8]; 385 u32 ss[8];
386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
387 const __le32 *key = (const __le32 *)in_key; 387 const __le32 *key = (const __le32 *)in_key;
388 u32 *flags = &tfm->crt_flags;
388 389
389 /* encryption schedule */ 390 /* encryption schedule */
390 391
diff --git a/arch/i386/crypto/twofish-i586-asm.S b/arch/i386/crypto/twofish-i586-asm.S
new file mode 100644
index 000000000000..39b98ed2c1b9
--- /dev/null
+++ b/arch/i386/crypto/twofish-i586-asm.S
@@ -0,0 +1,335 @@
1/***************************************************************************
2* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
3* *
4* This program is free software; you can redistribute it and/or modify *
5* it under the terms of the GNU General Public License as published by *
6* the Free Software Foundation; either version 2 of the License, or *
7* (at your option) any later version. *
8* *
9* This program is distributed in the hope that it will be useful, *
10* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12* GNU General Public License for more details. *
13* *
14* You should have received a copy of the GNU General Public License *
15* along with this program; if not, write to the *
16* Free Software Foundation, Inc., *
17* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18***************************************************************************/
19
20.file "twofish-i586-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25/* return adress at 0 */
26
27#define in_blk 12 /* input byte array address parameter*/
28#define out_blk 8 /* output byte array address parameter*/
29#define tfm 4 /* Twofish context structure */
30
31#define a_offset 0
32#define b_offset 4
33#define c_offset 8
34#define d_offset 12
35
36/* Structure of the crypto context struct*/
37
38#define s0 0 /* S0 Array 256 Words each */
39#define s1 1024 /* S1 Array */
40#define s2 2048 /* S2 Array */
41#define s3 3072 /* S3 Array */
42#define w 4096 /* 8 whitening keys (word) */
43#define k 4128 /* key 1-32 ( word ) */
44
45/* define a few register aliases to allow macro substitution */
46
47#define R0D %eax
48#define R0B %al
49#define R0H %ah
50
51#define R1D %ebx
52#define R1B %bl
53#define R1H %bh
54
55#define R2D %ecx
56#define R2B %cl
57#define R2H %ch
58
59#define R3D %edx
60#define R3B %dl
61#define R3H %dh
62
63
64/* performs input whitening */
65#define input_whitening(src,context,offset)\
66 xor w+offset(context), src;
67
68/* performs input whitening */
69#define output_whitening(src,context,offset)\
70 xor w+16+offset(context), src;
71
72/*
73 * a input register containing a (rotated 16)
74 * b input register containing b
75 * c input register containing c
76 * d input register containing d (already rol $1)
77 * operations on a and b are interleaved to increase performance
78 */
79#define encrypt_round(a,b,c,d,round)\
80 push d ## D;\
81 movzx b ## B, %edi;\
82 mov s1(%ebp,%edi,4),d ## D;\
83 movzx a ## B, %edi;\
84 mov s2(%ebp,%edi,4),%esi;\
85 movzx b ## H, %edi;\
86 ror $16, b ## D;\
87 xor s2(%ebp,%edi,4),d ## D;\
88 movzx a ## H, %edi;\
89 ror $16, a ## D;\
90 xor s3(%ebp,%edi,4),%esi;\
91 movzx b ## B, %edi;\
92 xor s3(%ebp,%edi,4),d ## D;\
93 movzx a ## B, %edi;\
94 xor (%ebp,%edi,4), %esi;\
95 movzx b ## H, %edi;\
96 ror $15, b ## D;\
97 xor (%ebp,%edi,4), d ## D;\
98 movzx a ## H, %edi;\
99 xor s1(%ebp,%edi,4),%esi;\
100 pop %edi;\
101 add d ## D, %esi;\
102 add %esi, d ## D;\
103 add k+round(%ebp), %esi;\
104 xor %esi, c ## D;\
105 rol $15, c ## D;\
106 add k+4+round(%ebp),d ## D;\
107 xor %edi, d ## D;
108
109/*
110 * a input register containing a (rotated 16)
111 * b input register containing b
112 * c input register containing c
113 * d input register containing d (already rol $1)
114 * operations on a and b are interleaved to increase performance
115 * last round has different rotations for the output preparation
116 */
117#define encrypt_last_round(a,b,c,d,round)\
118 push d ## D;\
119 movzx b ## B, %edi;\
120 mov s1(%ebp,%edi,4),d ## D;\
121 movzx a ## B, %edi;\
122 mov s2(%ebp,%edi,4),%esi;\
123 movzx b ## H, %edi;\
124 ror $16, b ## D;\
125 xor s2(%ebp,%edi,4),d ## D;\
126 movzx a ## H, %edi;\
127 ror $16, a ## D;\
128 xor s3(%ebp,%edi,4),%esi;\
129 movzx b ## B, %edi;\
130 xor s3(%ebp,%edi,4),d ## D;\
131 movzx a ## B, %edi;\
132 xor (%ebp,%edi,4), %esi;\
133 movzx b ## H, %edi;\
134 ror $16, b ## D;\
135 xor (%ebp,%edi,4), d ## D;\
136 movzx a ## H, %edi;\
137 xor s1(%ebp,%edi,4),%esi;\
138 pop %edi;\
139 add d ## D, %esi;\
140 add %esi, d ## D;\
141 add k+round(%ebp), %esi;\
142 xor %esi, c ## D;\
143 ror $1, c ## D;\
144 add k+4+round(%ebp),d ## D;\
145 xor %edi, d ## D;
146
147/*
148 * a input register containing a
149 * b input register containing b (rotated 16)
150 * c input register containing c
151 * d input register containing d (already rol $1)
152 * operations on a and b are interleaved to increase performance
153 */
154#define decrypt_round(a,b,c,d,round)\
155 push c ## D;\
156 movzx a ## B, %edi;\
157 mov (%ebp,%edi,4), c ## D;\
158 movzx b ## B, %edi;\
159 mov s3(%ebp,%edi,4),%esi;\
160 movzx a ## H, %edi;\
161 ror $16, a ## D;\
162 xor s1(%ebp,%edi,4),c ## D;\
163 movzx b ## H, %edi;\
164 ror $16, b ## D;\
165 xor (%ebp,%edi,4), %esi;\
166 movzx a ## B, %edi;\
167 xor s2(%ebp,%edi,4),c ## D;\
168 movzx b ## B, %edi;\
169 xor s1(%ebp,%edi,4),%esi;\
170 movzx a ## H, %edi;\
171 ror $15, a ## D;\
172 xor s3(%ebp,%edi,4),c ## D;\
173 movzx b ## H, %edi;\
174 xor s2(%ebp,%edi,4),%esi;\
175 pop %edi;\
176 add %esi, c ## D;\
177 add c ## D, %esi;\
178 add k+round(%ebp), c ## D;\
179 xor %edi, c ## D;\
180 add k+4+round(%ebp),%esi;\
181 xor %esi, d ## D;\
182 rol $15, d ## D;
183
184/*
185 * a input register containing a
186 * b input register containing b (rotated 16)
187 * c input register containing c
188 * d input register containing d (already rol $1)
189 * operations on a and b are interleaved to increase performance
190 * last round has different rotations for the output preparation
191 */
192#define decrypt_last_round(a,b,c,d,round)\
193 push c ## D;\
194 movzx a ## B, %edi;\
195 mov (%ebp,%edi,4), c ## D;\
196 movzx b ## B, %edi;\
197 mov s3(%ebp,%edi,4),%esi;\
198 movzx a ## H, %edi;\
199 ror $16, a ## D;\
200 xor s1(%ebp,%edi,4),c ## D;\
201 movzx b ## H, %edi;\
202 ror $16, b ## D;\
203 xor (%ebp,%edi,4), %esi;\
204 movzx a ## B, %edi;\
205 xor s2(%ebp,%edi,4),c ## D;\
206 movzx b ## B, %edi;\
207 xor s1(%ebp,%edi,4),%esi;\
208 movzx a ## H, %edi;\
209 ror $16, a ## D;\
210 xor s3(%ebp,%edi,4),c ## D;\
211 movzx b ## H, %edi;\
212 xor s2(%ebp,%edi,4),%esi;\
213 pop %edi;\
214 add %esi, c ## D;\
215 add c ## D, %esi;\
216 add k+round(%ebp), c ## D;\
217 xor %edi, c ## D;\
218 add k+4+round(%ebp),%esi;\
219 xor %esi, d ## D;\
220 ror $1, d ## D;
221
222.align 4
223.global twofish_enc_blk
224.global twofish_dec_blk
225
226twofish_enc_blk:
227 push %ebp /* save registers according to calling convention*/
228 push %ebx
229 push %esi
230 push %edi
231
232 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
233 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
234 mov in_blk+16(%esp),%edi /* input adress in edi */
235
236 mov (%edi), %eax
237 mov b_offset(%edi), %ebx
238 mov c_offset(%edi), %ecx
239 mov d_offset(%edi), %edx
240 input_whitening(%eax,%ebp,a_offset)
241 ror $16, %eax
242 input_whitening(%ebx,%ebp,b_offset)
243 input_whitening(%ecx,%ebp,c_offset)
244 input_whitening(%edx,%ebp,d_offset)
245 rol $1, %edx
246
247 encrypt_round(R0,R1,R2,R3,0);
248 encrypt_round(R2,R3,R0,R1,8);
249 encrypt_round(R0,R1,R2,R3,2*8);
250 encrypt_round(R2,R3,R0,R1,3*8);
251 encrypt_round(R0,R1,R2,R3,4*8);
252 encrypt_round(R2,R3,R0,R1,5*8);
253 encrypt_round(R0,R1,R2,R3,6*8);
254 encrypt_round(R2,R3,R0,R1,7*8);
255 encrypt_round(R0,R1,R2,R3,8*8);
256 encrypt_round(R2,R3,R0,R1,9*8);
257 encrypt_round(R0,R1,R2,R3,10*8);
258 encrypt_round(R2,R3,R0,R1,11*8);
259 encrypt_round(R0,R1,R2,R3,12*8);
260 encrypt_round(R2,R3,R0,R1,13*8);
261 encrypt_round(R0,R1,R2,R3,14*8);
262 encrypt_last_round(R2,R3,R0,R1,15*8);
263
264 output_whitening(%eax,%ebp,c_offset)
265 output_whitening(%ebx,%ebp,d_offset)
266 output_whitening(%ecx,%ebp,a_offset)
267 output_whitening(%edx,%ebp,b_offset)
268 mov out_blk+16(%esp),%edi;
269 mov %eax, c_offset(%edi)
270 mov %ebx, d_offset(%edi)
271 mov %ecx, (%edi)
272 mov %edx, b_offset(%edi)
273
274 pop %edi
275 pop %esi
276 pop %ebx
277 pop %ebp
278 mov $1, %eax
279 ret
280
281twofish_dec_blk:
282 push %ebp /* save registers according to calling convention*/
283 push %ebx
284 push %esi
285 push %edi
286
287
288 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
289 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
290 mov in_blk+16(%esp),%edi /* input adress in edi */
291
292 mov (%edi), %eax
293 mov b_offset(%edi), %ebx
294 mov c_offset(%edi), %ecx
295 mov d_offset(%edi), %edx
296 output_whitening(%eax,%ebp,a_offset)
297 output_whitening(%ebx,%ebp,b_offset)
298 ror $16, %ebx
299 output_whitening(%ecx,%ebp,c_offset)
300 output_whitening(%edx,%ebp,d_offset)
301 rol $1, %ecx
302
303 decrypt_round(R0,R1,R2,R3,15*8);
304 decrypt_round(R2,R3,R0,R1,14*8);
305 decrypt_round(R0,R1,R2,R3,13*8);
306 decrypt_round(R2,R3,R0,R1,12*8);
307 decrypt_round(R0,R1,R2,R3,11*8);
308 decrypt_round(R2,R3,R0,R1,10*8);
309 decrypt_round(R0,R1,R2,R3,9*8);
310 decrypt_round(R2,R3,R0,R1,8*8);
311 decrypt_round(R0,R1,R2,R3,7*8);
312 decrypt_round(R2,R3,R0,R1,6*8);
313 decrypt_round(R0,R1,R2,R3,5*8);
314 decrypt_round(R2,R3,R0,R1,4*8);
315 decrypt_round(R0,R1,R2,R3,3*8);
316 decrypt_round(R2,R3,R0,R1,2*8);
317 decrypt_round(R0,R1,R2,R3,1*8);
318 decrypt_last_round(R2,R3,R0,R1,0);
319
320 input_whitening(%eax,%ebp,c_offset)
321 input_whitening(%ebx,%ebp,d_offset)
322 input_whitening(%ecx,%ebp,a_offset)
323 input_whitening(%edx,%ebp,b_offset)
324 mov out_blk+16(%esp),%edi;
325 mov %eax, c_offset(%edi)
326 mov %ebx, d_offset(%edi)
327 mov %ecx, (%edi)
328 mov %edx, b_offset(%edi)
329
330 pop %edi
331 pop %esi
332 pop %ebx
333 pop %ebp
334 mov $1, %eax
335 ret
diff --git a/arch/i386/crypto/twofish.c b/arch/i386/crypto/twofish.c
new file mode 100644
index 000000000000..e3004dfe9c7a
--- /dev/null
+++ b/arch/i386/crypto/twofish.c
@@ -0,0 +1,97 @@
1/*
2 * Glue Code for optimized 586 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/module.h>
45#include <linux/types.h>
46
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-i586",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
97MODULE_ALIAS("twofish");
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index e6ea00edcb54..ea19d091fd41 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -32,6 +32,7 @@
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/compiler.h> 33#include <linux/compiler.h>
34#include <linux/sched.h> /* current */ 34#include <linux/sched.h> /* current */
35#include <linux/dmi.h>
35#include <asm/io.h> 36#include <asm/io.h>
36#include <asm/delay.h> 37#include <asm/delay.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -387,6 +388,33 @@ static int acpi_cpufreq_early_init_acpi(void)
387 return acpi_processor_preregister_performance(acpi_perf_data); 388 return acpi_processor_preregister_performance(acpi_perf_data);
388} 389}
389 390
391/*
392 * Some BIOSes do SW_ANY coordination internally, either set it up in hw
393 * or do it in BIOS firmware and won't inform about it to OS. If not
394 * detected, this has a side effect of making CPU run at a different speed
395 * than OS intended it to run at. Detect it and handle it cleanly.
396 */
397static int bios_with_sw_any_bug;
398
399static int __init sw_any_bug_found(struct dmi_system_id *d)
400{
401 bios_with_sw_any_bug = 1;
402 return 0;
403}
404
405static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = {
406 {
407 .callback = sw_any_bug_found,
408 .ident = "Supermicro Server X6DLP",
409 .matches = {
410 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
411 DMI_MATCH(DMI_BIOS_VERSION, "080010"),
412 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
413 },
414 },
415 { }
416};
417
390static int 418static int
391acpi_cpufreq_cpu_init ( 419acpi_cpufreq_cpu_init (
392 struct cpufreq_policy *policy) 420 struct cpufreq_policy *policy)
@@ -422,8 +450,17 @@ acpi_cpufreq_cpu_init (
422 * coordination is required. 450 * coordination is required.
423 */ 451 */
424 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || 452 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
425 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) 453 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
426 policy->cpus = perf->shared_cpu_map; 454 policy->cpus = perf->shared_cpu_map;
455 }
456
457#ifdef CONFIG_SMP
458 dmi_check_system(sw_any_bug_dmi_table);
459 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
460 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
461 policy->cpus = cpu_core_map[cpu];
462 }
463#endif
427 464
428 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { 465 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
429 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; 466 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 4f2c3aeef724..f5cc9f5c9bab 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -27,6 +27,7 @@
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpufreq.h> 29#include <linux/cpufreq.h>
30#include <linux/pci.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/string.h> 32#include <linux/string.h>
32 33
@@ -52,18 +53,26 @@
52#define CPU_NEHEMIAH 5 53#define CPU_NEHEMIAH 5
53 54
54static int cpu_model; 55static int cpu_model;
55static unsigned int numscales=16, numvscales; 56static unsigned int numscales=16;
56static unsigned int fsb; 57static unsigned int fsb;
57static int minvid, maxvid; 58
59static struct mV_pos *vrm_mV_table;
60static unsigned char *mV_vrm_table;
61struct f_msr {
62 unsigned char vrm;
63};
64static struct f_msr f_msr_table[32];
65
66static unsigned int highest_speed, lowest_speed; /* kHz */
58static unsigned int minmult, maxmult; 67static unsigned int minmult, maxmult;
59static int can_scale_voltage; 68static int can_scale_voltage;
60static int vrmrev;
61static struct acpi_processor *pr = NULL; 69static struct acpi_processor *pr = NULL;
62static struct acpi_processor_cx *cx = NULL; 70static struct acpi_processor_cx *cx = NULL;
71static int port22_en;
63 72
64/* Module parameters */ 73/* Module parameters */
65static int dont_scale_voltage; 74static int scale_voltage;
66 75static int ignore_latency;
67 76
68#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) 77#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
69 78
@@ -71,7 +80,6 @@ static int dont_scale_voltage;
71/* Clock ratios multiplied by 10 */ 80/* Clock ratios multiplied by 10 */
72static int clock_ratio[32]; 81static int clock_ratio[32];
73static int eblcr_table[32]; 82static int eblcr_table[32];
74static int voltage_table[32];
75static unsigned int highest_speed, lowest_speed; /* kHz */ 83static unsigned int highest_speed, lowest_speed; /* kHz */
76static int longhaul_version; 84static int longhaul_version;
77static struct cpufreq_frequency_table *longhaul_table; 85static struct cpufreq_frequency_table *longhaul_table;
@@ -124,10 +132,9 @@ static int longhaul_get_cpu_mult(void)
124 132
125/* For processor with BCR2 MSR */ 133/* For processor with BCR2 MSR */
126 134
127static void do_longhaul1(int cx_address, unsigned int clock_ratio_index) 135static void do_longhaul1(unsigned int clock_ratio_index)
128{ 136{
129 union msr_bcr2 bcr2; 137 union msr_bcr2 bcr2;
130 u32 t;
131 138
132 rdmsrl(MSR_VIA_BCR2, bcr2.val); 139 rdmsrl(MSR_VIA_BCR2, bcr2.val);
133 /* Enable software clock multiplier */ 140 /* Enable software clock multiplier */
@@ -136,13 +143,11 @@ static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
136 143
137 /* Sync to timer tick */ 144 /* Sync to timer tick */
138 safe_halt(); 145 safe_halt();
139 ACPI_FLUSH_CPU_CACHE();
140 /* Change frequency on next halt or sleep */ 146 /* Change frequency on next halt or sleep */
141 wrmsrl(MSR_VIA_BCR2, bcr2.val); 147 wrmsrl(MSR_VIA_BCR2, bcr2.val);
142 /* Invoke C3 */ 148 /* Invoke transition */
143 inb(cx_address); 149 ACPI_FLUSH_CPU_CACHE();
144 /* Dummy op - must do something useless after P_LVL3 read */ 150 halt();
145 t = inl(acpi_fadt.xpm_tmr_blk.address);
146 151
147 /* Disable software clock multiplier */ 152 /* Disable software clock multiplier */
148 local_irq_disable(); 153 local_irq_disable();
@@ -164,11 +169,16 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
164 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 169 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
165 longhaul.bits.EnableSoftBusRatio = 1; 170 longhaul.bits.EnableSoftBusRatio = 1;
166 171
172 if (can_scale_voltage) {
173 longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm;
174 longhaul.bits.EnableSoftVID = 1;
175 }
176
167 /* Sync to timer tick */ 177 /* Sync to timer tick */
168 safe_halt(); 178 safe_halt();
169 ACPI_FLUSH_CPU_CACHE();
170 /* Change frequency on next halt or sleep */ 179 /* Change frequency on next halt or sleep */
171 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 180 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
181 ACPI_FLUSH_CPU_CACHE();
172 /* Invoke C3 */ 182 /* Invoke C3 */
173 inb(cx_address); 183 inb(cx_address);
174 /* Dummy op - must do something useless after P_LVL3 read */ 184 /* Dummy op - must do something useless after P_LVL3 read */
@@ -227,10 +237,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
227 outb(0xFF,0xA1); /* Overkill */ 237 outb(0xFF,0xA1); /* Overkill */
228 outb(0xFE,0x21); /* TMR0 only */ 238 outb(0xFE,0x21); /* TMR0 only */
229 239
230 /* Disable bus master arbitration */ 240 if (pr->flags.bm_control) {
231 if (pr->flags.bm_check) { 241 /* Disable bus master arbitration */
232 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, 242 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
233 ACPI_MTX_DO_NOT_LOCK); 243 ACPI_MTX_DO_NOT_LOCK);
244 } else if (port22_en) {
245 /* Disable AGP and PCI arbiters */
246 outb(3, 0x22);
234 } 247 }
235 248
236 switch (longhaul_version) { 249 switch (longhaul_version) {
@@ -244,7 +257,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
244 */ 257 */
245 case TYPE_LONGHAUL_V1: 258 case TYPE_LONGHAUL_V1:
246 case TYPE_LONGHAUL_V2: 259 case TYPE_LONGHAUL_V2:
247 do_longhaul1(cx->address, clock_ratio_index); 260 do_longhaul1(clock_ratio_index);
248 break; 261 break;
249 262
250 /* 263 /*
@@ -259,14 +272,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
259 * to work in practice. 272 * to work in practice.
260 */ 273 */
261 case TYPE_POWERSAVER: 274 case TYPE_POWERSAVER:
275 /* Don't allow wakeup */
276 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
277 ACPI_MTX_DO_NOT_LOCK);
262 do_powersaver(cx->address, clock_ratio_index); 278 do_powersaver(cx->address, clock_ratio_index);
263 break; 279 break;
264 } 280 }
265 281
266 /* Enable bus master arbitration */ 282 if (pr->flags.bm_control) {
267 if (pr->flags.bm_check) { 283 /* Enable bus master arbitration */
268 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, 284 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
269 ACPI_MTX_DO_NOT_LOCK); 285 ACPI_MTX_DO_NOT_LOCK);
286 } else if (port22_en) {
287 /* Enable arbiters */
288 outb(0, 0x22);
270 } 289 }
271 290
272 outb(pic2_mask,0xA1); /* restore mask */ 291 outb(pic2_mask,0xA1); /* restore mask */
@@ -446,53 +465,57 @@ static int __init longhaul_get_ranges(void)
446static void __init longhaul_setup_voltagescaling(void) 465static void __init longhaul_setup_voltagescaling(void)
447{ 466{
448 union msr_longhaul longhaul; 467 union msr_longhaul longhaul;
468 struct mV_pos minvid, maxvid;
469 unsigned int j, speed, pos, kHz_step, numvscales;
449 470
450 rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); 471 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
451 472 if (!(longhaul.bits.RevisionID & 1)) {
452 if (!(longhaul.bits.RevisionID & 1)) 473 printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
453 return; 474 return;
475 }
476
477 if (!longhaul.bits.VRMRev) {
478 printk (KERN_INFO PFX "VRM 8.5\n");
479 vrm_mV_table = &vrm85_mV[0];
480 mV_vrm_table = &mV_vrm85[0];
481 } else {
482 printk (KERN_INFO PFX "Mobile VRM\n");
483 vrm_mV_table = &mobilevrm_mV[0];
484 mV_vrm_table = &mV_mobilevrm[0];
485 }
454 486
455 minvid = longhaul.bits.MinimumVID; 487 minvid = vrm_mV_table[longhaul.bits.MinimumVID];
456 maxvid = longhaul.bits.MaximumVID; 488 maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
457 vrmrev = longhaul.bits.VRMRev; 489 numvscales = maxvid.pos - minvid.pos + 1;
490 kHz_step = (highest_speed - lowest_speed) / numvscales;
458 491
459 if (minvid == 0 || maxvid == 0) { 492 if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
460 printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " 493 printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
461 "Voltage scaling disabled.\n", 494 "Voltage scaling disabled.\n",
462 minvid/1000, minvid%1000, maxvid/1000, maxvid%1000); 495 minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
463 return; 496 return;
464 } 497 }
465 498
466 if (minvid == maxvid) { 499 if (minvid.mV == maxvid.mV) {
467 printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are " 500 printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
468 "both %d.%03d. Voltage scaling disabled\n", 501 "both %d.%03d. Voltage scaling disabled\n",
469 maxvid/1000, maxvid%1000); 502 maxvid.mV/1000, maxvid.mV%1000);
470 return; 503 return;
471 } 504 }
472 505
473 if (vrmrev==0) { 506 printk(KERN_INFO PFX "Max VID=%d.%03d Min VID=%d.%03d, %d possible voltage scales\n",
474 dprintk ("VRM 8.5\n"); 507 maxvid.mV/1000, maxvid.mV%1000,
475 memcpy (voltage_table, vrm85scales, sizeof(voltage_table)); 508 minvid.mV/1000, minvid.mV%1000,
476 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25; 509 numvscales);
477 } else { 510
478 dprintk ("Mobile VRM\n"); 511 j = 0;
479 memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table)); 512 while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
480 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5; 513 speed = longhaul_table[j].frequency;
514 pos = (speed - lowest_speed) / kHz_step + minvid.pos;
515 f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos];
516 j++;
481 } 517 }
482 518
483 /* Current voltage isn't readable at first, so we need to
484 set it to a known value. The spec says to use maxvid */
485 longhaul.bits.RevisionKey = longhaul.bits.RevisionID; /* FIXME: This is bad. */
486 longhaul.bits.EnableSoftVID = 1;
487 longhaul.bits.SoftVID = maxvid;
488 wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
489
490 minvid = voltage_table[minvid];
491 maxvid = voltage_table[maxvid];
492
493 dprintk ("Min VID=%d.%03d Max VID=%d.%03d, %d possible voltage scales\n",
494 maxvid/1000, maxvid%1000, minvid/1000, minvid%1000, numvscales);
495
496 can_scale_voltage = 1; 519 can_scale_voltage = 1;
497} 520}
498 521
@@ -540,21 +563,33 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
540 return 1; 563 return 1;
541} 564}
542 565
566/* VIA don't support PM2 reg, but have something similar */
567static int enable_arbiter_disable(void)
568{
569 struct pci_dev *dev;
570 u8 pci_cmd;
571
572 /* Find PLE133 host bridge */
573 dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
574 if (dev != NULL) {
575 /* Enable access to port 0x22 */
576 pci_read_config_byte(dev, 0x78, &pci_cmd);
577 if ( !(pci_cmd & 1<<7) ) {
578 pci_cmd |= 1<<7;
579 pci_write_config_byte(dev, 0x78, pci_cmd);
580 }
581 return 1;
582 }
583 return 0;
584}
585
543static int __init longhaul_cpu_init(struct cpufreq_policy *policy) 586static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
544{ 587{
545 struct cpuinfo_x86 *c = cpu_data; 588 struct cpuinfo_x86 *c = cpu_data;
546 char *cpuname=NULL; 589 char *cpuname=NULL;
547 int ret; 590 int ret;
548 591
549 /* Check ACPI support for C3 state */ 592 /* Check what we have on this motherboard */
550 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
551 &longhaul_walk_callback, NULL, (void *)&pr);
552 if (pr == NULL) goto err_acpi;
553
554 cx = &pr->power.states[ACPI_STATE_C3];
555 if (cx->address == 0 || cx->latency > 1000) goto err_acpi;
556
557 /* Now check what we have on this motherboard */
558 switch (c->x86_model) { 593 switch (c->x86_model) {
559 case 6: 594 case 6:
560 cpu_model = CPU_SAMUEL; 595 cpu_model = CPU_SAMUEL;
@@ -636,12 +671,36 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
636 break; 671 break;
637 }; 672 };
638 673
674 /* Find ACPI data for processor */
675 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
676 &longhaul_walk_callback, NULL, (void *)&pr);
677 if (pr == NULL)
678 goto err_acpi;
679
680 if (longhaul_version == TYPE_POWERSAVER) {
681 /* Check ACPI support for C3 state */
682 cx = &pr->power.states[ACPI_STATE_C3];
683 if (cx->address == 0 ||
684 (cx->latency > 1000 && ignore_latency == 0) )
685 goto err_acpi;
686
687 } else {
688 /* Check ACPI support for bus master arbiter disable */
689 if (!pr->flags.bm_control) {
690 if (!enable_arbiter_disable()) {
691 printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
692 return -ENODEV;
693 } else
694 port22_en = 1;
695 }
696 }
697
639 ret = longhaul_get_ranges(); 698 ret = longhaul_get_ranges();
640 if (ret != 0) 699 if (ret != 0)
641 return ret; 700 return ret;
642 701
643 if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) && 702 if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) &&
644 (dont_scale_voltage==0)) 703 (scale_voltage != 0))
645 longhaul_setup_voltagescaling(); 704 longhaul_setup_voltagescaling();
646 705
647 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 706 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
@@ -729,8 +788,10 @@ static void __exit longhaul_exit(void)
729 kfree(longhaul_table); 788 kfree(longhaul_table);
730} 789}
731 790
732module_param (dont_scale_voltage, int, 0644); 791module_param (scale_voltage, int, 0644);
733MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor"); 792MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
793module_param(ignore_latency, int, 0644);
794MODULE_PARM_DESC(ignore_latency, "Skip ACPI C3 latency test");
734 795
735MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); 796MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
736MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); 797MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
@@ -738,4 +799,3 @@ MODULE_LICENSE ("GPL");
738 799
739late_initcall(longhaul_init); 800late_initcall(longhaul_init);
740module_exit(longhaul_exit); 801module_exit(longhaul_exit);
741
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h
index d3a95d77ee85..bc4682aad69b 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.h
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h
@@ -450,17 +450,45 @@ static int __initdata nehemiah_c_eblcr[32] = {
450 * Voltage scales. Div/Mod by 1000 to get actual voltage. 450 * Voltage scales. Div/Mod by 1000 to get actual voltage.
451 * Which scale to use depends on the VRM type in use. 451 * Which scale to use depends on the VRM type in use.
452 */ 452 */
453static int __initdata vrm85scales[32] = { 453
454 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700, 454struct mV_pos {
455 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300, 455 unsigned short mV;
456 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725, 456 unsigned short pos;
457 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325, 457};
458
459static struct mV_pos __initdata vrm85_mV[32] = {
460 {1250, 8}, {1200, 6}, {1150, 4}, {1100, 2},
461 {1050, 0}, {1800, 30}, {1750, 28}, {1700, 26},
462 {1650, 24}, {1600, 22}, {1550, 20}, {1500, 18},
463 {1450, 16}, {1400, 14}, {1350, 12}, {1300, 10},
464 {1275, 9}, {1225, 7}, {1175, 5}, {1125, 3},
465 {1075, 1}, {1825, 31}, {1775, 29}, {1725, 27},
466 {1675, 25}, {1625, 23}, {1575, 21}, {1525, 19},
467 {1475, 17}, {1425, 15}, {1375, 13}, {1325, 11}
468};
469
470static unsigned char __initdata mV_vrm85[32] = {
471 0x04, 0x14, 0x03, 0x13, 0x02, 0x12, 0x01, 0x11,
472 0x00, 0x10, 0x0f, 0x1f, 0x0e, 0x1e, 0x0d, 0x1d,
473 0x0c, 0x1c, 0x0b, 0x1b, 0x0a, 0x1a, 0x09, 0x19,
474 0x08, 0x18, 0x07, 0x17, 0x06, 0x16, 0x05, 0x15
475};
476
477static struct mV_pos __initdata mobilevrm_mV[32] = {
478 {1750, 31}, {1700, 30}, {1650, 29}, {1600, 28},
479 {1550, 27}, {1500, 26}, {1450, 25}, {1400, 24},
480 {1350, 23}, {1300, 22}, {1250, 21}, {1200, 20},
481 {1150, 19}, {1100, 18}, {1050, 17}, {1000, 16},
482 {975, 15}, {950, 14}, {925, 13}, {900, 12},
483 {875, 11}, {850, 10}, {825, 9}, {800, 8},
484 {775, 7}, {750, 6}, {725, 5}, {700, 4},
485 {675, 3}, {650, 2}, {625, 1}, {600, 0}
458}; 486};
459 487
460static int __initdata mobilevrmscales[32] = { 488static unsigned char __initdata mV_mobilevrm[32] = {
461 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 489 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
462 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1, 490 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
463 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 491 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
464 1075, 1050, 1025, 1000, 975, 950, 925, -1, 492 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
465}; 493};
466 494
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index b77f1358bd79..7a9325349e94 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -23,6 +23,7 @@
23 23
24#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 24#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/dmi.h>
26#include <acpi/processor.h> 27#include <acpi/processor.h>
27#endif 28#endif
28 29
@@ -377,6 +378,35 @@ static int centrino_cpu_early_init_acpi(void)
377 return 0; 378 return 0;
378} 379}
379 380
381
382/*
383 * Some BIOSes do SW_ANY coordination internally, either set it up in hw
384 * or do it in BIOS firmware and won't inform about it to OS. If not
385 * detected, this has a side effect of making CPU run at a different speed
386 * than OS intended it to run at. Detect it and handle it cleanly.
387 */
388static int bios_with_sw_any_bug;
389static int __init sw_any_bug_found(struct dmi_system_id *d)
390{
391 bios_with_sw_any_bug = 1;
392 return 0;
393}
394
395
396static struct dmi_system_id sw_any_bug_dmi_table[] = {
397 {
398 .callback = sw_any_bug_found,
399 .ident = "Supermicro Server X6DLP",
400 .matches = {
401 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
402 DMI_MATCH(DMI_BIOS_VERSION, "080010"),
403 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
404 },
405 },
406 { }
407};
408
409
380/* 410/*
381 * centrino_cpu_init_acpi - register with ACPI P-States library 411 * centrino_cpu_init_acpi - register with ACPI P-States library
382 * 412 *
@@ -398,14 +428,24 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
398 dprintk(PFX "obtaining ACPI data failed\n"); 428 dprintk(PFX "obtaining ACPI data failed\n");
399 return -EIO; 429 return -EIO;
400 } 430 }
431
401 policy->shared_type = p->shared_type; 432 policy->shared_type = p->shared_type;
402 /* 433 /*
403 * Will let policy->cpus know about dependency only when software 434 * Will let policy->cpus know about dependency only when software
404 * coordination is required. 435 * coordination is required.
405 */ 436 */
406 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || 437 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
407 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) 438 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
408 policy->cpus = p->shared_cpu_map; 439 policy->cpus = p->shared_cpu_map;
440 }
441
442#ifdef CONFIG_SMP
443 dmi_check_system(sw_any_bug_dmi_table);
444 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
445 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
446 policy->cpus = cpu_core_map[cpu];
447 }
448#endif
409 449
410 /* verify the acpi_data */ 450 /* verify the acpi_data */
411 if (p->state_count <= 1) { 451 if (p->state_count <= 1) {