Magellan Linux

Annotation of /trunk/kernel26-alx/patches-2.6.21-r14/0156-2.6.21-linux-phc-0.2.10.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 447 - (hide annotations) (download)
Tue Jan 22 17:55:52 2008 UTC (16 years, 4 months ago) by niro
File size: 36051 byte(s)
-2.6.21-alx-r14 - fixed some natsemi errors on wys terminals

1 niro 447 diff --new-file -a --unified=5 --recursive --exclude-from=diff.excludes linux.org/arch/i386/kernel/cpu/cpufreq/Kconfig linux.phc/arch/i386/kernel/cpu/cpufreq/Kconfig
2     --- linux.org/arch/i386/kernel/cpu/cpufreq/Kconfig 2007-05-12 15:41:54.000000000 +0200
3     +++ linux.phc/arch/i386/kernel/cpu/cpufreq/Kconfig 2007-05-12 16:21:52.000000000 +0200
4     @@ -1,9 +1,12 @@
5     #
6     # CPU Frequency scaling
7     #
8    
9     +# This file has been patched with Linux PHC: https://www.dedigentoo.org/trac/linux-phc
10     +# Patch version: linux-phc-0.2.10-kernel-vanilla-2.6.21.patch
11     +
12     menu "CPU Frequency scaling"
13    
14     source "drivers/cpufreq/Kconfig"
15    
16     if CPU_FREQ
17     @@ -95,11 +98,10 @@
18     depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
19     default y
20    
21     config X86_GX_SUSPMOD
22     tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
23     - depends on PCI
24     help
25     This add the CPUFreq driver for NatSemi Geode processors which
26     support suspend modulation.
27    
28     For details, take a look at <file:Documentation/cpu-freq/>.
29     @@ -107,45 +109,122 @@
30     If in doubt, say N.
31    
32     config X86_SPEEDSTEP_CENTRINO
33     tristate "Intel Enhanced SpeedStep"
34     select CPU_FREQ_TABLE
35     - select X86_SPEEDSTEP_CENTRINO_TABLE if (!X86_SPEEDSTEP_CENTRINO_ACPI)
36     + select X86_SPEEDSTEP_CENTRINO_ACPI if (!X86_SPEEDSTEP_CENTRINO_BUILTIN || (!X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS && !X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN && !X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA ))
37     help
38     This adds the CPUFreq driver for Enhanced SpeedStep enabled
39     mobile CPUs. This means Intel Pentium M (Centrino) CPUs. However,
40     - you also need to say Y to "Use ACPI tables to decode..." below
41     - [which might imply enabling ACPI] if you want to use this driver
42     - on non-Banias CPUs.
43     + you also need to say Y below to at least one of the following options:
44     + - "Use ACPI tables to decode..." [which might imply enabling ACPI]
45     + - "Built-in Tables for ... CPUs"
46     +
47     + You can also say yes to all of these options. In this configuration the
48     + driver will first try to use ACPI. Then if it fails it will try to use
49     + a built-in table if there is one matching the CPU.
50     +
51     + For details, take a look at <file:Documentation/cpu-freq/>.
52     +
53     + If in doubt, say N.
54     +
55     +config X86_SPEEDSTEP_CENTRINO_SYSFS
56     + bool "Userspace control of CPU frequency/voltage table"
57     + depends on X86_SPEEDSTEP_CENTRINO
58     + depends on SYSFS
59     + depends on (X86_SPEEDSTEP_CENTRINO_BUILTIN && (X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS || X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN || X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA )) || X86_SPEEDSTEP_CENTRINO_ACPI || X86_SPEEDSTEP_CENTRINO_DEFAULT
60     + default y
61     + help
62     + Add support for user space control of the CPU frequency/voltage
63     + operating points table through a sysfs interface.
64     +
65     + If you say Y here files will be created in
66     + /sys/devices/system/cpu/cpu*/cpufreq/op_points_table
67     + allowing reading and writing of the current table values as well as
68     + adding or removing operating points.
69    
70     For details, take a look at <file:Documentation/cpu-freq/>.
71    
72     If in doubt, say N.
73    
74     config X86_SPEEDSTEP_CENTRINO_ACPI
75     - bool "Use ACPI tables to decode valid frequency/voltage (deprecated)"
76     + bool "Use ACPI tables to decode valid frequency/voltage pairs (deprecated)"
77     depends on X86_SPEEDSTEP_CENTRINO && ACPI_PROCESSOR
78     depends on !(X86_SPEEDSTEP_CENTRINO = y && ACPI_PROCESSOR = m)
79     + default y
80     help
81     This is deprecated and this functionality is now merged into
82     acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
83     speedstep_centrino.
84     Use primarily the information provided in the BIOS ACPI tables
85     - to determine valid CPU frequency and voltage pairings. It is
86     - required for the driver to work on non-Banias CPUs.
87     + to determine valid CPU frequency and voltage pairings.
88     + It is required for the driver to work on CPUs with no built-in
89     + table available
90     +
91     + (this option adds around 3 kB to the kernel size)
92    
93     If in doubt, say Y.
94    
95     -config X86_SPEEDSTEP_CENTRINO_TABLE
96     - bool "Built-in tables for Banias CPUs"
97     +config X86_SPEEDSTEP_CENTRINO_BUILTIN
98     + bool "Built-in tables"
99     depends on X86_SPEEDSTEP_CENTRINO
100     default y
101     help
102     - Use built-in tables for Banias CPUs if ACPI encoding
103     + Use "hard coded" built-in tables if ACPI decoding
104     is not available.
105    
106     - If in doubt, say N.
107     + If you say Y here you must select at least one of the CPU below.
108     +
109     + If you are not sure of your exact CPU model you can select several CPU
110     + models or all of them. The driver will only use the table that match
111     + the exact CPU name and family/model/stepping numbers.
112     + Selecting all the built-in tables will only add a small size overhead
113     + to the kernel and an insignificant extra time to intialize the driver.
114     +
115     + If both ACPI and built-in tables support are enabled then built-in
116     + tables will be used only if ACPI table decoding fails.
117     +
118     + If you want to force usage of built-in tables over ACPI you need to say
119     + Y here and N to X86_SPEEDSTEP_CENTRINO_ACPI.
120     +
121     + (this option adds from 2.5 to 4.5 kB to the kernel size, depending on
122     + the selected built-in tables)
123     +
124     + If in doubt, say Y.
125     +
126     +config X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS
127     + bool "Built-in tables for Banias CPUs"
128     + depends on X86_SPEEDSTEP_CENTRINO_BUILTIN
129     + default y
130     + help
131     + Use built-in tables for Banias CPUs if ACPI encoding is not available.
132     + Banias CPUs are the first generation of Pentium-M, with a 1 MB L2 cache
133     + and 400 MHz FSB manufactured on 0.13 micron process.
134     +
135     + If in doubt, say Y.
136     +
137     +config X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN
138     + bool "Built-in tables for Dothan CPUs"
139     + depends on X86_SPEEDSTEP_CENTRINO_BUILTIN
140     + default y
141     + help
142     + Use built-in tables for Dothan CPUs if ACPI encoding is not available.
143     + Dothan CPUs are the second generation of Pentium-M, with a 2 MB L2
144     + cache and 400 MHz FSB manufactured on 90 nm process.
145     +
146     + If in doubt, say Y.
147     +
148     +config X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA
149     + bool "Built-in tables for Sonoma CPUs"
150     + depends on X86_SPEEDSTEP_CENTRINO_BUILTIN
151     + default y
152     + help
153     + Use built-in tables for Sonoma CPUs if ACPI encoding is not available.
154     + Sonoma CPUs are the third generation of Pentium-M, with a 2 MB L2 cache
155     + and 533 MHz FSB manufactured on 90 nm process.
156     +
157     + If in doubt, say Y.
158    
159     config X86_SPEEDSTEP_ICH
160     tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
161     select CPU_FREQ_TABLE
162     help
163     diff --new-file -a --unified=5 --recursive --exclude-from=diff.excludes linux.org/arch/i386/kernel/cpu/cpufreq/Makefile linux.phc/arch/i386/kernel/cpu/cpufreq/Makefile
164     --- linux.org/arch/i386/kernel/cpu/cpufreq/Makefile 2007-05-12 15:41:54.000000000 +0200
165     +++ linux.phc/arch/i386/kernel/cpu/cpufreq/Makefile 2007-05-12 16:26:41.000000000 +0200
166     @@ -6,11 +6,11 @@
167     obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
168     obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o
169     obj-$(CONFIG_X86_LONGRUN) += longrun.o
170     obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
171     obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
172     +obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
173     obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
174     obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
175     obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
176     -obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
177     obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
178     obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
179     diff --new-file -a --unified=5 --recursive --exclude-from=diff.excludes linux.org/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux.phc/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
180     --- linux.org/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-05-12 15:41:54.000000000 +0200
181     +++ linux.phc/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-05-13 19:08:51.000000000 +0200
182     @@ -11,10 +11,15 @@
183     * Modelled on speedstep.c
184     *
185     * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
186     */
187    
188     +/*
189     + * This file has been patched with Linux PHC: https://www.dedigentoo.org/trac/linux-phc
190     + * Patch version: linux-phc-0.2.10-kernel-vanilla-2.6.21.patch
191     + */
192     +
193     #include <linux/kernel.h>
194     #include <linux/module.h>
195     #include <linux/init.h>
196     #include <linux/cpufreq.h>
197     #include <linux/sched.h> /* current */
198     @@ -48,41 +53,45 @@
199     enum {
200     CPU_BANIAS,
201     CPU_DOTHAN_A1,
202     CPU_DOTHAN_A2,
203     CPU_DOTHAN_B0,
204     + CPU_DOTHAN_C0,
205     CPU_MP4HT_D0,
206     CPU_MP4HT_E0,
207     };
208    
209     static const struct cpu_id cpu_ids[] = {
210     [CPU_BANIAS] = { 6, 9, 5 },
211     [CPU_DOTHAN_A1] = { 6, 13, 1 },
212     [CPU_DOTHAN_A2] = { 6, 13, 2 },
213     [CPU_DOTHAN_B0] = { 6, 13, 6 },
214     + [CPU_DOTHAN_C0] = { 6, 13, 8 },
215     [CPU_MP4HT_D0] = {15, 3, 4 },
216     [CPU_MP4HT_E0] = {15, 4, 1 },
217     };
218     #define N_IDS ARRAY_SIZE(cpu_ids)
219    
220     struct cpu_model
221     {
222     const struct cpu_id *cpu_id;
223     const char *model_name;
224     unsigned max_freq; /* max clock in kHz */
225     -
226     struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
227     + unsigned base_freq; /* base frequency used to convert between clock rates and MSR: FSB/4 in kHz */
228     };
229     static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);
230    
231     /* Operating points for current CPU */
232     static struct cpu_model *centrino_model[NR_CPUS];
233     static const struct cpu_id *centrino_cpu[NR_CPUS];
234    
235     static struct cpufreq_driver centrino_driver;
236    
237     -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
238     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN
239     +
240     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS
241    
242     /* Computes the correct form for IA32_PERF_CTL MSR for a particular
243     frequency/voltage operating point; frequency in MHz, volts in mV.
244     This is stored as "index" in the structure. */
245     #define OP(mhz, mv) \
246     @@ -126,11 +135,10 @@
247     OP(1000, 1164),
248     OP(1100, 1180),
249     { .frequency = CPUFREQ_TABLE_END }
250     };
251    
252     -
253     /* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
254     static struct cpufreq_frequency_table banias_1200[] =
255     {
256     OP( 600, 956),
257     OP( 800, 1004),
258     @@ -203,38 +211,301 @@
259     #define _BANIAS(cpuid, max, name) \
260     { .cpu_id = cpuid, \
261     .model_name = "Intel(R) Pentium(R) M processor " name "MHz", \
262     .max_freq = (max)*1000, \
263     .op_points = banias_##max, \
264     + .base_freq = 100000, \
265     }
266     #define BANIAS(max) _BANIAS(&cpu_ids[CPU_BANIAS], max, #max)
267    
268     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS */
269     +
270     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN
271     +/* Dothan processor datasheet 30218903.pdf defines 4 voltages for each
272     + frequency (VID#A through VID#D) - this macro allows us to define all
273     + of these but we only use the VID#A voltages at compile time - this may
274     + need some work if we want to select the voltage profile at runtime. */
275     +
276     +#define OP(mhz, mva, mvb, mvc, mvd) \
277     + { \
278     + .frequency = (mhz) * 1000, \
279     + .index = (((mhz)/100) << 8) | ((mva - 700) / 16) \
280     + }
281     +
282     +/* Intel Pentium M processor 733 / 1.10GHz (Dothan) */
283     +static struct cpufreq_frequency_table dothan_1100[] =
284     +{
285     + OP( 600, 700, 700, 700, 700),
286     + OP( 800, 748, 748, 748, 748),
287     + OP( 900, 764, 764, 764, 764),
288     + OP(1000, 812, 812, 812, 812),
289     + OP(1100, 844, 844, 844, 844),
290     + { .frequency = CPUFREQ_TABLE_END }
291     +};
292     +
293     +/* Intel Pentium M processor 710 / 1.40GHz (Dothan) */
294     +static struct cpufreq_frequency_table dothan_1400[] =
295     +{
296     +
297     + OP( 600, 988, 988, 988, 988),
298     + OP( 800, 1068, 1068, 1068, 1052),
299     + OP(1000, 1148, 1148, 1132, 1116),
300     + OP(1200, 1228, 1212, 1212, 1180),
301     + OP(1400, 1340, 1324, 1308, 1276),
302     + { .frequency = CPUFREQ_TABLE_END }
303     +};
304     +
305     +/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */
306     +static struct cpufreq_frequency_table dothan_1500[] =
307     +{
308     + OP( 600, 988, 988, 988, 988),
309     + OP( 800, 1068, 1068, 1068, 1052),
310     + OP(1000, 1148, 1148, 1132, 1116),
311     + OP(1200, 1228, 1212, 1212, 1180),
312     + OP(1500, 1340, 1324, 1308, 1276),
313     + { .frequency = CPUFREQ_TABLE_END }
314     +};
315     +
316     +/* Intel Pentium M processor 725 / 1.60GHz (Dothan) */
317     +static struct cpufreq_frequency_table dothan_1600[] =
318     +{
319     + OP( 600, 988, 988, 988, 988),
320     + OP( 800, 1068, 1068, 1052, 1052),
321     + OP(1000, 1132, 1132, 1116, 1116),
322     + OP(1200, 1212, 1196, 1180, 1164),
323     + OP(1400, 1276, 1260, 1244, 1228),
324     + OP(1600, 1340, 1324, 1308, 1276),
325     + { .frequency = CPUFREQ_TABLE_END }
326     +};
327     +
328     +/* Intel Pentium M processor 735 / 1.70GHz (Dothan) */
329     +static struct cpufreq_frequency_table dothan_1700[] =
330     +{
331     + OP( 600, 988, 988, 988, 988),
332     + OP( 800, 1052, 1052, 1052, 1052),
333     + OP(1000, 1116, 1116, 1116, 1100),
334     + OP(1200, 1180, 1180, 1164, 1148),
335     + OP(1400, 1244, 1244, 1228, 1212),
336     + OP(1700, 1340, 1324, 1308, 1276),
337     + { .frequency = CPUFREQ_TABLE_END }
338     +};
339     +
340     +/* Intel Pentium M processor 745 / 1.80GHz (Dothan) */
341     +static struct cpufreq_frequency_table dothan_1800[] =
342     +{
343     + OP( 600, 988, 988, 988, 988),
344     + OP( 800, 1052, 1052, 1052, 1036),
345     + OP(1000, 1116, 1100, 1100, 1084),
346     + OP(1200, 1164, 1164, 1148, 1132),
347     + OP(1400, 1228, 1212, 1212, 1180),
348     + OP(1600, 1292, 1276, 1260, 1228),
349     + OP(1800, 1340, 1324, 1308, 1276),
350     + { .frequency = CPUFREQ_TABLE_END }
351     +};
352     +
353     +/* Intel Pentium M processor 755 / 2.00GHz (Dothan) */
354     +static struct cpufreq_frequency_table dothan_2000[] =
355     +{
356     + OP( 600, 988, 988, 988, 988),
357     + OP( 800, 1052, 1036, 1036, 1036),
358     + OP(1000, 1100, 1084, 1084, 1084),
359     + OP(1200, 1148, 1132, 1132, 1116),
360     + OP(1400, 1196, 1180, 1180, 1164),
361     + OP(1600, 1244, 1228, 1228, 1196),
362     + OP(1800, 1292, 1276, 1276, 1244),
363     + OP(2000, 1340, 1324, 1308, 1276),
364     + { .frequency = CPUFREQ_TABLE_END }
365     +};
366     +
367     +#undef OP
368     +
369     +#define DOTHAN(cpuid, max, name) \
370     +{ .cpu_id = cpuid, \
371     + .model_name = "Intel(R) Pentium(R) M processor " name "GHz", \
372     + .max_freq = (max)*1000, \
373     + .op_points = dothan_##max, \
374     + .base_freq = 100000, \
375     +}
376     +
377     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN */
378     +
379     +
380     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA
381     +
382     +/* Intel datasheets 30526202.pdf define voltages only for highest and
383     + lowest frequency modes (HFM and LFM).
384     + For LFM the datasheet gives one typical voltage: LFMVccTyp.
385     + For HFM the datasheet gives a min and a max voltage: HFMVccMin and HFMVccMax.
386     + The tables below are using HFMVccMax for the highest frequency to be on
387     + the safe side. The voltages of the intermediate frequencies are linearly
388     + interpolated from LFMVccTyp and HFMVccMax as it is what I have observed
389     + to be used by the ACPI tables of my laptop and of some other's one.
390     +
391     + LFMVccTyp is 988 mv for all models
392     + HFMVccMin is 1260 mv for all models
393     + HFMVccMax is 1356 mv for models 730, 740, 750 and 760.
394     + HFMVccMax is 1372 mv for model 770.
395     + HFMVccMax is 1404 mv for model 780.
396     +
397     + As only the first voltage of each row of the tables are used I have put
398     + there the values interpolated from HFMVccMax rounded to the next higher 16 mV step
399     + For reference I have put in the other 3 columns:
400     + values interpolated from HFMVccMax rounded to the nearest 1 mv
401     + values interpolated from HFMVccMin rounded to the next higher 16 mv step
402     + values interpolated from HFMVccMin rounded to the nearest 1 mv
403     +*/
404     +
405     +#define OPEX(mhz, base, mva, mvb, mvc, mvd) \
406     +{ \
407     + .frequency = (mhz) * 1000, \
408     + .index = (((mhz)/(base)) << 8) | ((mva - 700) / 16) \
409     +}
410     +
411     +/* Intel Pentium M processor 730 / 1.60 GHz (Sonoma) */
412     +static struct cpufreq_frequency_table sonoma_1596[] =
413     +{
414     + OPEX( 798, 133, 988, 988, 988, 988),
415     + OPEX(1064, 133, 1116, 1111, 1084, 1079),
416     + OPEX(1330, 133, 1244, 1233, 1180, 1169),
417     + OPEX(1596, 133, 1356, 1356, 1260, 1260),
418     + { .frequency = CPUFREQ_TABLE_END }
419     +};
420     +
421     +/* Intel Pentium M processor 740 / 1.73 GHz (Sonoma) */
422     +static struct cpufreq_frequency_table sonoma_1729[] =
423     +{
424     + OPEX( 798, 133, 988, 988, 988, 988),
425     + OPEX(1064, 133, 1100, 1093, 1068, 1066),
426     + OPEX(1330, 133, 1212, 1198, 1148, 1143),
427     + OPEX(1729, 133, 1356, 1356, 1260, 1260),
428     + { .frequency = CPUFREQ_TABLE_END }
429     +};
430     +
431     +/* Intel Pentium M processor 750 / 1.86 GHz (Sonoma) */
432     +static struct cpufreq_frequency_table sonoma_1862[] =
433     +{
434     + OPEX( 798, 133, 988, 988, 988, 988),
435     + OPEX(1064, 133, 1084, 1080, 1068, 1056),
436     + OPEX(1330, 133, 1180, 1172, 1132, 1124),
437     + OPEX(1596, 133, 1276, 1264, 1196, 1192),
438     + OPEX(1862, 133, 1356, 1356, 1260, 1260),
439     + { .frequency = CPUFREQ_TABLE_END }
440     +};
441     +
442     +/* Intel Pentium M processor 760 / 2.00 GHz (Sonoma) */
443     +static struct cpufreq_frequency_table sonoma_1995[] =
444     +{
445     + OPEX( 798, 133, 988, 988, 988, 988),
446     + OPEX(1064, 133, 1084, 1070, 1052, 1048),
447     + OPEX(1330, 133, 1164, 1152, 1116, 1109),
448     + OPEX(1596, 133, 1244, 1233, 1180, 1169),
449     + OPEX(1995, 133, 1356, 1356, 1260, 1260),
450     + { .frequency = CPUFREQ_TABLE_END }
451     +};
452     +
453     +/* Intel Pentium M processor 770 / 2.13 GHz (Sonoma) */
454     +static struct cpufreq_frequency_table sonoma_2128[] =
455     +{
456     + OPEX( 798, 133, 988, 988, 988, 988),
457     + OPEX(1064, 133, 1068, 1065, 1052, 1042),
458     + OPEX(1330, 133, 1148, 1142, 1100, 1097),
459     + OPEX(1596, 133, 1228, 1218, 1164, 1151),
460     + OPEX(1862, 133, 1308, 1295, 1212, 1206),
461     + OPEX(2128, 133, 1372, 1372, 1260, 1260),
462     + { .frequency = CPUFREQ_TABLE_END }
463     +};
464     +
465     +/* Intel Pentium M processor 780 / 2.26 GHz (Sonoma) */
466     +static struct cpufreq_frequency_table sonoma_2261[] =
467     +{
468     + OPEX( 798, 133, 988, 988, 988, 988),
469     + OPEX(1064, 133, 1068, 1064, 1052, 1037),
470     + OPEX(1330, 133, 1148, 1139, 1100, 1087),
471     + OPEX(1596, 133, 1228, 1215, 1148, 1136),
472     + OPEX(1862, 133, 1292, 1291, 1196, 1186),
473     + OPEX(2261, 133, 1404, 1404, 1260, 1260),
474     + { .frequency = CPUFREQ_TABLE_END }
475     +};
476     +
477     +#undef OPEX
478     +
479     +#define SONOMA(cpuid, max, base, name) \
480     +{ .cpu_id = cpuid, \
481     + .model_name = "Intel(R) Pentium(R) M processor " name "GHz", \
482     + .max_freq = (max)*1000, \
483     + .op_points = sonoma_##max, \
484     + .base_freq = (base)*1000, \
485     +}
486     +
487     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA */
488     +
489     +
490     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_YONAH
491     +// To Do
492     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_YONAH */
493     +
494     +
495     /* CPU models, their operating frequency range, and freq/voltage
496     operating points */
497     static struct cpu_model models[] =
498     {
499     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS
500     + /* Builtin tables for Banias CPUs */
501     _BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
502     BANIAS(1000),
503     BANIAS(1100),
504     BANIAS(1200),
505     BANIAS(1300),
506     BANIAS(1400),
507     BANIAS(1500),
508     BANIAS(1600),
509     BANIAS(1700),
510     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_BANIAS */
511    
512     - /* NULL model_name is a wildcard */
513     - { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
514     - { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
515     - { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
516     - { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
517     - { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
518     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN
519     + /* Builtin tables for Dothan B0 CPUs */
520     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1100, "1.10"),
521     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1400, "1.40"),
522     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1500, "1.50"),
523     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1600, "1.60"),
524     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1700, "1.70"),
525     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1800, "1.80"),
526     + DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 2000, "2.00"),
527     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_DOTHAN */
528     +
529     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA
530     + /* Builtin tables for Dothan C0 CPUs, a.k.a Sonoma */
531     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1596, 133, "1.60"),
532     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1729, 133, "1.73"),
533     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1862, 133, "1.86"),
534     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1995, 133, "2.00"),
535     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2128, 133, "2.13"),
536     + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2261, 133, "2.26"),
537     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_SONOMA */
538     +
539     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_YONAH
540     + /* Builtin tables for Yonah CPUs */
541     + // To Do
542     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN_YONAH */
543     +
544     + /* NULL model_name is a wildcard to catch known CPU IDs for which
545     + * we don't have any builtin table */
546     + { &cpu_ids[CPU_BANIAS], NULL, 0, NULL, 0 },
547     + { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL, 0 },
548     + { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL, 0 },
549     + { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL, 0 },
550     + { &cpu_ids[CPU_DOTHAN_C0], NULL, 0, NULL, 0 },
551     + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL, 0 },
552     + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL, 0 },
553    
554     + /* End of the table */
555     { NULL, }
556     };
557     #undef _BANIAS
558     #undef BANIAS
559     +#undef DOTHAN
560     +#undef SONOMA
561    
562     static int centrino_cpu_init_table(struct cpufreq_policy *policy)
563     {
564     struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
565     struct cpu_model *model;
566     @@ -271,11 +542,11 @@
567     return 0;
568     }
569    
570     #else
571     static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
572     -#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
573     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_BUILTIN */
574    
575     static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x)
576     {
577     if ((c->x86 == x->x86) &&
578     (c->x86_model == x->x86_model) &&
579     @@ -292,10 +563,17 @@
580     /*
581     * Extract clock in kHz from PERF_CTL value
582     * for centrino, as some DSDTs are buggy.
583     * Ideally, this can be done using the acpi_data structure.
584     */
585     +
586     + if ((centrino_model[cpu]) && (centrino_model[cpu]->base_freq != 0))
587     + {
588     + msr = (msr >> 8) & 0xff;
589     + return msr * centrino_model[cpu]->base_freq;
590     + }
591     +
592     if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
593     (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
594     (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0])) {
595     msr = (msr >> 8) & 0xff;
596     return msr * 100000;
597     @@ -508,10 +786,11 @@
598     i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
599     }
600     centrino_model[cpu]->op_points[p->state_count].frequency = CPUFREQ_TABLE_END;
601    
602     cur_freq = get_cur_freq(cpu);
603     + centrino_model[cpu]->base_freq = 0;
604    
605     for (i=0; i<p->state_count; i++) {
606     if (!p->states[i].core_frequency) {
607     dprintk("skipping state %u\n", i);
608     centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
609     @@ -519,12 +798,12 @@
610     }
611    
612     if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
613     (centrino_model[cpu]->op_points[i].frequency)) {
614     dprintk("Invalid encoded frequency (%u vs. %u)\n",
615     - extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
616     - centrino_model[cpu]->op_points[i].frequency);
617     + extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
618     + centrino_model[cpu]->op_points[i].frequency);
619     result = -EINVAL;
620     goto err_kfree_all;
621     }
622    
623     if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
624     @@ -551,10 +830,463 @@
625     #else
626     static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; }
627     static inline int centrino_cpu_early_init_acpi(void) { return 0; }
628     #endif
629    
630     +static int centrino_target (struct cpufreq_policy *policy,
631     + unsigned int target_freq,
632     + unsigned int relation);
633     +
634     +
635     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_SYSFS
636     +/************************** sysfs interface for user defined voltage table ************************/
637     +
638     +static struct cpufreq_frequency_table **original_table = NULL;
639     +
640     +static void check_origial_table (unsigned int cpu)
641     +{
642     + int i;
643     +
644     + if (!original_table)
645     + {
646     + original_table = kmalloc(sizeof(struct cpufreq_frequency_table *)*NR_CPUS, GFP_KERNEL);
647     + for (i=0; i < NR_CPUS; i++)
648     + {
649     + original_table[i] = NULL;
650     + }
651     + }
652     +
653     + if (!original_table[cpu])
654     + {
655     + /* Count number of frequencies and allocate memory for a copy */
656     + for (i=0; centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++);
657     + /* Allocate memory to store the copy */
658     + original_table[cpu] = (struct cpufreq_frequency_table*) kmalloc(sizeof(struct cpufreq_frequency_table)*(i+1), GFP_KERNEL);
659     + /* Make copy of frequency/voltage pairs */
660     + for (i=0; centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++)
661     + {
662     + original_table[cpu][i].frequency = centrino_model[cpu]->op_points[i].frequency;
663     + original_table[cpu][i].index = centrino_model[cpu]->op_points[i].index;
664     + }
665     + original_table[cpu][i].frequency = CPUFREQ_TABLE_END;
666     + }
667     +}
668     +
669     +
670     +static ssize_t show_user_voltage (struct cpufreq_policy *policy, char *buf)
671     +{
672     + ssize_t bytes_written = 0;
673     + unsigned int cpu = policy->cpu;
674     + unsigned int op_index = 0;
675     + unsigned int op_count = 0;
676     + unsigned int voltage = 0;
677     + unsigned int frequency = 0;
678     +
679     + //dprintk("showing user voltage table in sysfs\n");
680     +
681     + while ( (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
682     + && (bytes_written<PAGE_SIZE-16) )
683     + {
684     + //dprintk("getting state %i \n", op_index);
685     + frequency = centrino_model[cpu]->op_points[op_index].frequency;
686     + if (frequency != CPUFREQ_ENTRY_INVALID)
687     + {
688     + op_count++;
689     + if (op_count>1)
690     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-1, ",");
691     + voltage = centrino_model[cpu]->op_points[op_index].index;
692     + voltage = 700 + ((voltage & 0xFF) << 4);
693     + //dprintk("writing voltage %i: %u mV \n", op_index, voltage);
694     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-1, "%u",voltage);
695     + }
696     + else
697     + {
698     + // This operating point of the table is invalid, ignoring it.
699     + dprintk("Ignoring invalid operating point %i \n", op_index);
700     + }
701     + op_index++;
702     + }
703     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-1, "\n");
704     + buf[PAGE_SIZE-1] = 0;
705     + return bytes_written;
706     +}
707     +
708     +static ssize_t
709     +store_user_voltage (struct cpufreq_policy *policy, const char *buf, size_t count)
710     +{
711     + unsigned int cpu;
712     + const char *curr_buf;
713     + unsigned int curr_freq;
714     + unsigned int op_index;
715     + int isok;
716     + char *next_buf;
717     + unsigned int op_point;
718     + ssize_t retval;
719     + unsigned int voltage;
720     +
721     + if (!policy)
722     + return -ENODEV;
723     + cpu = policy->cpu;
724     + if (!centrino_model[cpu] || !centrino_model[cpu]->op_points)
725     + return -ENODEV;
726     +
727     + check_origial_table(cpu);
728     +
729     + op_index = 0;
730     + curr_buf = buf;
731     + next_buf = NULL;
732     + isok = 1;
733     +
734     + while ((centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
735     + && (isok))
736     + {
737     + if (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_ENTRY_INVALID)
738     + {
739     + voltage = simple_strtoul(curr_buf, &next_buf, 10);
740     + if ((next_buf != curr_buf) && (next_buf != NULL))
741     + {
742     + if ((voltage >= 700) && (voltage<=1600))
743     + {
744     + voltage = ((voltage - 700) >> 4) & 0xFF;
745     + op_point = (original_table[cpu])[op_index].index;
746     + if (voltage <= (op_point & 0xFF))
747     + {
748     + //dprintk("setting control value %i to %04x\n", op_index, op_point);
749     + op_point = (op_point & 0xFFFFFF00) | voltage;
750     + centrino_model[cpu]->op_points[op_index].index = op_point;
751     + }
752     + else
753     + {
754     + op_point = (op_point & 0xFFFFFF00) | voltage;
755     + dprintk("not setting control value %i to %04x because requested voltage is not lower than the default value\n", op_index, op_point);
756     + //isok = 0;
757     + }
758     + }
759     + else
760     + {
761     + dprintk("voltage value %i is out of bounds: %u mV\n", op_index, voltage);
762     + isok = 0;
763     + }
764     + curr_buf = next_buf;
765     + if (*curr_buf==',')
766     + curr_buf++;
767     + next_buf = NULL;
768     + }
769     + else
770     + {
771     + dprintk("failed to parse voltage value %i\n", op_index);
772     + isok = 0;
773     + }
774     + }
775     + else
776     + {
777     + // This operating point of the table is invalid, ignoring it.
778     + dprintk("Ignoring invalid operating point %i \n", op_index);
779     + }
780     + op_index++;
781     + }
782     +
783     + if (isok)
784     + {
785     + retval = count;
786     + curr_freq = policy->cur;
787     + centrino_target(policy, curr_freq, CPUFREQ_RELATION_L);
788     + }
789     + else
790     + {
791     + retval = -EINVAL;
792     + }
793     +
794     + return retval;
795     +}
796     +
797     +static struct freq_attr centrino_freq_attr_voltage_table =
798     +{
799     + .attr = { .name = "voltage_table", .mode = 0644, .owner = THIS_MODULE },
800     + .show = show_user_voltage,
801     + .store = store_user_voltage,
802     +};
803     +
804     +
805     +static ssize_t show_user_op_points (struct cpufreq_policy *policy, char *buf)
806     +{
807     + ssize_t bytes_written = 0;
808     + unsigned int cpu = policy->cpu;
809     + unsigned int op_index = 0;
810     + unsigned int op_count = 0;
811     + unsigned int voltage = 0;
812     + unsigned int frequency = 0;
813     +
814     + //dprintk("showing user voltage table in sysfs\n");
815     +
816     + while ( (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
817     + && (bytes_written<PAGE_SIZE-16) )
818     + {
819     + //dprintk("getting state %i \n", i);
820     + frequency = centrino_model[cpu]->op_points[op_index].frequency;
821     + if (frequency != CPUFREQ_ENTRY_INVALID)
822     + {
823     + op_count++;
824     + if (op_count>1)
825     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-1, ",");
826     + voltage = centrino_model[cpu]->op_points[op_index].index;
827     + voltage = 700 + ((voltage & 0xFF) << 4);
828     + //dprintk("writing voltage %i: %u mV \n", i, voltage);
829     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-2, "%u:%u",frequency,voltage);
830     + }
831     + else
832     + {
833     + // This operating point of the table is invalid, ignoring it.
834     + dprintk("Ignoring invalid operating point %i \n", op_index);
835     + }
836     + op_index++;
837     + }
838     + bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE-bytes_written-1, "\n");
839     + buf[PAGE_SIZE-1] = 0;
840     + return bytes_written;
841     +}
842     +
843     +static ssize_t
844     +store_user_op_points (struct cpufreq_policy *policy, const char *buf, size_t count)
845     +{
846     + unsigned int cpu;
847     + const char *curr_buf;
848     + unsigned int curr_freq;
849     + unsigned int op_index;
850     + unsigned int op_count;
851     + int isok;
852     + char *next_buf;
853     + unsigned int op_point;
854     + ssize_t retval;
855     + unsigned int voltage;
856     + unsigned int frequency;
857     + int found;
858     +
859     + if (!policy)
860     + return -ENODEV;
861     + cpu = policy->cpu;
862     + if (!centrino_model[cpu] || !centrino_model[cpu]->op_points)
863     + return -ENODEV;
864     +
865     + check_origial_table(cpu);
866     +
867     + op_count = 0;
868     + curr_buf = buf;
869     + next_buf = NULL;
870     + isok = 1;
871     +
872     + while ( (isok) && (curr_buf != NULL) )
873     + {
874     + op_count++;
875     + // Parse frequency
876     + frequency = simple_strtoul(curr_buf, &next_buf, 10);
877     + if ((next_buf != curr_buf) && (next_buf != NULL))
878     + {
879     + // Parse separator between frequency and voltage
880     + curr_buf = next_buf;
881     + next_buf = NULL;
882     + if (*curr_buf==':')
883     + {
884     + curr_buf++;
885     + // Parse voltage
886     + voltage = simple_strtoul(curr_buf, &next_buf, 10);
887     + if ((next_buf != curr_buf) && (next_buf != NULL))
888     + {
889     + if ((voltage >= 700) && (voltage<=1600))
890     + {
891     + voltage = ((voltage - 700) >> 4) & 0xFF;
892     + op_index = 0;
893     + found = 0;
894     + while (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
895     + {
896     + if ((centrino_model[cpu]->op_points[op_index].frequency == frequency)
897     + && (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_ENTRY_INVALID))
898     + {
899     + found = 1;
900     + op_point = (original_table[cpu])[op_index].index;
901     + if (voltage <= (op_point & 0xFF))
902     + {
903     + //dprintk("setting control value %i to %04x\n", op_index, op_point);
904     + op_point = (op_point & 0xFFFFFF00) | voltage;
905     + centrino_model[cpu]->op_points[op_index].index = op_point;
906     + }
907     + else
908     + {
909     + op_point = (op_point & 0xFFFFFF00) | voltage;
910     + dprintk("not setting control value %i to %04x because requested voltage is not lower than the default value (%u MHz)\n", op_index, op_point, frequency);
911     + }
912     + }
913     + op_index++;
914     + }
915     + if (found == 0)
916     + {
917     + dprintk("operating point # %u not found: %u MHz\n", op_count, frequency);
918     + isok = 0;
919     + }
920     + }
921     + else
922     + {
923     + dprintk("operating point # %u voltage value is out of bounds: %u mV\n", op_count, voltage);
924     + isok = 0;
925     + }
926     + // Parse seprator before next operating point, if any
927     + curr_buf = next_buf;
928     + next_buf = NULL;
929     + if (*curr_buf==',')
930     + curr_buf++;
931     + else
932     + curr_buf = NULL;
933     + }
934     + else
935     + {
936     + dprintk("failed to parse operating point # %u voltage\n", op_count);
937     + isok = 0;
938     + }
939     + }
940     + else
941     + {
942     + dprintk("failed to parse operating point # %u\n", op_count);
943     + isok = 0;
944     + }
945     + }
946     + else
947     + {
948     + dprintk("failed to parse operating point # %u frequency\n", op_count);
949     + isok = 0;
950     + }
951     + }
952     +
953     + if (isok)
954     + {
955     + retval = count;
956     + curr_freq = policy->cur;
957     + centrino_target(policy, curr_freq, CPUFREQ_RELATION_L);
958     + }
959     + else
960     + {
961     + retval = -EINVAL;
962     + }
963     +
964     + return retval;
965     +}
966     +
967     +static struct freq_attr centrino_freq_attr_op_points_table =
968     +{
969     + .attr = { .name = "op_points_table", .mode = 0644, .owner = THIS_MODULE },
970     + .show = show_user_op_points,
971     + .store = store_user_op_points,
972     +};
973     +
974     +unsigned long rounded_div(unsigned long x, unsigned long y)
975     +{
976     + return (((x*2) / y)+1)/2;
977     +}
978     +
979     +static ssize_t show_FSB_base_freq (struct cpufreq_policy *policy, char *buf)
980     +{
981     + ssize_t bytes_written = 0;
982     + unsigned int cpu = policy->cpu;
983     + unsigned int frequency;
984     + unsigned int index;
985     + unsigned int op_index = 0;
986     +
987     + frequency = centrino_model[cpu]->base_freq;
988     + if (frequency!=0)
989     + {
990     + bytes_written += snprintf (buf, PAGE_SIZE-2, "User defined base FSB frequency:\n%u kHz\n",frequency);
991     + }
992     +
993     + bytes_written += snprintf (buf+bytes_written, PAGE_SIZE-bytes_written-2,
994     + "Base FSB frequency computed from operating points table:\n");
995     +
996     + check_origial_table(cpu);
997     + while ((original_table[cpu][op_index].frequency != CPUFREQ_TABLE_END)
998     + && (bytes_written < PAGE_SIZE-3))
999     + {
1000     + index = original_table[cpu][op_index].index;
1001     + index = (index >> 8) & 0xFF;
1002     + if (index > 0)
1003     + {
1004     + frequency = rounded_div((original_table[cpu][op_index].frequency), index);
1005     + bytes_written += snprintf (buf+bytes_written, PAGE_SIZE-bytes_written-2, "%u kHz (%u / %u)\n",
1006     + frequency, original_table[cpu][op_index].frequency, index);
1007     + }
1008     + op_index++;
1009     + }
1010     +
1011     + buf[PAGE_SIZE-1] = 0;
1012     + return bytes_written;
1013     +}
1014     +
1015     +static ssize_t
1016     +store_FSB_base_freq (struct cpufreq_policy *policy, const char *buf, size_t count)
1017     +{
1018     + unsigned int cpu;
1019     + const char *curr_buf;
1020     + unsigned int curr_freq;
1021     + unsigned int frequency;
1022     + unsigned int index;
1023     + char *next_buf;
1024     + unsigned int op_index = 0;
1025     + ssize_t retval;
1026     +
1027     + if (!policy)
1028     + return -ENODEV;
1029     + cpu = policy->cpu;
1030     + if (!centrino_model[cpu] || !centrino_model[cpu]->op_points)
1031     + return -ENODEV;
1032     +
1033     + curr_buf = buf;
1034     + next_buf = NULL;
1035     + frequency = simple_strtoul(curr_buf, &next_buf, 10);
1036     + if ((next_buf != curr_buf) && (next_buf != NULL))
1037     + {
1038     + if (centrino_model[cpu]->base_freq != frequency)
1039     + {
1040     + centrino_model[cpu]->base_freq = frequency;
1041     +
1042     + check_origial_table(cpu);
1043     + while (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
1044     + {
1045     + if (frequency>0)
1046     + {
1047     + index = original_table[cpu][op_index].index;
1048     + index = (index >> 8) & 0xFF;
1049     + if (index > 0)
1050     + {
1051     + centrino_model[cpu]->op_points[op_index].frequency = frequency * index;
1052     + }
1053     + }
1054     + else
1055     + {
1056     + centrino_model[cpu]->op_points[op_index].frequency = original_table[cpu][op_index].frequency;
1057     + }
1058     + op_index++;
1059     + }
1060     + }
1061     +
1062     + retval = count;
1063     + curr_freq = policy->cur;
1064     + centrino_target(policy, curr_freq, CPUFREQ_RELATION_L);
1065     + }
1066     + else
1067     + {
1068     + retval = -EINVAL;
1069     + }
1070     +
1071     + return retval;
1072     +}
1073     +
1074     +static struct freq_attr centrino_freq_attr_FSB_Base_Freq =
1075     +{
1076     + .attr = { .name = "FSB_base_frequency", .mode = 0644, .owner = THIS_MODULE },
1077     + .show = show_FSB_base_freq,
1078     + .store = store_FSB_base_freq,
1079     +};
1080     +
1081     +#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_SYSFS */
1082     +
1083     static int centrino_cpu_init(struct cpufreq_policy *policy)
1084     {
1085     struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
1086     unsigned freq;
1087     unsigned l, h;
1088     @@ -802,10 +1534,15 @@
1089     return 0;
1090     }
1091    
1092     static struct freq_attr* centrino_attr[] = {
1093     &cpufreq_freq_attr_scaling_available_freqs,
1094     +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_SYSFS
1095     + &centrino_freq_attr_voltage_table,
1096     + &centrino_freq_attr_op_points_table,
1097     + &centrino_freq_attr_FSB_Base_Freq,
1098     +#endif
1099     NULL,
1100     };
1101    
1102     static struct cpufreq_driver centrino_driver = {
1103     .name = "centrino", /* should be speedstep-centrino,
1104     @@ -866,5 +1603,6 @@
1105     MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
1106     MODULE_LICENSE ("GPL");
1107    
1108     late_initcall(centrino_init);
1109     module_exit(centrino_exit);
1110     +