diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2006-09-27 14:57:54 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-09-27 14:57:54 -0400 |
commit | 2dc94310bd94d0906febea7d0f7c188da620c952 (patch) | |
tree | 6de4096f1887e2c00966177354b1c378e59bd632 /arch/i386 | |
parent | c06015148fa9a3cc452ec7121b8c3f59f4a7d6ac (diff) | |
parent | fb60cf4ab52f3520c2119aa42f7d4ed8e7594eb6 (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/Makefile | 3 | ||||
-rw-r--r-- | arch/i386/crypto/aes.c | 3 | ||||
-rw-r--r-- | arch/i386/crypto/twofish-i586-asm.S | 335 | ||||
-rw-r--r-- | arch/i386/crypto/twofish.c | 97 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 39 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/longhaul.c | 186 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/longhaul.h | 48 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 42 |
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 | ||
7 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o | 7 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o |
8 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | ||
8 | 9 | ||
9 | aes-i586-y := aes-i586-asm.o aes.o | 10 | aes-i586-y := aes-i586-asm.o aes.o |
11 | twofish-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 | ||
381 | static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 381 | static 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 | |||
226 | twofish_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 | |||
281 | twofish_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 | |||
48 | asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | ||
49 | asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | ||
50 | |||
51 | static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
52 | { | ||
53 | twofish_enc_blk(tfm, dst, src); | ||
54 | } | ||
55 | |||
56 | static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
57 | { | ||
58 | twofish_dec_blk(tfm, dst, src); | ||
59 | } | ||
60 | |||
61 | static 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 | |||
82 | static int __init init(void) | ||
83 | { | ||
84 | return crypto_register_alg(&alg); | ||
85 | } | ||
86 | |||
87 | static void __exit fini(void) | ||
88 | { | ||
89 | crypto_unregister_alg(&alg); | ||
90 | } | ||
91 | |||
92 | module_init(init); | ||
93 | module_exit(fini); | ||
94 | |||
95 | MODULE_LICENSE("GPL"); | ||
96 | MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized"); | ||
97 | MODULE_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 | */ | ||
397 | static int bios_with_sw_any_bug; | ||
398 | |||
399 | static int __init sw_any_bug_found(struct dmi_system_id *d) | ||
400 | { | ||
401 | bios_with_sw_any_bug = 1; | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static 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 | |||
390 | static int | 418 | static int |
391 | acpi_cpufreq_cpu_init ( | 419 | acpi_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 | ||
54 | static int cpu_model; | 55 | static int cpu_model; |
55 | static unsigned int numscales=16, numvscales; | 56 | static unsigned int numscales=16; |
56 | static unsigned int fsb; | 57 | static unsigned int fsb; |
57 | static int minvid, maxvid; | 58 | |
59 | static struct mV_pos *vrm_mV_table; | ||
60 | static unsigned char *mV_vrm_table; | ||
61 | struct f_msr { | ||
62 | unsigned char vrm; | ||
63 | }; | ||
64 | static struct f_msr f_msr_table[32]; | ||
65 | |||
66 | static unsigned int highest_speed, lowest_speed; /* kHz */ | ||
58 | static unsigned int minmult, maxmult; | 67 | static unsigned int minmult, maxmult; |
59 | static int can_scale_voltage; | 68 | static int can_scale_voltage; |
60 | static int vrmrev; | ||
61 | static struct acpi_processor *pr = NULL; | 69 | static struct acpi_processor *pr = NULL; |
62 | static struct acpi_processor_cx *cx = NULL; | 70 | static struct acpi_processor_cx *cx = NULL; |
71 | static int port22_en; | ||
63 | 72 | ||
64 | /* Module parameters */ | 73 | /* Module parameters */ |
65 | static int dont_scale_voltage; | 74 | static int scale_voltage; |
66 | 75 | static 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 */ |
72 | static int clock_ratio[32]; | 81 | static int clock_ratio[32]; |
73 | static int eblcr_table[32]; | 82 | static int eblcr_table[32]; |
74 | static int voltage_table[32]; | ||
75 | static unsigned int highest_speed, lowest_speed; /* kHz */ | 83 | static unsigned int highest_speed, lowest_speed; /* kHz */ |
76 | static int longhaul_version; | 84 | static int longhaul_version; |
77 | static struct cpufreq_frequency_table *longhaul_table; | 85 | static 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 | ||
127 | static void do_longhaul1(int cx_address, unsigned int clock_ratio_index) | 135 | static 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) | |||
446 | static void __init longhaul_setup_voltagescaling(void) | 465 | static 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 */ | ||
567 | static 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 | |||
543 | static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | 586 | static 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 | ||
732 | module_param (dont_scale_voltage, int, 0644); | 791 | module_param (scale_voltage, int, 0644); |
733 | MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor"); | 792 | MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); |
793 | module_param(ignore_latency, int, 0644); | ||
794 | MODULE_PARM_DESC(ignore_latency, "Skip ACPI C3 latency test"); | ||
734 | 795 | ||
735 | MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); | 796 | MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); |
736 | MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); | 797 | MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); |
@@ -738,4 +799,3 @@ MODULE_LICENSE ("GPL"); | |||
738 | 799 | ||
739 | late_initcall(longhaul_init); | 800 | late_initcall(longhaul_init); |
740 | module_exit(longhaul_exit); | 801 | module_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 | */ |
453 | static int __initdata vrm85scales[32] = { | 453 | |
454 | 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700, | 454 | struct 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 | |||
459 | static 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 | |||
470 | static 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 | |||
477 | static 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 | ||
460 | static int __initdata mobilevrmscales[32] = { | 488 | static 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 | */ | ||
388 | static int bios_with_sw_any_bug; | ||
389 | static 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 | |||
396 | static 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) { |