aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2012-01-25 18:09:12 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-26 19:49:06 -0500
commitfa8031aefec0cf7ea6c2387c93610d99d9659aa2 (patch)
treea174505948159296198a66874655868b78718bde
parent2f1e097e24defe64a86535b53768f5c8ab0368d1 (diff)
cpufreq: Add support for x86 cpuinfo auto loading v4
This marks all the x86 cpuinfo tables to the CPU specific device drivers, to allow auto loading by udev. This should simplify the distribution startup scripts for this greatly. I didn't add MODULE_DEVICE_IDs to the centrino and p4-clockmod drivers, because those probably shouldn't be auto loaded and the acpi driver be used instead (not fully sure on that, would appreciate feedback) The old nforce drivers autoload based on the PCI ID. ACPI cpufreq is autoloaded in another patch. v3: Autoload gx based on PCI IDs only. Remove cpu check (Dave Jones) v4: Use newly introduce HW_PSTATE feature for powernow-k8 loading Cc: Dave Jones <davej@redhat.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Thomas Renninger <trenn@suse.de> Acked-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/cpufreq/cpufreq-nforce2.c8
-rw-r--r--drivers/cpufreq/e_powersaver.c20
-rw-r--r--drivers/cpufreq/elanfreq.c14
-rw-r--r--drivers/cpufreq/gx-suspmod.c9
-rw-r--r--drivers/cpufreq/longhaul.c8
-rw-r--r--drivers/cpufreq/longrun.c13
-rw-r--r--drivers/cpufreq/p4-clockmod.c17
-rw-r--r--drivers/cpufreq/powernow-k6.c12
-rw-r--r--drivers/cpufreq/powernow-k7.c14
-rw-r--r--drivers/cpufreq/powernow-k8.c19
-rw-r--r--drivers/cpufreq/sc520_freq.c14
-rw-r--r--drivers/cpufreq/speedstep-centrino.c24
-rw-r--r--drivers/cpufreq/speedstep-ich.c15
-rw-r--r--drivers/cpufreq/speedstep-lib.c1
-rw-r--r--drivers/cpufreq/speedstep-smi.c15
15 files changed, 142 insertions, 61 deletions
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c
index 7bac808804f3..13d311ee08b3 100644
--- a/drivers/cpufreq/cpufreq-nforce2.c
+++ b/drivers/cpufreq/cpufreq-nforce2.c
@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = {
385 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
386}; 386};
387 387
388#ifdef MODULE
389static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
390 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 },
391 {}
392};
393MODULE_DEVICE_TABLE(pci, nforce2_ids);
394#endif
395
388/** 396/**
389 * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic 397 * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
390 * 398 *
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index 4bd6815d317b..3fffbe6025cd 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -16,6 +16,7 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18 18
19#include <asm/cpu_device_id.h>
19#include <asm/msr.h> 20#include <asm/msr.h>
20#include <asm/tsc.h> 21#include <asm/tsc.h>
21 22
@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = {
437 .attr = eps_attr, 438 .attr = eps_attr,
438}; 439};
439 440
441
442/* This driver will work only on Centaur C7 processors with
443 * Enhanced SpeedStep/PowerSaver registers */
444static const struct x86_cpu_id eps_cpu_id[] = {
445 { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
446 {}
447};
448MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
449
440static int __init eps_init(void) 450static int __init eps_init(void)
441{ 451{
442 struct cpuinfo_x86 *c = &cpu_data(0); 452 if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
443
444 /* This driver will work only on Centaur C7 processors with
445 * Enhanced SpeedStep/PowerSaver registers */
446 if (c->x86_vendor != X86_VENDOR_CENTAUR
447 || c->x86 != 6 || c->x86_model < 10)
448 return -ENODEV;
449 if (!cpu_has(c, X86_FEATURE_EST))
450 return -ENODEV; 453 return -ENODEV;
451
452 if (cpufreq_register_driver(&eps_driver)) 454 if (cpufreq_register_driver(&eps_driver))
453 return -EINVAL; 455 return -EINVAL;
454 return 0; 456 return 0;
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index c587db472a75..960671fd3d7e 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/cpufreq.h> 24#include <linux/cpufreq.h>
25 25
26#include <asm/cpu_device_id.h>
26#include <asm/msr.h> 27#include <asm/msr.h>
27#include <linux/timex.h> 28#include <linux/timex.h>
28#include <linux/io.h> 29#include <linux/io.h>
@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = {
277 .attr = elanfreq_attr, 278 .attr = elanfreq_attr,
278}; 279};
279 280
281static const struct x86_cpu_id elan_id[] = {
282 { X86_VENDOR_AMD, 4, 10, },
283 {}
284};
285MODULE_DEVICE_TABLE(x86cpu, elan_id);
280 286
281static int __init elanfreq_init(void) 287static int __init elanfreq_init(void)
282{ 288{
283 struct cpuinfo_x86 *c = &cpu_data(0); 289 if (!x86_match_cpu(elan_id))
284
285 /* Test if we have the right hardware */
286 if ((c->x86_vendor != X86_VENDOR_AMD) ||
287 (c->x86 != 4) || (c->x86_model != 10)) {
288 printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
289 return -ENODEV; 290 return -ENODEV;
290 }
291 return cpufreq_register_driver(&elanfreq_driver); 291 return cpufreq_register_driver(&elanfreq_driver);
292} 292}
293 293
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c
index ffe1f2c92ed3..5a06c0ba2452 100644
--- a/drivers/cpufreq/gx-suspmod.c
+++ b/drivers/cpufreq/gx-suspmod.c
@@ -82,6 +82,7 @@
82#include <linux/errno.h> 82#include <linux/errno.h>
83#include <linux/slab.h> 83#include <linux/slab.h>
84 84
85#include <asm/cpu_device_id.h>
85#include <asm/processor-cyrix.h> 86#include <asm/processor-cyrix.h>
86 87
87/* PCI config registers, all at F0 */ 88/* PCI config registers, all at F0 */
@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = {
171 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, 172 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
172 { 0, }, 173 { 0, },
173}; 174};
175MODULE_DEVICE_TABLE(gx_chipset_tbl);
174 176
175static void gx_write_byte(int reg, int value) 177static void gx_write_byte(int reg, int value)
176{ 178{
@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void)
185{ 187{
186 struct pci_dev *gx_pci = NULL; 188 struct pci_dev *gx_pci = NULL;
187 189
188 /* check if CPU is a MediaGX or a Geode. */
189 if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
190 (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
191 pr_debug("error: no MediaGX/Geode processor found!\n");
192 return NULL;
193 }
194
195 /* detect which companion chip is used */ 190 /* detect which companion chip is used */
196 for_each_pci_dev(gx_pci) { 191 for_each_pci_dev(gx_pci) {
197 if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) 192 if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index f47d26e2a135..53ddbc760af7 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -35,6 +35,7 @@
35#include <linux/acpi.h> 35#include <linux/acpi.h>
36 36
37#include <asm/msr.h> 37#include <asm/msr.h>
38#include <asm/cpu_device_id.h>
38#include <acpi/processor.h> 39#include <acpi/processor.h>
39 40
40#include "longhaul.h" 41#include "longhaul.h"
@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = {
951 .attr = longhaul_attr, 952 .attr = longhaul_attr,
952}; 953};
953 954
955static const struct x86_cpu_id longhaul_id[] = {
956 { X86_VENDOR_CENTAUR, 6 },
957 {}
958};
959MODULE_DEVICE_TABLE(x86cpu, longhaul_id);
954 960
955static int __init longhaul_init(void) 961static int __init longhaul_init(void)
956{ 962{
957 struct cpuinfo_x86 *c = &cpu_data(0); 963 struct cpuinfo_x86 *c = &cpu_data(0);
958 964
959 if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6) 965 if (!x86_match_cpu(longhaul_id))
960 return -ENODEV; 966 return -ENODEV;
961 967
962#ifdef CONFIG_SMP 968#ifdef CONFIG_SMP
diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c
index 34ea359b370e..8bc9f5fbbaeb 100644
--- a/drivers/cpufreq/longrun.c
+++ b/drivers/cpufreq/longrun.c
@@ -14,6 +14,7 @@
14 14
15#include <asm/msr.h> 15#include <asm/msr.h>
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/cpu_device_id.h>
17 18
18static struct cpufreq_driver longrun_driver; 19static struct cpufreq_driver longrun_driver;
19 20
@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = {
288 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
289}; 290};
290 291
292static const struct x86_cpu_id longrun_ids[] = {
293 { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY,
294 X86_FEATURE_LONGRUN },
295 {}
296};
297MODULE_DEVICE_TABLE(x86cpu, longrun_ids);
291 298
292/** 299/**
293 * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver 300 * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {
296 */ 303 */
297static int __init longrun_init(void) 304static int __init longrun_init(void)
298{ 305{
299 struct cpuinfo_x86 *c = &cpu_data(0); 306 if (!x86_match_cpu(longrun_ids))
300
301 if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
302 !cpu_has(c, X86_FEATURE_LONGRUN))
303 return -ENODEV; 307 return -ENODEV;
304
305 return cpufreq_register_driver(&longrun_driver); 308 return cpufreq_register_driver(&longrun_driver);
306} 309}
307 310
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
index 6be3e0760c26..827629c9aad7 100644
--- a/drivers/cpufreq/p4-clockmod.c
+++ b/drivers/cpufreq/p4-clockmod.c
@@ -31,6 +31,7 @@
31#include <asm/processor.h> 31#include <asm/processor.h>
32#include <asm/msr.h> 32#include <asm/msr.h>
33#include <asm/timer.h> 33#include <asm/timer.h>
34#include <asm/cpu_device_id.h>
34 35
35#include "speedstep-lib.h" 36#include "speedstep-lib.h"
36 37
@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = {
289 .attr = p4clockmod_attr, 290 .attr = p4clockmod_attr,
290}; 291};
291 292
293static const struct x86_cpu_id cpufreq_p4_id[] = {
294 { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC },
295 {}
296};
297
298/*
299 * Intentionally no MODULE_DEVICE_TABLE here: this driver should not
300 * be auto loaded. Please don't add one.
301 */
292 302
293static int __init cpufreq_p4_init(void) 303static int __init cpufreq_p4_init(void)
294{ 304{
295 struct cpuinfo_x86 *c = &cpu_data(0);
296 int ret; 305 int ret;
297 306
298 /* 307 /*
299 * THERM_CONTROL is architectural for IA32 now, so 308 * THERM_CONTROL is architectural for IA32 now, so
300 * we can rely on the capability checks 309 * we can rely on the capability checks
301 */ 310 */
302 if (c->x86_vendor != X86_VENDOR_INTEL) 311 if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI))
303 return -ENODEV;
304
305 if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
306 !test_cpu_cap(c, X86_FEATURE_ACC))
307 return -ENODEV; 312 return -ENODEV;
308 313
309 ret = cpufreq_register_driver(&p4clockmod_driver); 314 ret = cpufreq_register_driver(&p4clockmod_driver);
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index b3379d6a5c57..54dd031394f6 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -16,6 +16,7 @@
16#include <linux/timex.h> 16#include <linux/timex.h>
17#include <linux/io.h> 17#include <linux/io.h>
18 18
19#include <asm/cpu_device_id.h>
19#include <asm/msr.h> 20#include <asm/msr.h>
20 21
21#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long 22#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = {
210 .attr = powernow_k6_attr, 211 .attr = powernow_k6_attr,
211}; 212};
212 213
214static const struct x86_cpu_id powernow_k6_ids[] = {
215 { X86_VENDOR_AMD, 5, 12 },
216 { X86_VENDOR_AMD, 5, 13 },
217 {}
218};
219
213 220
214/** 221/**
215 * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver 222 * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {
220 */ 227 */
221static int __init powernow_k6_init(void) 228static int __init powernow_k6_init(void)
222{ 229{
223 struct cpuinfo_x86 *c = &cpu_data(0); 230 if (!x86_match_cpu(powernow_k6_ids))
224
225 if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
226 ((c->x86_model != 12) && (c->x86_model != 13)))
227 return -ENODEV; 231 return -ENODEV;
228 232
229 if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { 233 if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index d71d9f372359..501d167368d2 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -28,6 +28,7 @@
28#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */ 28#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
29#include <asm/msr.h> 29#include <asm/msr.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/cpu_device_id.h>
31 32
32#ifdef CONFIG_X86_POWERNOW_K7_ACPI 33#ifdef CONFIG_X86_POWERNOW_K7_ACPI
33#include <linux/acpi.h> 34#include <linux/acpi.h>
@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)
110 return delta < 5; 111 return delta < 5;
111} 112}
112 113
114static const struct x86_cpu_id powernow_k7_cpuids[] = {
115 { X86_VENDOR_AMD, 7, },
116 {}
117};
118MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
119
113static int check_powernow(void) 120static int check_powernow(void)
114{ 121{
115 struct cpuinfo_x86 *c = &cpu_data(0); 122 struct cpuinfo_x86 *c = &cpu_data(0);
116 unsigned int maxei, eax, ebx, ecx, edx; 123 unsigned int maxei, eax, ebx, ecx, edx;
117 124
118 if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) { 125 if (!x86_match_cpu(powernow_k7_cpuids))
119#ifdef MODULE
120 printk(KERN_INFO PFX "This module only works with "
121 "AMD K7 CPUs\n");
122#endif
123 return 0; 126 return 0;
124 }
125 127
126 /* Get maximum capabilities */ 128 /* Get maximum capabilities */
127 maxei = cpuid_eax(0x80000000); 129 maxei = cpuid_eax(0x80000000);
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 8f9b2ceeec85..c0e816468e30 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -40,6 +40,7 @@
40#include <linux/delay.h> 40#include <linux/delay.h>
41 41
42#include <asm/msr.h> 42#include <asm/msr.h>
43#include <asm/cpu_device_id.h>
43 44
44#include <linux/acpi.h> 45#include <linux/acpi.h>
45#include <linux/mutex.h> 46#include <linux/mutex.h>
@@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
520 return 0; 521 return 0;
521} 522}
522 523
524static const struct x86_cpu_id powernow_k8_ids[] = {
525 /* IO based frequency switching */
526 { X86_VENDOR_AMD, 0xf },
527 /* MSR based frequency switching supported */
528 X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
529 {}
530};
531MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
532
523static void check_supported_cpu(void *_rc) 533static void check_supported_cpu(void *_rc)
524{ 534{
525 u32 eax, ebx, ecx, edx; 535 u32 eax, ebx, ecx, edx;
@@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc)
527 537
528 *rc = -ENODEV; 538 *rc = -ENODEV;
529 539
530 if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
531 return;
532
533 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); 540 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
534 if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
535 ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
536 return;
537 541
538 if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { 542 if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
539 if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || 543 if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
@@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void)
1553 unsigned int i, supported_cpus = 0, cpu; 1557 unsigned int i, supported_cpus = 0, cpu;
1554 int rv; 1558 int rv;
1555 1559
1560 if (!x86_match_cpu(powernow_k8_ids))
1561 return -ENODEV;
1562
1556 for_each_online_cpu(i) { 1563 for_each_online_cpu(i) {
1557 int rc; 1564 int rc;
1558 smp_call_function_single(i, check_supported_cpu, &rc, 1); 1565 smp_call_function_single(i, check_supported_cpu, &rc, 1);
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
index 1e205e6b1727..e42e073cd9b8 100644
--- a/drivers/cpufreq/sc520_freq.c
+++ b/drivers/cpufreq/sc520_freq.c
@@ -22,6 +22,7 @@
22#include <linux/timex.h> 22#include <linux/timex.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24
25#include <asm/cpu_device_id.h>
25#include <asm/msr.h> 26#include <asm/msr.h>
26 27
27#define MMCR_BASE 0xfffef000 /* The default base address */ 28#define MMCR_BASE 0xfffef000 /* The default base address */
@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = {
150 .attr = sc520_freq_attr, 151 .attr = sc520_freq_attr,
151}; 152};
152 153
154static const struct x86_cpu_id sc520_ids[] = {
155 { X86_VENDOR_AMD, 4, 9 },
156 {}
157};
158MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
153 159
154static int __init sc520_freq_init(void) 160static int __init sc520_freq_init(void)
155{ 161{
156 struct cpuinfo_x86 *c = &cpu_data(0);
157 int err; 162 int err;
158 163
159 /* Test if we have the right hardware */ 164 if (!x86_match_cpu(sc520_ids))
160 if (c->x86_vendor != X86_VENDOR_AMD ||
161 c->x86 != 4 || c->x86_model != 9) {
162 pr_debug("no Elan SC520 processor found!\n");
163 return -ENODEV; 165 return -ENODEV;
164 } 166
165 cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); 167 cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
166 if (!cpuctl) { 168 if (!cpuctl) {
167 printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); 169 printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index 6ea3455def21..3a953d519f46 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -25,6 +25,7 @@
25#include <asm/msr.h> 25#include <asm/msr.h>
26#include <asm/processor.h> 26#include <asm/processor.h>
27#include <asm/cpufeature.h> 27#include <asm/cpufeature.h>
28#include <asm/cpu_device_id.h>
28 29
29#define PFX "speedstep-centrino: " 30#define PFX "speedstep-centrino: "
30#define MAINTAINER "cpufreq@vger.kernel.org" 31#define MAINTAINER "cpufreq@vger.kernel.org"
@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = {
595 .owner = THIS_MODULE, 596 .owner = THIS_MODULE,
596}; 597};
597 598
599/*
600 * This doesn't replace the detailed checks above because
601 * the generic CPU IDs don't have a way to match for steppings
602 * or ASCII model IDs.
603 */
604static const struct x86_cpu_id centrino_ids[] = {
605 { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST },
606 { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
607 { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
608 { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
609 { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST },
610 { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST },
611 {}
612};
613#if 0
614/* Autoload or not? Do not for now. */
615MODULE_DEVICE_TABLE(x86cpu, centrino_ids);
616#endif
598 617
599/** 618/**
600 * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver 619 * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {
612 */ 631 */
613static int __init centrino_init(void) 632static int __init centrino_init(void)
614{ 633{
615 struct cpuinfo_x86 *cpu = &cpu_data(0); 634 if (!x86_match_cpu(centrino_ids))
616
617 if (!cpu_has(cpu, X86_FEATURE_EST))
618 return -ENODEV; 635 return -ENODEV;
619
620 return cpufreq_register_driver(&centrino_driver); 636 return cpufreq_register_driver(&centrino_driver);
621} 637}
622 638
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index a748ce782fee..7432b3a72cd4 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -25,6 +25,8 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27 27
28#include <asm/cpu_device_id.h>
29
28#include "speedstep-lib.h" 30#include "speedstep-lib.h"
29 31
30 32
@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = {
388 .attr = speedstep_attr, 390 .attr = speedstep_attr,
389}; 391};
390 392
393static const struct x86_cpu_id ss_smi_ids[] = {
394 { X86_VENDOR_INTEL, 6, 0xb, },
395 { X86_VENDOR_INTEL, 6, 0x8, },
396 { X86_VENDOR_INTEL, 15, 2 },
397 {}
398};
399#if 0
400/* Autoload or not? Do not for now. */
401MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
402#endif
391 403
392/** 404/**
393 * speedstep_init - initializes the SpeedStep CPUFreq driver 405 * speedstep_init - initializes the SpeedStep CPUFreq driver
@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {
398 */ 410 */
399static int __init speedstep_init(void) 411static int __init speedstep_init(void)
400{ 412{
413 if (!x86_match_cpu(ss_smi_ids))
414 return -ENODEV;
415
401 /* detect processor */ 416 /* detect processor */
402 speedstep_processor = speedstep_detect_processor(); 417 speedstep_processor = speedstep_detect_processor();
403 if (!speedstep_processor) { 418 if (!speedstep_processor) {
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c
index 8af2d2fd9d51..7047821a7f8a 100644
--- a/drivers/cpufreq/speedstep-lib.c
+++ b/drivers/cpufreq/speedstep-lib.c
@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
249 * DETECT SPEEDSTEP-CAPABLE PROCESSOR * 249 * DETECT SPEEDSTEP-CAPABLE PROCESSOR *
250 *********************************************************************/ 250 *********************************************************************/
251 251
252/* Keep in sync with the x86_cpu_id tables in the different modules */
252unsigned int speedstep_detect_processor(void) 253unsigned int speedstep_detect_processor(void)
253{ 254{
254 struct cpuinfo_x86 *c = &cpu_data(0); 255 struct cpuinfo_x86 *c = &cpu_data(0);
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index c76ead3490bf..6a457fcaaad5 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <asm/ist.h> 22#include <asm/ist.h>
23#include <asm/cpu_device_id.h>
23 24
24#include "speedstep-lib.h" 25#include "speedstep-lib.h"
25 26
@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = {
379 .attr = speedstep_attr, 380 .attr = speedstep_attr,
380}; 381};
381 382
383static const struct x86_cpu_id ss_smi_ids[] = {
384 { X86_VENDOR_INTEL, 6, 0xb, },
385 { X86_VENDOR_INTEL, 6, 0x8, },
386 { X86_VENDOR_INTEL, 15, 2 },
387 {}
388};
389#if 0
390/* Not auto loaded currently */
391MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
392#endif
393
382/** 394/**
383 * speedstep_init - initializes the SpeedStep CPUFreq driver 395 * speedstep_init - initializes the SpeedStep CPUFreq driver
384 * 396 *
@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {
388 */ 400 */
389static int __init speedstep_init(void) 401static int __init speedstep_init(void)
390{ 402{
403 if (!x86_match_cpu(ss_smi_ids))
404 return -ENODEV;
405
391 speedstep_processor = speedstep_detect_processor(); 406 speedstep_processor = speedstep_detect_processor();
392 407
393 switch (speedstep_processor) { 408 switch (speedstep_processor) {