CPUID based driver autoloading v3
Subsystems (12)
Automatically load drivers based on the x86 cpuid.
I made some mistake in the last post with missing patches and wrong numbering. Here's a v3 that should be better.
The only code change is the removal of the Cyrix CPUID match as Dave Jones suggested.
-Andi
PATCH 1/8 Add driver auto probing for x86 features v2
From: Andi Kleen <[email protected]>
Old patchkit, resurrect due to popular demand.
There's a growing number of drivers that support a specific x86 feature or CPU. Currently loading these drivers currently on a generic distribution requires various driver specific hacks and it often doesn't work.
This patch adds auto probing for drivers based on the x86 cpuid information, in particular based on vendor/family/model number and also based on CPUID feature bits.
For example a common issue is not loading the SSE 4.2 accelerated CRC module: this can significantly lower the performance of BTRFS which relies on fast CRC.
Another issue is loading the right CPUFREQ driver for the current CPU. Currently distributions often try all all possible driver until one sticks, which is not really a good way to do this.
It works with existing udev without any changes. The code exports the x86 information as a generic string in sysfs that can be matched by udev's pattern matching.
This scheme does not support numeric ranges, so if you want to handle e.g. ranges of model numbers they have to be encoded in ASCII or simply all models or families listed. Fixing that would require changing udev.
Another issue is that udev will happily load all drivers that match, there is currently no nice way to stop a specific driver from being loaded if it's not needed (e.g. if you don't need fast CRC) But there are not that many cpu specific drivers around and they're all not that bloated, so this isn't a particularly serious issue.
Originally this patch added the modalias to the normal cpu sysdevs. However sysdevs don't have all the infrastructure needed for udev, so it couldn't really autoload drivers. This patch instead adds the CPU modaliases to the cpuid devices, which are real devices with full support for udev. This implies that the cpuid driver has to be loaded to use this.
This patch just adds infrastructure, some driver conversions in followups.
Thanks to Kay for helping with some sysfs magic.
v2: Constifcation, some updates
--- arch/x86/include/asm/cpu_device_id.h | 13 +++++++ arch/x86/kernel/cpu/Makefile | 1 + arch/x86/kernel/cpu/match.c | 48 ++++++++++++++++++++++++++++ arch/x86/kernel/cpuid.c | 58 +++++++++++++++++++++++++++++++++- include/linux/mod_devicetable.h | 20 ++++++++++++ scripts/mod/file2alias.c | 27 ++++++++++++++++ 6 files changed, 166 insertions(+), 1 deletions(-) create mode 100755 arch/x86/include/asm/cpu_device_id.h create mode 100644 arch/x86/kernel/cpu/match.c
arch/x86/include/asm/cpu_device_id.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _CPU_DEVICE_ID +#define _CPU_DEVICE_ID 1 + +/* +* Declare drivers belonging to specific x86 CPUs +* Similar in spirit to pci_device_id and related PCI functions +*/ + +#include <linux/mod_devicetable.h> + +extern const struct x86_cpu_id *x86_match_cpu (const struct x86_cpu_id *match); + +#endif
arch/x86/kernel/cpu/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o obj-y += vmware.o hypervisor.o sched.o mshyperv.o obj-y += rdrand.o +obj-y += match.o obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o
arch/x86/kernel/cpu/match.c new file +48 -0
48 lines not on this page · raw message
arch/x86/kernel/cpuid.c +57 -1
88 lines not on this page · raw message
include/linux/mod_devicetable.h +20 -0
@@ -542,4 +542,24 @@ struct isapnp_device_id { kernel_ulong_t driver_data; /* data private to the driver */ }; +/* +* Match x86 CPUs for CPU specific drivers. +* See documentation of "x86_match_cpu" for details. +*/ + +struct x86_cpu_id { +__u16 vendor; +__u16 family; +__u16 model; +__u16 feature;/* bit index */ +kernel_ulong_t driver_data; +}; + +#define X86_FEATURE_MATCH (x) { X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x } + +#define X86_VENDOR_ANY 0xffff +#define X86_FAMILY_ANY 0 +#define X86_MODEL_ANY 0 +#define X86_FEATURE_ANY 0/* Same as FPU, you can't test for that */ +#endif /* LINUX_MOD_DEVICETABLE_H */
scripts/mod/file2alias.c +27 -0
@@ -880,6 +880,29 @@ static int do_isapnp_entry(const char *filename,return 1 ; } +/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* +* All fields are numbers. It would be nicer to use strings for vendor +* and feature, but getting those out of the build system here is too +* complicated. +*/ + +static int do_x86cpu_entry (const char *filename,struct x86_cpu_id *id, +char *alias) +{ + id->feature =TO_NATIVE (id->feature); + id->family =TO_NATIVE (id->family); + id->model =TO_NATIVE (id->model); + id->vendor =TO_NATIVE (id->vendor); + +strcpy (alias,"x86cpu:" ); +ADD (alias,"vendor:" , id->vendor !=X86_VENDOR_ANY , id->vendor); +ADD (alias,":family:" , id->family !=X86_FAMILY_ANY , id->family); +ADD (alias,":model:" , id->model !=X86_MODEL_ANY , id->model); +ADD (alias,":feature:*," , id->feature !=X86_FEATURE_ANY , id->feature); +strcat (alias,",*" ); +return 1 ; +} +/* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is (const char *symbol,const char *name) {
@@ -1047,6 +1070,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,do_table (symval, sym->st_size,sizeof (struct isapnp_device_id ),"isa" , do_isapnp_entry, mod); + else if (sym_is(symname, "__mod_x86cpu_device_table")) + do_table(symval, sym->st_size, + sizeof(struct x86_cpu_id), "x86cpu", + do_x86cpu_entry, mod);free (zeros ); }
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86: Add driver auto probing for x86 features
Commit-ID: faea229b398eac478e065c0726402e7d959b4e4c Gitweb: http://git.kernel.org/tip/faea229b398eac478e065c0726402e7d959b4e4c Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:27 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:25 -0800
x86: Add driver auto probing for x86 features
Old patchkit, resurrect due to popular demand.
There's a growing number of drivers that support a specific x86 feature or CPU. Currently loading these drivers currently on a generic distribution requires various driver specific hacks and it often doesn't work.
This patch adds auto probing for drivers based on the x86 cpuid information, in particular based on vendor/family/model number and also based on CPUID feature bits.
For example a common issue is not loading the SSE 4.2 accelerated CRC module: this can significantly lower the performance of BTRFS which relies on fast CRC.
Another issue is loading the right CPUFREQ driver for the current CPU. Currently distributions often try all all possible driver until one sticks, which is not really a good way to do this.
It works with existing udev without any changes. The code exports the x86 information as a generic string in sysfs that can be matched by udev's pattern matching.
This scheme does not support numeric ranges, so if you want to handle e.g. ranges of model numbers they have to be encoded in ASCII or simply all models or families listed. Fixing that would require changing udev.
Another issue is that udev will happily load all drivers that match, there is currently no nice way to stop a specific driver from being loaded if it's not needed (e.g. if you don't need fast CRC) But there are not that many cpu specific drivers around and they're all not that bloated, so this isn't a particularly serious issue.
Originally this patch added the modalias to the normal cpu sysdevs. However sysdevs don't have all the infrastructure needed for udev, so it couldn't really autoload drivers. This patch instead adds the CPU modaliases to the cpuid devices, which are real devices with full support for udev. This implies that the cpuid driver has to be loaded to use this.
This patch just adds infrastructure, some driver conversions in followups.
Thanks to Kay for helping with some sysfs magic.
v2: Constifcation, some updates
--- arch/x86/include/asm/cpu_device_id.h | 13 +++++++ arch/x86/kernel/cpu/Makefile | 1 + arch/x86/kernel/cpu/match.c | 48 ++++++++++++++++++++++++++++ arch/x86/kernel/cpuid.c | 58 +++++++++++++++++++++++++++++++++- include/linux/mod_devicetable.h | 20 ++++++++++++ scripts/mod/file2alias.c | 27 ++++++++++++++++ 6 files changed, 166 insertions(+), 1 deletions(-)
arch/x86/include/asm/cpu_device_id.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _CPU_DEVICE_ID +#define _CPU_DEVICE_ID 1 + +/* +* Declare drivers belonging to specific x86 CPUs +* Similar in spirit to pci_device_id and related PCI functions +*/ + +#include <linux/mod_devicetable.h> + +extern const struct x86_cpu_id *x86_match_cpu (const struct x86_cpu_id *match); + +#endif
arch/x86/kernel/cpu/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o obj-y += vmware.o hypervisor.o sched.o mshyperv.o obj-y += rdrand.o +obj-y += match.o obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o
arch/x86/kernel/cpu/match.c new file +48 -0
48 lines not on this page · raw message
arch/x86/kernel/cpuid.c +57 -1
88 lines not on this page · raw message
include/linux/mod_devicetable.h +20 -0
@@ -542,4 +542,24 @@ struct isapnp_device_id { kernel_ulong_t driver_data; /* data private to the driver */ }; +/* +* Match x86 CPUs for CPU specific drivers. +* See documentation of "x86_match_cpu" for details. +*/ + +struct x86_cpu_id { +__u16 vendor; +__u16 family; +__u16 model; +__u16 feature;/* bit index */ +kernel_ulong_t driver_data; +}; + +#define X86_FEATURE_MATCH (x) { X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x } + +#define X86_VENDOR_ANY 0xffff +#define X86_FAMILY_ANY 0 +#define X86_MODEL_ANY 0 +#define X86_FEATURE_ANY 0/* Same as FPU, you can't test for that */ +#endif /* LINUX_MOD_DEVICETABLE_H */
scripts/mod/file2alias.c +27 -0
@@ -880,6 +880,29 @@ static int do_isapnp_entry(const char *filename,return 1 ; } +/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* +* All fields are numbers. It would be nicer to use strings for vendor +* and feature, but getting those out of the build system here is too +* complicated. +*/ + +static int do_x86cpu_entry (const char *filename,struct x86_cpu_id *id, +char *alias) +{ + id->feature =TO_NATIVE (id->feature); + id->family =TO_NATIVE (id->family); + id->model =TO_NATIVE (id->model); + id->vendor =TO_NATIVE (id->vendor); + +strcpy (alias,"x86cpu:" ); +ADD (alias,"vendor:" , id->vendor !=X86_VENDOR_ANY , id->vendor); +ADD (alias,":family:" , id->family !=X86_FAMILY_ANY , id->family); +ADD (alias,":model:" , id->model !=X86_MODEL_ANY , id->model); +ADD (alias,":feature:*," , id->feature !=X86_FEATURE_ANY , id->feature); +strcat (alias,",*" ); +return 1 ; +} +/* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is (const char *symbol,const char *name) {
@@ -1047,6 +1070,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,do_table (symval, sym->st_size,sizeof (struct isapnp_device_id ),"isa" , do_isapnp_entry, mod); + else if (sym_is(symname, "__mod_x86cpu_device_table")) + do_table(symval, sym->st_size, + sizeof(struct x86_cpu_id), "x86cpu", + do_x86cpu_entry, mod);free (zeros ); }
Re: [PATCH 1/8] Add driver auto probing for x86 features v2
In reply to Andi KleenHi,
for info:
Quoted 3 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Old patchkit, resurrect due to popular demand.
...
arch/x86/kernel/cpuid.c static const struct file_operations cpuid_fops = { · line 150
Quoted 1 line
arch/x86/kernel/cpuid.c +1
-0+ n = snprintf(buf, size, "x86cpu:vendor:%04x:family:%04x:model:%04x:feature:",
this must be uppercase hex values (%04X)
...
arch/x86/kernel/cpuid.c static const struct file_operations cpuid_fops = { · line 159
Quoted 2 lines
arch/x86/kernel/cpuid.c +2
-0+if (boot_cpu_has (i)) { + n =snprintf (buf, size,",%04x" , i);
same here.
Looks like a string compare is happening and in scripts/mod/file2alias.c
sizeof(field) == 2 ? "%04X"
is used and the modalias added to the driver and showing up in /lib/modules/*/modales.alias is uppercase.
...
arch/x86/kernel/cpuid.c static const struct file_operations cpuid_fops = { · line 169
Quoted 3 lines
arch/x86/kernel/cpuid.c +3
-0+ } + *buf++ =',' ; + *buf++ ='\n' ;
this must be:
+ *buf++ = '\0';
otherwise one can hit:
WARNING: at lib/kobject_uevent.c:362 add_uevent_var+0xf2/0x100() add_uevent_var: buffer size too small
Hm, then /sys/devices/system/cpu/modalias has not a newline. Using kzalloc in arch_cpu_uevent() should be the nicest way to address this.
Now things work much better, hope that's all.
I just send out a new patchset (with cpuid vs cpu kobject broken out in a separate patch for better backporting).
Thomas
PATCH 2/8 crypto: Add support for x86 cpuid auto loading for x86 crypto drivers
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Add support for auto-loading of crypto drivers based on cpuid features. This enables auto-loading of the VIA and Intel specific drivers for AES, hashing and CRCs.
Requires the earlier infrastructure patch to add x86 modinfo. I kept it all in a single patch for now.
I dropped the printks when the driver cpuid doesn't match (imho drivers never should print anything in such a case)
One drawback is that udev doesn't know if the drivers are used or not, so they will be unconditionally loaded at boot up. That's better than not loading them at all, like it often happens.
--- arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++--- arch/x86/crypto/crc32c-intel.c | 11 ++++++++--- arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++---- drivers/crypto/padlock-aes.c | 9 ++++++++- drivers/crypto/padlock-sha.c | 16 ++++++++-------- 5 files changed, 41 insertions(+), 19 deletions(-)
arch/x86/crypto/aesni-intel_glue.c +9 -3
@@ -28,6 +28,7 @@#include <crypto/aes.h> #include <crypto/cryptd.h> #include <crypto/ctr.h> +#include <asm/cpu_device_id.h> #include <asm/i387.h> #include <asm/aes.h> #include <crypto/scatterwalk.h>
@@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = { };#endif + +static const struct x86_cpu_id aesni_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_AES ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, aesni_cpu_id); +static int __init aesni_init (void ) {int err; -if (!cpu_has_aes) { -printk (KERN_INFO "Intel AES-NI instructions are not detected.\n" ); +if (!x86_match_cpu (aesni_cpu_id))return -ENODEV ; - }if ((err =crypto_fpu_init ())) goto fpu_err;
arch/x86/crypto/crc32c-intel.c +8 -3
@@ -31,6 +31,7 @@#include <crypto/internal/hash.h> #include <asm/cpufeature.h> +#include <asm/cpu_device_id.h> #define CHKSUM_BLOCK_SIZE 1#define CHKSUM_DIGEST_SIZE 4
@@ -173,13 +174,17 @@ static struct shash_alg alg = { } }; +static const struct x86_cpu_id crc32c_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_XMM4_2 ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, crc32c_cpu_id);static int __init crc32c_intel_mod_init (void ) { -if (cpu_has_xmm4_2) -return crypto_register_shash (&alg); -else +if (!x86_match_cpu (crc32c_cpu_id))return -ENODEV ; +return crypto_register_shash (&alg); } static void __exit crc32c_intel_mod_fini(void)
arch/x86/crypto/ghash-clmulni-intel_glue.c +8 -4
@@ -20,6 +20,7 @@#include <crypto/gf128mul.h> #include <crypto/internal/hash.h> #include <asm/i387.h> +#include <asm/cpu_device_id.h> #define GHASH_BLOCK_SIZE 16#define GHASH_DIGEST_SIZE 16
@@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = { }, }; +static const struct x86_cpu_id pcmul_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_PCLMULQDQ ),/* Pickle-Mickle-Duck */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, pcmul_cpu_id); +static int __init ghash_pclmulqdqni_mod_init (void ) {int err; -if (!cpu_has_pclmulqdq) { -printk (KERN_INFO "Intel PCLMULQDQ-NI instructions are not" -" detected.\n" ); +if (!x86_match_cpu (pcmul_cpu_id))return -ENODEV ; - } err =crypto_register_shash (&ghash_alg);if (err)
drivers/crypto/padlock-aes.c +8 -1
@@ -19,6 +19,7 @@#include <linux/percpu.h> #include <linux/smp.h> #include <linux/slab.h> +#include <asm/cpu_device_id.h> #include <asm/byteorder.h> #include <asm/processor.h> #include <asm/i387.h>
@@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = { } }; +static struct x86_cpu_id padlock_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_XCRYPT ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, padlock_cpu_id); +static int __init padlock_init (void ) {int ret;struct cpuinfo_x86 *c = &cpu_data (0 ); -if (!cpu_has_xcrypt) +if (!x86_match_cpu (padlock_cpu_id))return -ENODEV ;if (!cpu_has_xcrypt_enabled) {
drivers/crypto/padlock-sha.c +8 -8
@@ -22,6 +22,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/scatterlist.h> +#include <asm/cpu_device_id.h> #include <asm/i387.h> struct padlock_sha_desc {
@@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = { } }; +static struct x86_cpu_id padlock_sha_ids[] = { +X86_FEATURE_MATCH (X86_FEATURE_PHE ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, padlock_sha_ids); +static int __init padlock_init (void ) {int rc = -ENODEV ;
@@ -533,15 +540,8 @@ static int __init padlock_init(void)struct shash_alg *sha1;struct shash_alg *sha256; -if (!cpu_has_phe) { - printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); -return -ENODEV ; - } - -if (!cpu_has_phe_enabled) { - printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); +if (!x86_match_cpu (padlock_sha_ids) || !cpu_has_phe_enabled)return -ENODEV ; - }/* Register the newly added algorithm module if on * * VIA Nano processor, or else just do as before */
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, crypto: Add support for x86 cpuid auto loading for x86 crypto drivers
Commit-ID: 5c60702817b4b1376e633ee23acdd536cda75308 Gitweb: http://git.kernel.org/tip/5c60702817b4b1376e633ee23acdd536cda75308 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:28 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:32 -0800
x86, crypto: Add support for x86 cpuid auto loading for x86 crypto drivers
Add support for auto-loading of crypto drivers based on cpuid features. This enables auto-loading of the VIA and Intel specific drivers for AES, hashing and CRCs.
Requires the earlier infrastructure patch to add x86 modinfo. I kept it all in a single patch for now.
I dropped the printks when the driver cpuid doesn't match (imho drivers never should print anything in such a case)
One drawback is that udev doesn't know if the drivers are used or not, so they will be unconditionally loaded at boot up. That's better than not loading them at all, like it often happens.
--- arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++--- arch/x86/crypto/crc32c-intel.c | 11 ++++++++--- arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++---- drivers/crypto/padlock-aes.c | 9 ++++++++- drivers/crypto/padlock-sha.c | 16 ++++++++-------- 5 files changed, 41 insertions(+), 19 deletions(-)
arch/x86/crypto/aesni-intel_glue.c +9 -3
@@ -28,6 +28,7 @@#include <crypto/aes.h> #include <crypto/cryptd.h> #include <crypto/ctr.h> +#include <asm/cpu_device_id.h> #include <asm/i387.h> #include <asm/aes.h> #include <crypto/scatterwalk.h>
@@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = { };#endif + +static const struct x86_cpu_id aesni_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_AES ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, aesni_cpu_id); +static int __init aesni_init (void ) {int err; -if (!cpu_has_aes) { -printk (KERN_INFO "Intel AES-NI instructions are not detected.\n" ); +if (!x86_match_cpu (aesni_cpu_id))return -ENODEV ; - }if ((err =crypto_fpu_init ())) goto fpu_err;
arch/x86/crypto/crc32c-intel.c +8 -3
@@ -31,6 +31,7 @@#include <crypto/internal/hash.h> #include <asm/cpufeature.h> +#include <asm/cpu_device_id.h> #define CHKSUM_BLOCK_SIZE 1#define CHKSUM_DIGEST_SIZE 4
@@ -173,13 +174,17 @@ static struct shash_alg alg = { } }; +static const struct x86_cpu_id crc32c_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_XMM4_2 ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, crc32c_cpu_id);static int __init crc32c_intel_mod_init (void ) { -if (cpu_has_xmm4_2) -return crypto_register_shash (&alg); -else +if (!x86_match_cpu (crc32c_cpu_id))return -ENODEV ; +return crypto_register_shash (&alg); } static void __exit crc32c_intel_mod_fini(void)
arch/x86/crypto/ghash-clmulni-intel_glue.c +8 -4
@@ -20,6 +20,7 @@#include <crypto/gf128mul.h> #include <crypto/internal/hash.h> #include <asm/i387.h> +#include <asm/cpu_device_id.h> #define GHASH_BLOCK_SIZE 16#define GHASH_DIGEST_SIZE 16
@@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = { }, }; +static const struct x86_cpu_id pcmul_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_PCLMULQDQ ),/* Pickle-Mickle-Duck */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, pcmul_cpu_id); +static int __init ghash_pclmulqdqni_mod_init (void ) {int err; -if (!cpu_has_pclmulqdq) { -printk (KERN_INFO "Intel PCLMULQDQ-NI instructions are not" -" detected.\n" ); +if (!x86_match_cpu (pcmul_cpu_id))return -ENODEV ; - } err =crypto_register_shash (&ghash_alg);if (err)
drivers/crypto/padlock-aes.c +8 -1
@@ -19,6 +19,7 @@#include <linux/percpu.h> #include <linux/smp.h> #include <linux/slab.h> +#include <asm/cpu_device_id.h> #include <asm/byteorder.h> #include <asm/processor.h> #include <asm/i387.h>
@@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = { } }; +static struct x86_cpu_id padlock_cpu_id[] = { +X86_FEATURE_MATCH (X86_FEATURE_XCRYPT ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, padlock_cpu_id); +static int __init padlock_init (void ) {int ret;struct cpuinfo_x86 *c = &cpu_data (0 ); -if (!cpu_has_xcrypt) +if (!x86_match_cpu (padlock_cpu_id))return -ENODEV ;if (!cpu_has_xcrypt_enabled) {
drivers/crypto/padlock-sha.c +8 -8
@@ -22,6 +22,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/scatterlist.h> +#include <asm/cpu_device_id.h> #include <asm/i387.h> struct padlock_sha_desc {
@@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = { } }; +static struct x86_cpu_id padlock_sha_ids[] = { +X86_FEATURE_MATCH (X86_FEATURE_PHE ), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, padlock_sha_ids); +static int __init padlock_init (void ) {int rc = -ENODEV ;
@@ -533,15 +540,8 @@ static int __init padlock_init(void)struct shash_alg *sha1;struct shash_alg *sha256; -if (!cpu_has_phe) { - printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); -return -ENODEV ; - } - -if (!cpu_has_phe_enabled) { - printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); +if (!x86_match_cpu (padlock_sha_ids) || !cpu_has_phe_enabled)return -ENODEV ; - }/* Register the newly added algorithm module if on * * VIA Nano processor, or else just do as before */
PATCH 3/8 intel-idle: convert to x86_cpu_id auto probing
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
With this it should be automatically loaded on suitable systems by udev.
The old switch () is replaced with a table based approach, this also cleans up the code.
--- drivers/idle/intel_idle.c | 116 +++++++++++++++++++++++++------------------- 1 files changed, 66 insertions(+), 50 deletions(-)
drivers/idle/intel_idle.c +66 -50
@@ -62,6 +62,7 @@#include <linux/notifier.h> #include <linux/cpu.h> #include <linux/module.h> +#include <asm/cpu_device_id.h> #include <asm/mwait.h> #include <asm/msr.h>
@@ -81,6 +82,17 @@ static unsigned int mwait_substates;/* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 <<1 );/* Default to only C1 */ +struct idle_cpu { +struct cpuidle_state *state_table; + +/* +* Hardware C-state auto-demotion may not always be optimal. +* Indicate which enable bits to clear here. +*/ +unsigned long auto_demotion_disable_flags; +}; + +static const struct idle_cpu *icpu;static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;static int intel_idle (struct cpuidle_device *dev,struct cpuidle_driver *drv,int index);
@@ -88,12 +100,6 @@ static int intel_idle(struct cpuidle_device *dev,static struct cpuidle_state *cpuidle_state_table;/* -* Hardware C-state auto-demotion may not always be optimal. -* Indicate which enable bits to clear here. -*/ -static unsigned long long auto_demotion_disable_flags; - -/* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. * If this flag is set, SW flushes the TLB, so even if the
@@ -320,27 +326,72 @@ static void auto_demotion_disable(void *dummy)unsigned long long msr_bits;rdmsrl (MSR_NHM_SNB_PKG_CST_CFG_CTL , msr_bits); - msr_bits &= ~auto_demotion_disable_flags; + msr_bits &= ~(icpu->auto_demotion_disable_flags);wrmsrl (MSR_NHM_SNB_PKG_CST_CFG_CTL , msr_bits); } +static const struct idle_cpu idle_cpu_nehalem = { + .state_table = nehalem_cstates, +}; + +static const struct idle_cpu idle_cpu_westmere = { + .state_table = nehalem_cstates, + .auto_demotion_disable_flags =NHM_C1_AUTO_DEMOTE |NHM_C3_AUTO_DEMOTE , +}; + +static const struct idle_cpu idle_cpu_atom = { + .state_table = atom_cstates, +}; + +static const struct idle_cpu idle_cpu_lincroft = { + .state_table = atom_cstates, + .auto_demotion_disable_flags =ATM_LNC_C6_AUTO_DEMOTE , +}; + +static const struct idle_cpu idle_cpu_snb = { + .state_table = snb_cstates, +}; + +#define ICPU (model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } + +static const struct x86_cpu_id intel_idle_ids[] = { +ICPU (0x1a , idle_cpu_nehalem), +ICPU (0x1e , idle_cpu_nehalem), +ICPU (0x1f , idle_cpu_nehalem), +ICPU (0x25 , idle_cpu_westmere), +ICPU (0x2c , idle_cpu_westmere), +ICPU (0x2f , idle_cpu_westmere), +ICPU (0x1c , idle_cpu_atom), +ICPU (0x26 , idle_cpu_lincroft), +ICPU (0x2f , idle_cpu_westmere), +ICPU (0x2a , idle_cpu_snb), +ICPU (0x2d , idle_cpu_snb), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, intel_idle_ids); +/* * intel_idle_probe() */ static int intel_idle_probe (void ) {unsigned int eax, ebx, ecx; +const struct x86_cpu_id *id;if (max_cstate ==0 ) {pr_debug (PREFIX "disabled\n" );return -EPERM ; } -if (boot_cpu_data.x86_vendor !=X86_VENDOR_INTEL ) -return -ENODEV ; - -if (!boot_cpu_has (X86_FEATURE_MWAIT )) + id =x86_match_cpu (intel_idle_ids); +if (!id) { +if (boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL && + boot_cpu_data.x86 ==6 ) +pr_debug (PREFIX "does not run on family %d model %d\n" , + boot_cpu_data.x86, boot_cpu_data.x86_model);return -ENODEV ; + }if (boot_cpu_data.cpuid_level <CPUID_MWAIT_LEAF )return -ENODEV ;
@@ -353,44 +404,9 @@ static int intel_idle_probe(void)pr_debug (PREFIX "MWAIT substates: 0x%x\n" , mwait_substates); - -if (boot_cpu_data.x86 !=6 )/* family 6 */ -return -ENODEV ; - -switch (boot_cpu_data.x86_model) { - -case 0x1A :/* Core i7, Xeon 5500 series */ -case 0x1E :/* Core i7 and i5 Processor - Lynnfield Jasper Forest */ -case 0x1F :/* Core i7 and i5 Processor - Nehalem */ -case 0x2E :/* Nehalem-EX Xeon */ -case 0x2F :/* Westmere-EX Xeon */ -case 0x25 :/* Westmere */ -case 0x2C :/* Westmere */ - cpuidle_state_table = nehalem_cstates; - auto_demotion_disable_flags = - (NHM_C1_AUTO_DEMOTE |NHM_C3_AUTO_DEMOTE ); -break ; - -case 0x1C :/* 28 - Atom Processor */ - cpuidle_state_table = atom_cstates; -break ; - -case 0x26 :/* 38 - Lincroft Atom Processor */ - cpuidle_state_table = atom_cstates; - auto_demotion_disable_flags =ATM_LNC_C6_AUTO_DEMOTE ; -break ; - -case 0x2A :/* SNB */ -case 0x2D :/* SNB Xeon */ - cpuidle_state_table = snb_cstates; -break ; - -default : -pr_debug (PREFIX "does not run on family %d model %d\n" , - boot_cpu_data.x86, boot_cpu_data.x86_model); -return -ENODEV ; - } - + icpu = (const struct idle_cpu *)id->driver_data; + cpuidle_state_table = icpu->state_table; +if (boot_cpu_has (X86_FEATURE_ARAT ))/* Always Reliable APIC Timer */ lapic_timer_reliable_states =LAPIC_TIMER_ALWAYS_RELIABLE ;else {
@@ -470,7 +486,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count +=1 ; } -if (auto_demotion_disable_flags) +if (icpu->auto_demotion_disable_flags)smp_call_function (auto_demotion_disable,NULL ,1 );return 0 ;
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, intel-idle: convert to x86_cpu_id auto probing
Commit-ID: 2023bae21ec13d12cdaf877809a17ee75190649b Gitweb: http://git.kernel.org/tip/2023bae21ec13d12cdaf877809a17ee75190649b Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:29 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:38 -0800
x86, intel-idle: convert to x86_cpu_id auto probing
With this it should be automatically loaded on suitable systems by udev.
The old switch () is replaced with a table based approach, this also cleans up the code.
--- drivers/idle/intel_idle.c | 114 +++++++++++++++++++++++++------------------- 1 files changed, 65 insertions(+), 49 deletions(-)
drivers/idle/intel_idle.c +65 -49
@@ -62,6 +62,7 @@#include <linux/notifier.h> #include <linux/cpu.h> #include <linux/module.h> +#include <asm/cpu_device_id.h> #include <asm/mwait.h> #include <asm/msr.h>
@@ -81,6 +82,17 @@ static unsigned int mwait_substates;/* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 <<1 );/* Default to only C1 */ +struct idle_cpu { +struct cpuidle_state *state_table; + +/* +* Hardware C-state auto-demotion may not always be optimal. +* Indicate which enable bits to clear here. +*/ +unsigned long auto_demotion_disable_flags; +}; + +static const struct idle_cpu *icpu;static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;static int intel_idle (struct cpuidle_device *dev,struct cpuidle_driver *drv,int index);
@@ -88,12 +100,6 @@ static int intel_idle(struct cpuidle_device *dev,static struct cpuidle_state *cpuidle_state_table;/* -* Hardware C-state auto-demotion may not always be optimal. -* Indicate which enable bits to clear here. -*/ -static unsigned long long auto_demotion_disable_flags; - -/* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. * If this flag is set, SW flushes the TLB, so even if the
@@ -320,27 +326,72 @@ static void auto_demotion_disable(void *dummy)unsigned long long msr_bits;rdmsrl (MSR_NHM_SNB_PKG_CST_CFG_CTL , msr_bits); - msr_bits &= ~auto_demotion_disable_flags; + msr_bits &= ~(icpu->auto_demotion_disable_flags);wrmsrl (MSR_NHM_SNB_PKG_CST_CFG_CTL , msr_bits); } +static const struct idle_cpu idle_cpu_nehalem = { + .state_table = nehalem_cstates, +}; + +static const struct idle_cpu idle_cpu_westmere = { + .state_table = nehalem_cstates, + .auto_demotion_disable_flags =NHM_C1_AUTO_DEMOTE |NHM_C3_AUTO_DEMOTE , +}; + +static const struct idle_cpu idle_cpu_atom = { + .state_table = atom_cstates, +}; + +static const struct idle_cpu idle_cpu_lincroft = { + .state_table = atom_cstates, + .auto_demotion_disable_flags =ATM_LNC_C6_AUTO_DEMOTE , +}; + +static const struct idle_cpu idle_cpu_snb = { + .state_table = snb_cstates, +}; + +#define ICPU (model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } + +static const struct x86_cpu_id intel_idle_ids[] = { +ICPU (0x1a , idle_cpu_nehalem), +ICPU (0x1e , idle_cpu_nehalem), +ICPU (0x1f , idle_cpu_nehalem), +ICPU (0x25 , idle_cpu_westmere), +ICPU (0x2c , idle_cpu_westmere), +ICPU (0x2f , idle_cpu_westmere), +ICPU (0x1c , idle_cpu_atom), +ICPU (0x26 , idle_cpu_lincroft), +ICPU (0x2f , idle_cpu_westmere), +ICPU (0x2a , idle_cpu_snb), +ICPU (0x2d , idle_cpu_snb), + {} +}; +MODULE_DEVICE_TABLE (x86cpu, intel_idle_ids); +/* * intel_idle_probe() */ static int intel_idle_probe (void ) {unsigned int eax, ebx, ecx; +const struct x86_cpu_id *id;if (max_cstate ==0 ) {pr_debug (PREFIX "disabled\n" );return -EPERM ; } -if (boot_cpu_data.x86_vendor !=X86_VENDOR_INTEL ) -return -ENODEV ; - -if (!boot_cpu_has (X86_FEATURE_MWAIT )) + id =x86_match_cpu (intel_idle_ids); +if (!id) { +if (boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL && + boot_cpu_data.x86 ==6 ) +pr_debug (PREFIX "does not run on family %d model %d\n" , + boot_cpu_data.x86, boot_cpu_data.x86_model);return -ENODEV ; + }if (boot_cpu_data.cpuid_level <CPUID_MWAIT_LEAF )return -ENODEV ;
@@ -353,43 +404,8 @@ static int intel_idle_probe(void)pr_debug (PREFIX "MWAIT substates: 0x%x\n" , mwait_substates); - -if (boot_cpu_data.x86 !=6 )/* family 6 */ -return -ENODEV ; - -switch (boot_cpu_data.x86_model) { - -case 0x1A :/* Core i7, Xeon 5500 series */ -case 0x1E :/* Core i7 and i5 Processor - Lynnfield Jasper Forest */ -case 0x1F :/* Core i7 and i5 Processor - Nehalem */ -case 0x2E :/* Nehalem-EX Xeon */ -case 0x2F :/* Westmere-EX Xeon */ -case 0x25 :/* Westmere */ -case 0x2C :/* Westmere */ - cpuidle_state_table = nehalem_cstates; - auto_demotion_disable_flags = - (NHM_C1_AUTO_DEMOTE |NHM_C3_AUTO_DEMOTE ); -break ; - -case 0x1C :/* 28 - Atom Processor */ - cpuidle_state_table = atom_cstates; -break ; - -case 0x26 :/* 38 - Lincroft Atom Processor */ - cpuidle_state_table = atom_cstates; - auto_demotion_disable_flags =ATM_LNC_C6_AUTO_DEMOTE ; -break ; - -case 0x2A :/* SNB */ -case 0x2D :/* SNB Xeon */ - cpuidle_state_table = snb_cstates; -break ; - -default : -pr_debug (PREFIX "does not run on family %d model %d\n" , - boot_cpu_data.x86, boot_cpu_data.x86_model); -return -ENODEV ; - } + icpu = (const struct idle_cpu *)id->driver_data; + cpuidle_state_table = icpu->state_table;if (boot_cpu_has (X86_FEATURE_ARAT ))/* Always Reliable APIC Timer */ lapic_timer_reliable_states =LAPIC_TIMER_ALWAYS_RELIABLE ;
@@ -470,7 +486,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count +=1 ; } -if (auto_demotion_disable_flags) +if (icpu->auto_demotion_disable_flags)smp_call_function (auto_demotion_disable,NULL ,1 );return 0 ;
PATCH 4/8 ACPI: Load acpi-cpufreq from processor driver automatically
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
The only left over hole in automatic cpufreq driver loading was the loading of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC method and the CPU vendor wants to use acpi cpufreq.
Simply add a request module call to the acpi processor core driver when this is true. This seems like the simplest solution for this.
--- drivers/acpi/processor_driver.c | 1 + drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++ include/acpi/processor.h | 1 + 3 files changed, 24 insertions(+), 0 deletions(-)
drivers/acpi/processor_driver.c +1 -0
@@ -499,6 +499,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)#ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed (pr,0 ); +acpi_processor_load_module (pr);#endif acpi_processor_get_throttling_info (pr);acpi_processor_get_limit_info (pr);
drivers/acpi/processor_perflib.c +22 -0
@@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void) acpi_processor_ppc_status &= ~PPC_REGISTERED ; } +/* +* Do a quick check if the systems looks like it should use ACPI +* cpufreq. We look at a _PCT method being available, but don't +* do a whole lot of sanity checks. +*/ +void acpi_processor_load_module (struct acpi_processor *pr) +{ +static int requested; +acpi_status status =0 ; +struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; + +if (!arch_has_acpi_pdc () || requested) +return ; + status =acpi_evaluate_object (pr->handle,"_PCT" ,NULL , &buffer); +if (!ACPI_FAILURE (status)) { + printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); +request_module_nowait ("acpi_cpufreq" ); + requested =1 ; + } +kfree (buffer.pointer); +} +static int acpi_processor_get_performance_control (struct acpi_processor *pr) {int result =0 ;
include/acpi/processor.h +1 -0
@@ -224,6 +224,7 @@ struct acpi_processor_errata { } piix4; }; +extern void acpi_processor_load_module (struct acpi_processor *pr);extern int acpi_processor_preregister_performance (struct acpi_processor_performance __percpu *performance);
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, acpi: Load acpi-cpufreq from processor driver automatically
Commit-ID: 848fd8ee1881650226f11113e17b0118a792e12f Gitweb: http://git.kernel.org/tip/848fd8ee1881650226f11113e17b0118a792e12f Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:30 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:43 -0800
x86, acpi: Load acpi-cpufreq from processor driver automatically
The only left over hole in automatic cpufreq driver loading was the loading of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC method and the CPU vendor wants to use acpi cpufreq.
Simply add a request module call to the acpi processor core driver when this is true. This seems like the simplest solution for this.
--- drivers/acpi/processor_driver.c | 1 + drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++ include/acpi/processor.h | 1 + 3 files changed, 24 insertions(+), 0 deletions(-)
drivers/acpi/processor_driver.c +1 -0
@@ -499,6 +499,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)#ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed (pr,0 ); +acpi_processor_load_module (pr);#endif acpi_processor_get_throttling_info (pr);acpi_processor_get_limit_info (pr);
drivers/acpi/processor_perflib.c +22 -0
@@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void) acpi_processor_ppc_status &= ~PPC_REGISTERED ; } +/* +* Do a quick check if the systems looks like it should use ACPI +* cpufreq. We look at a _PCT method being available, but don't +* do a whole lot of sanity checks. +*/ +void acpi_processor_load_module (struct acpi_processor *pr) +{ +static int requested; +acpi_status status =0 ; +struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; + +if (!arch_has_acpi_pdc () || requested) +return ; + status =acpi_evaluate_object (pr->handle,"_PCT" ,NULL , &buffer); +if (!ACPI_FAILURE (status)) { + printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); +request_module_nowait ("acpi_cpufreq" ); + requested =1 ; + } +kfree (buffer.pointer); +} +static int acpi_processor_get_performance_control (struct acpi_processor *pr) {int result =0 ;
include/acpi/processor.h +1 -0
@@ -224,6 +224,7 @@ struct acpi_processor_errata { } piix4; }; +extern void acpi_processor_load_module (struct acpi_processor *pr);extern int acpi_processor_preregister_performance (struct acpi_processor_performance __percpu *performance);
PATCH 5/8 HWMON: Convert via-cputemp to x86 cpuid autoprobing
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Use the new x86 cpuid autoprobe interface.
--- drivers/hwmon/via-cputemp.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-)
drivers/hwmon/via-cputemp.c +11 -5
@@ -37,6 +37,7 @@#include <linux/cpu.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "via_cputemp"
@@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; +static const struct x86_cpu_id cputemp_ids[] = { + {X86_VENDOR_CENTAUR ,6 ,0xa , },/* C7 A */ + {X86_VENDOR_CENTAUR ,6 ,0xd , },/* C7 D */ + {X86_VENDOR_CENTAUR ,6 ,0xf , },/* Nano */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, cputemp_ids); +static int __init via_cputemp_init (void ) {int i, err; -if (cpu_data (0 ).x86_vendor !=X86_VENDOR_CENTAUR ) { - printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); - err = -ENODEV ; - goto exit; - } +if (!x86_match_cpu (cputemp_ids)) +return -ENODEV ; err =platform_driver_register (&via_cputemp_driver);if (err)
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, hwmon: Convert via-cputemp to x86 cpuid autoprobing
Commit-ID: 12ea04ef68d6d4c6f843e4041008bb3ba29846b9 Gitweb: http://git.kernel.org/tip/12ea04ef68d6d4c6f843e4041008bb3ba29846b9 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:31 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:50 -0800
x86, hwmon: Convert via-cputemp to x86 cpuid autoprobing
Use the new x86 cpuid autoprobe interface.
--- drivers/hwmon/via-cputemp.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-)
drivers/hwmon/via-cputemp.c +11 -5
@@ -37,6 +37,7 @@#include <linux/cpu.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "via_cputemp"
@@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; +static const struct x86_cpu_id cputemp_ids[] = { + {X86_VENDOR_CENTAUR ,6 ,0xa , },/* C7 A */ + {X86_VENDOR_CENTAUR ,6 ,0xd , },/* C7 D */ + {X86_VENDOR_CENTAUR ,6 ,0xf , },/* Nano */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, cputemp_ids); +static int __init via_cputemp_init (void ) {int i, err; -if (cpu_data (0 ).x86_vendor !=X86_VENDOR_CENTAUR ) { - printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); - err = -ENODEV ; - goto exit; - } +if (!x86_match_cpu (cputemp_ids)) +return -ENODEV ; err =platform_driver_register (&via_cputemp_driver);if (err)
PATCH 6/8 HWMON: Convert coretemp to x86 cpuid autoprobing
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Use the new x86 cpuid autoprobe interface for the Intel coretemp driver.
--- drivers/hwmon/coretemp.c | 17 ++++++++++++++--- 1 files changed, 14 insertions(+), 3 deletions(-)
drivers/hwmon/coretemp.c +14 -3
@@ -39,6 +39,7 @@#include <linux/moduleparam.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "coretemp"
@@ -756,13 +757,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; +static const struct x86_cpu_id coretemp_ids[] = { + {X86_VENDOR_INTEL ,X86_FAMILY_ANY ,X86_MODEL_ANY ,X86_FEATURE_DTS }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, coretemp_ids); +static int __init coretemp_init (void ) {int i, err = -ENODEV ; -/* quick check if we run Intel */ -if (cpu_data (0 ).x86_vendor !=X86_VENDOR_INTEL ) - goto exit; +/* +* CPUID.06H.EAX[0] indicates whether the CPU has thermal +* sensors. We check this bit only, all the early CPUs +* without thermal sensors will be filtered out. +*/ +if (!x86_match_cpu (coretemp_ids)) +return -ENODEV ; err =platform_driver_register (&coretemp_driver);if (err)
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, hwmon: Convert coretemp to x86 cpuid autoprobing
Commit-ID: 10b85d6c159658e912730efa9cd787a607f1ad6c Gitweb: http://git.kernel.org/tip/10b85d6c159658e912730efa9cd787a607f1ad6c Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:32 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:49:55 -0800
x86, hwmon: Convert coretemp to x86 cpuid autoprobing
Use the new x86 cpuid autoprobe interface for the Intel coretemp driver.
--- drivers/hwmon/coretemp.c | 17 ++++++++++++++--- 1 files changed, 14 insertions(+), 3 deletions(-)
drivers/hwmon/coretemp.c +14 -3
@@ -39,6 +39,7 @@#include <linux/moduleparam.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "coretemp"
@@ -756,13 +757,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; +static const struct x86_cpu_id coretemp_ids[] = { + {X86_VENDOR_INTEL ,X86_FAMILY_ANY ,X86_MODEL_ANY ,X86_FEATURE_DTS }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, coretemp_ids); +static int __init coretemp_init (void ) {int i, err = -ENODEV ; -/* quick check if we run Intel */ -if (cpu_data (0 ).x86_vendor !=X86_VENDOR_INTEL ) - goto exit; +/* +* CPUID.06H.EAX[0] indicates whether the CPU has thermal +* sensors. We check this bit only, all the early CPUs +* without thermal sensors will be filtered out. +*/ +if (!x86_match_cpu (coretemp_ids)) +return -ENODEV ; err =platform_driver_register (&coretemp_driver);if (err)
PATCH 7/8 cpufreq: Add support for x86 cpuinfo auto loading v3
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
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)
--- drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++ drivers/cpufreq/e_powersaver.c | 20 +++++++++++--------- drivers/cpufreq/elanfreq.c | 14 +++++++------- drivers/cpufreq/gx-suspmod.c | 9 ++------- drivers/cpufreq/longhaul.c | 8 +++++++- drivers/cpufreq/longrun.c | 13 ++++++++----- drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------ drivers/cpufreq/powernow-k6.c | 12 ++++++++---- drivers/cpufreq/powernow-k7.c | 14 ++++++++------ drivers/cpufreq/powernow-k8.c | 22 ++++++++++++++++------ drivers/cpufreq/sc520_freq.c | 14 ++++++++------ drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++---- drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++ drivers/cpufreq/speedstep-lib.c | 1 + drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++ 15 files changed, 145 insertions(+), 61 deletions(-)
drivers/cpufreq/cpufreq-nforce2.c +8 -0
@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = { .owner = THIS_MODULE, }; +#ifdef MODULE +static struct pci_device_id nforce2_ids[] = { + {PCI_VENDOR_ID_NVIDIA ,PCI_DEVICE_ID_NVIDIA_NFORCE2 }, + {} +}; +MODULE_DEVICE_TABLE (pci, nforce2_ids); +#endif +/** * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic *
drivers/cpufreq/e_powersaver.c +11 -9
@@ -16,6 +16,7 @@#include <linux/io.h> #include <linux/delay.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #include <asm/tsc.h>
@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = { .attr = eps_attr, }; + +/* This driver will work only on Centaur C7 processors with +* Enhanced SpeedStep/PowerSaver registers */ +static const struct x86_cpu_id eps_cpu_id[] = { + {X86_VENDOR_CENTAUR ,6 ,X86_MODEL_ANY ,X86_FEATURE_EST }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, eps_cpu_id); +static int __init eps_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -/* This driver will work only on Centaur C7 processors with -* Enhanced SpeedStep/PowerSaver registers */ -if (c->x86_vendor !=X86_VENDOR_CENTAUR - || c->x86 !=6 || c->x86_model <10 ) -return -ENODEV ; -if (!cpu_has (c,X86_FEATURE_EST )) +if (!x86_match_cpu (eps_cpu_id) || boot_cpu_data.x86_model <10 )return -ENODEV ; -if (cpufreq_register_driver (&eps_driver))return -EINVAL ;return 0 ;
drivers/cpufreq/elanfreq.c +7 -7
@@ -23,6 +23,7 @@#include <linux/delay.h> #include <linux/cpufreq.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #include <linux/timex.h> #include <linux/io.h>
@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = { .attr = elanfreq_attr, }; +static const struct x86_cpu_id elan_id[] = { + {X86_VENDOR_AMD ,4 ,10 , }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, elan_id);static int __init elanfreq_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -/* Test if we have the right hardware */ -if ((c->x86_vendor !=X86_VENDOR_AMD ) || - (c->x86 !=4 ) || (c->x86_model !=10 )) { -printk (KERN_INFO "elanfreq: error: no Elan processor found!\n" ); +if (!x86_match_cpu (elan_id))return -ENODEV ; - }return cpufreq_register_driver (&elanfreq_driver); }
drivers/cpufreq/gx-suspmod.c +2 -7
@@ -82,6 +82,7 @@#include <linux/errno.h> #include <linux/slab.h> +#include <asm/cpu_device_id.h> #include <asm/processor-cyrix.h> /* PCI config registers, all at F0 */
@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; +MODULE_DEVICE_TABLE (gx_chipset_tbl);static void gx_write_byte (int reg,int value) {
@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void) {struct pci_dev *gx_pci =NULL ; -/* check if CPU is a MediaGX or a Geode. */ -if ((boot_cpu_data.x86_vendor !=X86_VENDOR_NSC ) && - (boot_cpu_data.x86_vendor !=X86_VENDOR_CYRIX )) { -pr_debug ("error: no MediaGX/Geode processor found!\n" ); -return NULL ; - } -/* detect which companion chip is used */ for_each_pci_dev (gx_pci) {if ((pci_match_id (gx_chipset_tbl, gx_pci)) !=NULL )
drivers/cpufreq/longhaul.c +7 -1
@@ -35,6 +35,7 @@#include <linux/acpi.h> #include <asm/msr.h> +#include <asm/cpu_device_id.h> #include <acpi/processor.h> #include "longhaul.h"
@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = { .attr = longhaul_attr, }; +static const struct x86_cpu_id longhaul_id[] = { + {X86_VENDOR_CENTAUR ,6 }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, longhaul_id);static int __init longhaul_init (void ) {struct cpuinfo_x86 *c = &cpu_data (0 ); -if (c->x86_vendor !=X86_VENDOR_CENTAUR || c->x86 !=6 ) +if (!x86_match_cpu (longhaul_id))return -ENODEV ;#ifdef CONFIG_SMP
drivers/cpufreq/longrun.c +8 -5
@@ -14,6 +14,7 @@#include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> static struct cpufreq_driver longrun_driver;
@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = { .owner = THIS_MODULE, }; +static const struct x86_cpu_id longrun_ids[] = { + {X86_VENDOR_TRANSMETA ,X86_FAMILY_ANY ,X86_MODEL_ANY , +X86_FEATURE_LONGRUN }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, longrun_ids);/** * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {*/ static int __init longrun_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -if (c->x86_vendor !=X86_VENDOR_TRANSMETA || - !cpu_has (c,X86_FEATURE_LONGRUN )) +if (!x86_match_cpu (longrun_ids))return -ENODEV ; -return cpufreq_register_driver (&longrun_driver); }
drivers/cpufreq/p4-clockmod.c +11 -6
@@ -31,6 +31,7 @@#include <asm/processor.h> #include <asm/msr.h> #include <asm/timer.h> +#include <asm/cpu_device_id.h> #include "speedstep-lib.h"
@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = { .attr = p4clockmod_attr, }; +static const struct x86_cpu_id cpufreq_p4_id[] = { + {X86_VENDOR_INTEL ,X86_FAMILY_ANY ,X86_MODEL_ANY ,X86_FEATURE_ACC }, + {} +}; + +/* +* Intentionally no MODULE_DEVICE_TABLE here: this driver should not +* be auto loaded. Please don't add one. +*/ static int __init cpufreq_p4_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 );int ret;/* * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ -if (c->x86_vendor !=X86_VENDOR_INTEL ) -return -ENODEV ; - -if (!test_cpu_cap (c,X86_FEATURE_ACPI ) || - !test_cpu_cap (c,X86_FEATURE_ACC )) +if (!x86_match_cpu (cpufreq_p4_id) || !boot_cpu_has (X86_FEATURE_ACPI ))return -ENODEV ; ret =cpufreq_register_driver (&p4clockmod_driver);
drivers/cpufreq/powernow-k6.c +8 -4
@@ -16,6 +16,7 @@#include <linux/timex.h> #include <linux/io.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #define POWERNOW_IOPORT 0xfff0/* it doesn't matter where, as long
@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = { .attr = powernow_k6_attr, }; +static const struct x86_cpu_id powernow_k6_ids[] = { + {X86_VENDOR_AMD ,5 ,12 }, + {X86_VENDOR_AMD ,5 ,13 }, + {} +}; +/** * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {*/ static int __init powernow_k6_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -if ((c->x86_vendor !=X86_VENDOR_AMD ) || (c->x86 !=5 ) || - ((c->x86_model !=12 ) && (c->x86_model !=13 ))) +if (!x86_match_cpu (powernow_k6_ids))return -ENODEV ;if (!request_region (POWERNOW_IOPORT ,16 ,"PowerNow!" )) {
drivers/cpufreq/powernow-k7.c +8 -6
@@ -28,6 +28,7 @@#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */ #include <asm/msr.h> #include <asm/system.h> +#include <asm/cpu_device_id.h> #ifdef CONFIG_X86_POWERNOW_K7_ACPI #include <linux/acpi.h>
@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)return delta <5 ; } +static const struct x86_cpu_id powernow_k7_cpuids[] = { + {X86_VENDOR_AMD ,7 , }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, powernow_k7_cpuids); +static int check_powernow (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );unsigned int maxei, eax, ebx, ecx, edx; -if ((c->x86_vendor !=X86_VENDOR_AMD ) || (c->x86 !=6 )) { -#ifdef MODULE - printk(KERN_INFO PFX "This module only works with " - "AMD K7 CPUs\n"); -#endif +if (!x86_match_cpu (powernow_k7_cpuids))return 0 ; - }/* Get maximum capabilities */ maxei =cpuid_eax (0x80000000 );
drivers/cpufreq/powernow-k8.c +16 -6
@@ -37,6 +37,7 @@#include <linux/delay.h> #include <asm/msr.h> +#include <asm/cpu_device_id.h> #include <linux/acpi.h> #include <linux/mutex.h>
@@ -514,6 +515,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,return 0 ; } +static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , }, +/* Add more here? */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, powernow_k8_ids); +static void check_supported_cpu (void *_rc) {u32 eax, ebx, ecx, edx;
@@ -521,13 +534,7 @@ static void check_supported_cpu(void *_rc) *rc = -ENODEV ; -if (__this_cpu_read (cpu_info.x86_vendor) !=X86_VENDOR_AMD ) -return ; - eax =cpuid_eax (CPUID_PROCESSOR_SIGNATURE ); -if (((eax &CPUID_XFAM ) !=CPUID_XFAM_K8 ) && - ((eax &CPUID_XFAM ) <CPUID_XFAM_10H )) -return ;if ((eax &CPUID_XFAM ) ==CPUID_XFAM_K8 ) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
@@ -1542,6 +1549,9 @@ static int __cpuinit powernowk8_init(void)unsigned int i, supported_cpus =0 , cpu;int rv; +if (!x86_match_cpu (powernow_k8_ids)) +return -ENODEV ; +for_each_online_cpu (i) {int rc;smp_call_function_single (i, check_supported_cpu, &rc,1 );
drivers/cpufreq/sc520_freq.c +8 -6
@@ -22,6 +22,7 @@#include <linux/timex.h> #include <linux/io.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #define MMCR_BASE 0xfffef000/* The default base address */
@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = { .attr = sc520_freq_attr, }; +static const struct x86_cpu_id sc520_ids[] = { + {X86_VENDOR_AMD ,4 ,9 }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, sc520_ids);static int __init sc520_freq_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 );int err; -/* Test if we have the right hardware */ -if (c->x86_vendor !=X86_VENDOR_AMD || - c->x86 !=4 || c->x86_model !=9 ) { -pr_debug ("no Elan SC520 processor found!\n" ); +if (!x86_match_cpu (sc520_ids))return -ENODEV ; - } + cpuctl =ioremap ((unsigned long )(MMCR_BASE +OFFS_CPUCTL ),1 );if (!cpuctl) {printk (KERN_ERR "sc520_freq: error: failed to remap memory\n" );
drivers/cpufreq/speedstep-centrino.c +20 -4
@@ -25,6 +25,7 @@#include <asm/msr.h> #include <asm/processor.h> #include <asm/cpufeature.h> +#include <asm/cpu_device_id.h> #define PFX "speedstep-centrino: "#define MAINTAINER "[email protected]"
@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = { .owner = THIS_MODULE, }; +/* +* This doesn't replace the detailed checks above because +* the generic CPU IDs don't have a way to match for steppings +* or ASCII model IDs. +*/ +static const struct x86_cpu_id centrino_ids[] = { + {X86_VENDOR_INTEL ,6 ,9 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,15 ,3 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,15 ,4 ,X86_FEATURE_EST }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE (x86cpu, centrino_ids); +#endif /** * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {*/ static int __init centrino_init (void ) { -struct cpuinfo_x86 *cpu = &cpu_data (0 ); - -if (!cpu_has (cpu,X86_FEATURE_EST )) +if (!x86_match_cpu (centrino_ids))return -ENODEV ; -return cpufreq_register_driver (¢rino_driver); }
drivers/cpufreq/speedstep-ich.c +15 -0
@@ -25,6 +25,8 @@#include <linux/pci.h> #include <linux/sched.h> +#include <asm/cpu_device_id.h> +#include "speedstep-lib.h"
@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + {X86_VENDOR_INTEL ,6 ,0xb , }, + {X86_VENDOR_INTEL ,6 ,0x8 , }, + {X86_VENDOR_INTEL ,15 ,2 }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE (x86cpu, ss_smi_ids); +#endif /** * speedstep_init - initializes the SpeedStep CPUFreq driver
@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {*/ static int __init speedstep_init (void ) { +if (!x86_match_cpu (ss_smi_ids)) +return -ENODEV ; +/* detect processor */ speedstep_processor =speedstep_detect_processor ();if (!speedstep_processor) {
drivers/cpufreq/speedstep-lib.c +1 -0
@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);* DETECT SPEEDSTEP-CAPABLE PROCESSOR * *********************************************************************/ +/* Keep in sync with the x86_cpu_id tables in the different modules */ unsigned int speedstep_detect_processor (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );
drivers/cpufreq/speedstep-smi.c +15 -0
@@ -20,6 +20,7 @@#include <linux/delay.h> #include <linux/io.h> #include <asm/ist.h> +#include <asm/cpu_device_id.h> #include "speedstep-lib.h"
@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + {X86_VENDOR_INTEL ,6 ,0xb , }, + {X86_VENDOR_INTEL ,6 ,0x8 , }, + {X86_VENDOR_INTEL ,15 ,2 }, + {} +}; +#if 0 +/* Not auto loaded currently */ +MODULE_DEVICE_TABLE (x86cpu, ss_smi_ids); +#endif +/** * speedstep_init - initializes the SpeedStep CPUFreq driver *
@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {*/ static int __init speedstep_init (void ) { +if (!x86_match_cpu (ss_smi_ids)) +return -ENODEV ; + speedstep_processor =speedstep_detect_processor ();switch (speedstep_processor) {
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86, cpufreq: Add support for x86 cpuinfo auto loading
Commit-ID: c347c2092efcd7d4fc1575057db7a42c1fc15ec5 Gitweb: http://git.kernel.org/tip/c347c2092efcd7d4fc1575057db7a42c1fc15ec5 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:33 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:50:01 -0800
x86, cpufreq: Add support for x86 cpuinfo auto loading
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)
--- drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++ drivers/cpufreq/e_powersaver.c | 20 +++++++++++--------- drivers/cpufreq/elanfreq.c | 14 +++++++------- drivers/cpufreq/gx-suspmod.c | 9 ++------- drivers/cpufreq/longhaul.c | 8 +++++++- drivers/cpufreq/longrun.c | 13 ++++++++----- drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------ drivers/cpufreq/powernow-k6.c | 12 ++++++++---- drivers/cpufreq/powernow-k7.c | 14 ++++++++------ drivers/cpufreq/powernow-k8.c | 22 ++++++++++++++++------ drivers/cpufreq/sc520_freq.c | 14 ++++++++------ drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++---- drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++ drivers/cpufreq/speedstep-lib.c | 1 + drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++ 15 files changed, 145 insertions(+), 61 deletions(-)
drivers/cpufreq/cpufreq-nforce2.c +8 -0
@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = { .owner = THIS_MODULE, }; +#ifdef MODULE +static struct pci_device_id nforce2_ids[] = { + {PCI_VENDOR_ID_NVIDIA ,PCI_DEVICE_ID_NVIDIA_NFORCE2 }, + {} +}; +MODULE_DEVICE_TABLE (pci, nforce2_ids); +#endif +/** * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic *
drivers/cpufreq/e_powersaver.c +11 -9
@@ -16,6 +16,7 @@#include <linux/io.h> #include <linux/delay.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #include <asm/tsc.h>
@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = { .attr = eps_attr, }; + +/* This driver will work only on Centaur C7 processors with +* Enhanced SpeedStep/PowerSaver registers */ +static const struct x86_cpu_id eps_cpu_id[] = { + {X86_VENDOR_CENTAUR ,6 ,X86_MODEL_ANY ,X86_FEATURE_EST }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, eps_cpu_id); +static int __init eps_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -/* This driver will work only on Centaur C7 processors with -* Enhanced SpeedStep/PowerSaver registers */ -if (c->x86_vendor !=X86_VENDOR_CENTAUR - || c->x86 !=6 || c->x86_model <10 ) -return -ENODEV ; -if (!cpu_has (c,X86_FEATURE_EST )) +if (!x86_match_cpu (eps_cpu_id) || boot_cpu_data.x86_model <10 )return -ENODEV ; -if (cpufreq_register_driver (&eps_driver))return -EINVAL ;return 0 ;
drivers/cpufreq/elanfreq.c +7 -7
@@ -23,6 +23,7 @@#include <linux/delay.h> #include <linux/cpufreq.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #include <linux/timex.h> #include <linux/io.h>
@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = { .attr = elanfreq_attr, }; +static const struct x86_cpu_id elan_id[] = { + {X86_VENDOR_AMD ,4 ,10 , }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, elan_id);static int __init elanfreq_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -/* Test if we have the right hardware */ -if ((c->x86_vendor !=X86_VENDOR_AMD ) || - (c->x86 !=4 ) || (c->x86_model !=10 )) { -printk (KERN_INFO "elanfreq: error: no Elan processor found!\n" ); +if (!x86_match_cpu (elan_id))return -ENODEV ; - }return cpufreq_register_driver (&elanfreq_driver); }
drivers/cpufreq/gx-suspmod.c +2 -7
@@ -82,6 +82,7 @@#include <linux/errno.h> #include <linux/slab.h> +#include <asm/cpu_device_id.h> #include <asm/processor-cyrix.h> /* PCI config registers, all at F0 */
@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; +MODULE_DEVICE_TABLE (gx_chipset_tbl);static void gx_write_byte (int reg,int value) {
@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void) {struct pci_dev *gx_pci =NULL ; -/* check if CPU is a MediaGX or a Geode. */ -if ((boot_cpu_data.x86_vendor !=X86_VENDOR_NSC ) && - (boot_cpu_data.x86_vendor !=X86_VENDOR_CYRIX )) { -pr_debug ("error: no MediaGX/Geode processor found!\n" ); -return NULL ; - } -/* detect which companion chip is used */ for_each_pci_dev (gx_pci) {if ((pci_match_id (gx_chipset_tbl, gx_pci)) !=NULL )
drivers/cpufreq/longhaul.c +7 -1
@@ -35,6 +35,7 @@#include <linux/acpi.h> #include <asm/msr.h> +#include <asm/cpu_device_id.h> #include <acpi/processor.h> #include "longhaul.h"
@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = { .attr = longhaul_attr, }; +static const struct x86_cpu_id longhaul_id[] = { + {X86_VENDOR_CENTAUR ,6 }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, longhaul_id);static int __init longhaul_init (void ) {struct cpuinfo_x86 *c = &cpu_data (0 ); -if (c->x86_vendor !=X86_VENDOR_CENTAUR || c->x86 !=6 ) +if (!x86_match_cpu (longhaul_id))return -ENODEV ;#ifdef CONFIG_SMP
drivers/cpufreq/longrun.c +8 -5
@@ -14,6 +14,7 @@#include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> static struct cpufreq_driver longrun_driver;
@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = { .owner = THIS_MODULE, }; +static const struct x86_cpu_id longrun_ids[] = { + {X86_VENDOR_TRANSMETA ,X86_FAMILY_ANY ,X86_MODEL_ANY , +X86_FEATURE_LONGRUN }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, longrun_ids);/** * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {*/ static int __init longrun_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -if (c->x86_vendor !=X86_VENDOR_TRANSMETA || - !cpu_has (c,X86_FEATURE_LONGRUN )) +if (!x86_match_cpu (longrun_ids))return -ENODEV ; -return cpufreq_register_driver (&longrun_driver); }
drivers/cpufreq/p4-clockmod.c +11 -6
@@ -31,6 +31,7 @@#include <asm/processor.h> #include <asm/msr.h> #include <asm/timer.h> +#include <asm/cpu_device_id.h> #include "speedstep-lib.h"
@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = { .attr = p4clockmod_attr, }; +static const struct x86_cpu_id cpufreq_p4_id[] = { + {X86_VENDOR_INTEL ,X86_FAMILY_ANY ,X86_MODEL_ANY ,X86_FEATURE_ACC }, + {} +}; + +/* +* Intentionally no MODULE_DEVICE_TABLE here: this driver should not +* be auto loaded. Please don't add one. +*/ static int __init cpufreq_p4_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 );int ret;/* * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ -if (c->x86_vendor !=X86_VENDOR_INTEL ) -return -ENODEV ; - -if (!test_cpu_cap (c,X86_FEATURE_ACPI ) || - !test_cpu_cap (c,X86_FEATURE_ACC )) +if (!x86_match_cpu (cpufreq_p4_id) || !boot_cpu_has (X86_FEATURE_ACPI ))return -ENODEV ; ret =cpufreq_register_driver (&p4clockmod_driver);
drivers/cpufreq/powernow-k6.c +8 -4
@@ -16,6 +16,7 @@#include <linux/timex.h> #include <linux/io.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #define POWERNOW_IOPORT 0xfff0/* it doesn't matter where, as long
@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = { .attr = powernow_k6_attr, }; +static const struct x86_cpu_id powernow_k6_ids[] = { + {X86_VENDOR_AMD ,5 ,12 }, + {X86_VENDOR_AMD ,5 ,13 }, + {} +}; +/** * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {*/ static int __init powernow_k6_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 ); - -if ((c->x86_vendor !=X86_VENDOR_AMD ) || (c->x86 !=5 ) || - ((c->x86_model !=12 ) && (c->x86_model !=13 ))) +if (!x86_match_cpu (powernow_k6_ids))return -ENODEV ;if (!request_region (POWERNOW_IOPORT ,16 ,"PowerNow!" )) {
drivers/cpufreq/powernow-k7.c +8 -6
@@ -28,6 +28,7 @@#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */ #include <asm/msr.h> #include <asm/system.h> +#include <asm/cpu_device_id.h> #ifdef CONFIG_X86_POWERNOW_K7_ACPI #include <linux/acpi.h>
@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)return delta <5 ; } +static const struct x86_cpu_id powernow_k7_cpuids[] = { + {X86_VENDOR_AMD ,7 , }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, powernow_k7_cpuids); +static int check_powernow (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );unsigned int maxei, eax, ebx, ecx, edx; -if ((c->x86_vendor !=X86_VENDOR_AMD ) || (c->x86 !=6 )) { -#ifdef MODULE - printk(KERN_INFO PFX "This module only works with " - "AMD K7 CPUs\n"); -#endif +if (!x86_match_cpu (powernow_k7_cpuids))return 0 ; - }/* Get maximum capabilities */ maxei =cpuid_eax (0x80000000 );
drivers/cpufreq/powernow-k8.c +16 -6
@@ -37,6 +37,7 @@#include <linux/delay.h> #include <asm/msr.h> +#include <asm/cpu_device_id.h> #include <linux/acpi.h> #include <linux/mutex.h>
@@ -514,6 +515,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,return 0 ; } +static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , }, +/* Add more here? */ + {} +}; +MODULE_DEVICE_TABLE (x86cpu, powernow_k8_ids); +static void check_supported_cpu (void *_rc) {u32 eax, ebx, ecx, edx;
@@ -521,13 +534,7 @@ static void check_supported_cpu(void *_rc) *rc = -ENODEV ; -if (__this_cpu_read (cpu_info.x86_vendor) !=X86_VENDOR_AMD ) -return ; - eax =cpuid_eax (CPUID_PROCESSOR_SIGNATURE ); -if (((eax &CPUID_XFAM ) !=CPUID_XFAM_K8 ) && - ((eax &CPUID_XFAM ) <CPUID_XFAM_10H )) -return ;if ((eax &CPUID_XFAM ) ==CPUID_XFAM_K8 ) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
@@ -1542,6 +1549,9 @@ static int __cpuinit powernowk8_init(void)unsigned int i, supported_cpus =0 , cpu;int rv; +if (!x86_match_cpu (powernow_k8_ids)) +return -ENODEV ; +for_each_online_cpu (i) {int rc;smp_call_function_single (i, check_supported_cpu, &rc,1 );
drivers/cpufreq/sc520_freq.c +8 -6
@@ -22,6 +22,7 @@#include <linux/timex.h> #include <linux/io.h> +#include <asm/cpu_device_id.h> #include <asm/msr.h> #define MMCR_BASE 0xfffef000/* The default base address */
@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = { .attr = sc520_freq_attr, }; +static const struct x86_cpu_id sc520_ids[] = { + {X86_VENDOR_AMD ,4 ,9 }, + {} +}; +MODULE_DEVICE_TABLE (x86cpu, sc520_ids);static int __init sc520_freq_init (void ) { -struct cpuinfo_x86 *c = &cpu_data (0 );int err; -/* Test if we have the right hardware */ -if (c->x86_vendor !=X86_VENDOR_AMD || - c->x86 !=4 || c->x86_model !=9 ) { -pr_debug ("no Elan SC520 processor found!\n" ); +if (!x86_match_cpu (sc520_ids))return -ENODEV ; - } + cpuctl =ioremap ((unsigned long )(MMCR_BASE +OFFS_CPUCTL ),1 );if (!cpuctl) {printk (KERN_ERR "sc520_freq: error: failed to remap memory\n" );
drivers/cpufreq/speedstep-centrino.c +20 -4
@@ -25,6 +25,7 @@#include <asm/msr.h> #include <asm/processor.h> #include <asm/cpufeature.h> +#include <asm/cpu_device_id.h> #define PFX "speedstep-centrino: "#define MAINTAINER "[email protected]"
@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = { .owner = THIS_MODULE, }; +/* +* This doesn't replace the detailed checks above because +* the generic CPU IDs don't have a way to match for steppings +* or ASCII model IDs. +*/ +static const struct x86_cpu_id centrino_ids[] = { + {X86_VENDOR_INTEL ,6 ,9 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,6 ,13 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,15 ,3 ,X86_FEATURE_EST }, + {X86_VENDOR_INTEL ,15 ,4 ,X86_FEATURE_EST }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE (x86cpu, centrino_ids); +#endif /** * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {*/ static int __init centrino_init (void ) { -struct cpuinfo_x86 *cpu = &cpu_data (0 ); - -if (!cpu_has (cpu,X86_FEATURE_EST )) +if (!x86_match_cpu (centrino_ids))return -ENODEV ; -return cpufreq_register_driver (¢rino_driver); }
drivers/cpufreq/speedstep-ich.c +15 -0
@@ -25,6 +25,8 @@#include <linux/pci.h> #include <linux/sched.h> +#include <asm/cpu_device_id.h> +#include "speedstep-lib.h"
@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + {X86_VENDOR_INTEL ,6 ,0xb , }, + {X86_VENDOR_INTEL ,6 ,0x8 , }, + {X86_VENDOR_INTEL ,15 ,2 }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE (x86cpu, ss_smi_ids); +#endif /** * speedstep_init - initializes the SpeedStep CPUFreq driver
@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {*/ static int __init speedstep_init (void ) { +if (!x86_match_cpu (ss_smi_ids)) +return -ENODEV ; +/* detect processor */ speedstep_processor =speedstep_detect_processor ();if (!speedstep_processor) {
drivers/cpufreq/speedstep-lib.c +1 -0
@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);* DETECT SPEEDSTEP-CAPABLE PROCESSOR * *********************************************************************/ +/* Keep in sync with the x86_cpu_id tables in the different modules */ unsigned int speedstep_detect_processor (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );
drivers/cpufreq/speedstep-smi.c +15 -0
@@ -20,6 +20,7 @@#include <linux/delay.h> #include <linux/io.h> #include <asm/ist.h> +#include <asm/cpu_device_id.h> #include "speedstep-lib.h"
@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + {X86_VENDOR_INTEL ,6 ,0xb , }, + {X86_VENDOR_INTEL ,6 ,0x8 , }, + {X86_VENDOR_INTEL ,15 ,2 }, + {} +}; +#if 0 +/* Not auto loaded currently */ +MODULE_DEVICE_TABLE (x86cpu, ss_smi_ids); +#endif +/** * speedstep_init - initializes the SpeedStep CPUFreq driver *
@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {*/ static int __init speedstep_init (void ) { +if (!x86_match_cpu (ss_smi_ids)) +return -ENODEV ; + speedstep_processor =speedstep_detect_processor ();switch (speedstep_processor) {
Re: [tip:x86/autoprobe] x86, cpufreq: Add support for x86 cpuinfo auto loading
Quoted 22 lines · tip-bot for Andi Kleen
Commit-ID: c347c2092efcd7d4fc1575057db7a42c1fc15ec5 Gitweb: http://git.kernel.org/tip/c347c2092efcd7d4fc1575057db7a42c1fc15ec5 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:33 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:50:01 -0800x86, cpufreq: Add support for x86 cpuinfo auto loading
drivers/cpufreq/gx-suspmod.c +1
-0@@ -82,6 +82,7 @@#include <linux/errno.h> #include <linux/slab.h> +#include <asm/cpu_device_id.h> #include <asm/processor-cyrix.h> /* PCI config registers, all at F0 */
drivers/cpufreq/gx-suspmod.c static struct pci_device_id gx_chipset_tbl[] __initdata = { · line 175
Quoted 4 lines
drivers/cpufreq/gx-suspmod.c +1
-0@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; +MODULE_DEVICE_TABLE (gx_chipset_tbl);
Andi, you are sloppy as usual:
drivers/cpufreq/gx-suspmod.c:175:35: error: macro "MODULE_DEVICE_TABLE" requires 2 arguments, but only 1 given
You have not even build tested this change?
Thanks,
Ingo
Re: [tip:x86/autoprobe] x86, cpufreq: Add support for x86 cpuinfo auto loading
Quoted 3 lines
drivers/cpufreq/gx-suspmod.c:175:35: error: macro "MODULE_DEVICE_TABLE" requires 2 arguments, but only 1 givenYou have not even build tested this change?
I did an allyes build, but only on 64bit. Forgot it's a 32bit only driver. Sorry. Here's an incremential if you haven't fixed it already.
-Andi
Fix 32bit build for gx-suspmod.c
Pointed out by the friendly maintainer.
drivers/cpufreq/gx-suspmod.c +1 -1
@@ -172,7 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; -MODULE_DEVICE_TABLE (gx_chipset_tbl); +MODULE_DEVICE_TABLE (pci, gx_chipset_tbl);static void gx_write_byte (int reg,int value) {
Signature · 1 line
[email protected] -- Speaking for myself only
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
In reply to Andi KleenQuoted 20 lines · Andi Kleen
From: Andi Kleen <[email protected]>
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_IDsto 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)
Signed-off-by Andi Kleen <[email protected]>
...
Quoted 13 lines
drivers/cpufreq/powernow-k8.c +1
-0@@ -37,6 +37,7 @@#include <linux/delay.h> #include <asm/msr.h> +#include <asm/cpu_device_id.h> #include <linux/acpi.h> #include <linux/mutex.h>
drivers/cpufreq/powernow-k8.c static int core_voltage_post_transition(struct powernow_k8_data *data, · line 524
Quoted 10 lines
drivers/cpufreq/powernow-k8.c +7
-0@@ -514,6 +515,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,return 0 ; } +static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , },
{ X86_VENDOR_AMD, 0x15, },
Should also have BullDozer family included.
drivers/cpufreq/powernow-k8.c static int core_voltage_post_transition(struct powernow_k8_data *data, · line 526
Quoted 2 lines
drivers/cpufreq/powernow-k8.c +2
-0+/* Add more here? */ + {}
Thomas
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 10 lines
drivers/cpufreq/powernow-k8.c static int core_voltage_post_transition(struct powernow_k8_data *data, · line 524
Quoted 7 lines
drivers/cpufreq/powernow-k8.c +7
-0+static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , },{
X86_VENDOR_AMD,0x15, },Should also have BullDozer family included.
I think it really needs a cpuid feature bit for the hwpstate. This is not in one of the normal CPUID leaves, so the amd specific CPU init code would need to set it.
I added 0x15 for now, but it would be good if someone with the hardware fixed it like this.
Then could just add a match on "AMD-hw pstate" or so.
-Andi
H. Peter Anvin
maintainerRe: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 11 lines · Andi Kleen
Quoted 10 lines
drivers/cpufreq/powernow-k8.c static int core_voltage_post_transition(struct powernow_k8_data *data, · line 524
Quoted 7 lines
drivers/cpufreq/powernow-k8.c +7
-0+static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , },{
X86_VENDOR_AMD,0x15, },Should also have BullDozer family included.
Quoted 9 lines
I think it really needs a cpuid feature bit for the hwpstate. This is not in one of the normal CPUID leaves, so the amd specific CPU init code would need to set it.
I added
0x15for now, but it would be good if someone with the hardware fixed it like this.Then could just add a match on "AMD-hw pstate" or so.
Agreed. This is literally screaming for a synthetic CPUID bit.
-hpa
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 16 lines · H. Peter Anvin
Quoted 15 lines · Andi Kleen
Quoted 10 lines
drivers/cpufreq/powernow-k8.c static int core_voltage_post_transition(struct powernow_k8_data *data, · line 524
Quoted 7 lines
drivers/cpufreq/powernow-k8.c +7
-0+static const struct x86_cpu_id powernow_k8_ids[] = { + {X86_VENDOR_AMD ,0xf , }, + {X86_VENDOR_AMD ,0x10 , }, + {X86_VENDOR_AMD ,0x11 , }, + {X86_VENDOR_AMD ,0x12 , }, + {X86_VENDOR_AMD ,0x13 , }, + {X86_VENDOR_AMD ,0x14 , },{
X86_VENDOR_AMD,0x15, },Should also have BullDozer family included.
I think it really needs a cpuid feature bit for the hwpstate. This is not in one of the normal CPUID leaves, so the amd specific CPU init code would need to set it.
Quoted 7 lines
Quoted 5 lines
I added
0x15for now, but it would be good if someone with the hardware fixed it like this.Then could just add a match on "AMD-hw pstate" or so.
Agreed. This is literally screaming for a synthetic CPUID bit.
A synthetic one is pointless, because you'd just be duplicating something similar to the above in generic code that would need updating for every new stepping.
If anything other than powernow-k8 cared, there might be a more compelling argument, but I don't see the point in moving something that only this driver cares about to common code.
Dave
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 2 lines
A synthetic one is pointless, because you'd just be duplicating something similar to the above in generic code that would need updating for every new stepping.
powernow-k8 uses two mechanisms: family/models and on newer CPUs like Fam15 a CPUID bit. Just not in the standard leaves. This would not need to be updated.
} else { /* must be a HW Pstate capable processor */
cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
cpu_family = CPU_HW_PSTATE;
else
return;
}-Andi
H. Peter Anvin
maintainerRe: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 7 lines · Andi Kleen
Quoted 2 lines
A synthetic one is pointless, because you'd just be duplicating something similar to the above in generic code that would need updating for every new stepping.
powernow-k8 uses two mechanisms: family/models and on newer CPUs like Fam15 a CPUID bit. Just not in the standard leaves. This would not need to be updated.
So this should be:
1. added to the scattered CPUID features list;
2. artificially set in the AMD-specific initialization code for the older CPUs.
-hpa
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 5 lines
So this should be:
1. added to the scattered CPUID features list;
2. artificially set in the AMD-specific initialization code for the older CPUs.
Not sure (2) is correct. As far as I understand it's actually different mechanisms, just implemented by the same driver.
Keeping the list for old CPUs is not a big issue anyways.
Agreed with (1)
Anyways someone with the hardware should do it. Thomas?
-Andi
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 6 lines · Andi Kleen
Quoted 5 lines
So this should be:
1. added to the scattered CPUID features list;
2. artificially set in the AMD-specific initialization code for the older CPUs.
Quoted 8 lines
Not sure (2) is correct. As far as I understand it's actually different mechanisms, just implemented by the same driver.
Keeping the list for old CPUs is not a big issue anyways.
Agreed with (1)
Anyways someone with the hardware should do it. Thomas?
I have something.
Andi: If you don't mind, I'll pick up your patches, use drivers/base/cpu.c instead of cpuid driver. Then there will never show up a cpuid version mainline.
I'll call it v4 and this patchset then depends on Kay's work.
I'll also adjust:
- the microcode typo (in patch fix)
- add a cpuid hw_pstate (new patch)
- adjust powernow-k8 to make use of it via x86cpu autoloading (in patch adjustings)
Tell me (best in the next hour) if something else should still be added.
I'll then resend with your From: tag on top.
No idea in which tree this should end (x86-tip, because it's a x86 feature or Greg's because no further serialization care has to be taken. I'll vote for Greg's, I already work on his driver-core tree on the driver-core-next branch where Kay's stuff already is in).
I'll add everybody to CC.
Thomas
Re: [PATCH 7/8] cpufreq: Add support for x86 cpuinfo auto loading v3
Quoted 14 lines · Thomas Renninger
Quoted 13 lines · Andi Kleen
Quoted 5 lines
So this should be:
1. added to the scattered CPUID features list;
2. artificially set in the AMD-specific initialization code for the older CPUs.Not sure (2) is correct. As far as I understand it's actually different mechanisms, just implemented by the same driver.
Keeping the list for old CPUs is not a big issue anyways.
Agreed with (1)
Quoted 7 lines
Quoted 1 line
Anyways someone with the hardware should do it. Thomas?
I have something.
Andi: If you don't mind, I'll pick up your patches, use
drivers/base/cpu.cinstead of cpuid driver. Then there will never show up a cpuid version mainline.
I'll call it v4 and this patchset then depends on Kay's work.
I would prefer to keep them separated, Kay's patchkit is gigantic.
They can be always merged later, but a dependency is not really needed. It doesn't matter much whether it's in cpuid or in cpu.
Quoted 9 lines
I'll also adjust:
- the microcode typo (in patch fix)
- add a cpuidhw_pstate(new patch)
- adjust powernow-k8 to make use of it via x86cpu autoloading (in patch adjustings)Tell me (best in the next hour) if something else should still be added.
I have nothing else.
-Andi
PATCH 1/1 X86: Introduce HW-Pstate scattered cpuid feature
In reply to Andi KleenQuoted 6 lines · Andi Kleen
Quoted 5 lines
So this should be:
1. added to the scattered CPUID features list;
2. artificially set in the AMD-specific initialization code for the older CPUs.
Quoted 6 lines
Not sure (2) is correct. As far as I understand it's actually different mechanisms, just implemented by the same driver.
Keeping the list for old CPUs is not a big issue anyways.
Agreed with (1)
This would be the hw-pstate feature patch to avoid mainting families for autoloading, etc.
It should be in powernow-k8 then:
/* IO-Based switching */
{ X86_VENDOR_AMD, 0xf, },
/* Future models support MSR based switching and a cpuid bit for it */
{ X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_HW_PSTATE },Something does not work and I need to re-test and dig.
I'll embed this one into the others from Andi and will resend the next days.
Thomas
---
X86: Introduce HW-Pstate scattered cpuid feature
It is rather similar to CPB (boot capability) feature and exists since fam10h (can be looked up in AMD's BKDG).
--- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/kernel/cpu/scattered.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
@@ -176,6 +176,7 @@#define X86_FEATURE_PLN (7*32+ 5)/* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6)/* Intel Package Thermal Status */ #define X86_FEATURE_DTS (7*32+ 7)/* Digital Thermal Sensor */ +#define X86_FEATURE_HW_PSTATE (7*32+ 8)/* AMD HW-PState */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0)/* Intel TPR Shadow */
arch/x86/kernel/cpu/scattered.c +1 -0
@@ -40,6 +40,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 }, { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, + { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
PATCH 8/8 x86: autoload microcode driver on Intel and AMD systems
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Don't try to describe the actual models for now.
--- arch/x86/kernel/microcode_core.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
arch/x86/kernel/microcode_core.c +15 -0
@@ -86,6 +86,7 @@#include <asm/microcode.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> MODULE_DESCRIPTION ("Microcode Update Driver" );MODULE_AUTHOR ("Tigran Aivazian <[email protected]>" );
@@ -502,6 +503,20 @@ static struct notifier_block __refdata mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; +#ifdef MODULE +/* Autoload on Intel and AMD systems */ +static const struct x86_cpu_id microcode_id[] = { +#ifdef CONFIG_MICROCODE_INTEL + {X86_VENDOR_INTEL ,X86_VENDOR_ANY ,X86_MODEL_ANY , }, +#endif +#ifdef CONFIG_MICROCODE_AMD + {X86_VENDOR_AMD ,X86_VENDOR_ANY ,X86_MODEL_ANY , }, +#endif + {} +}; +MODULE_DEVICE_TABLE (x86cpu, microcode_id); +#endif +static int __init microcode_init (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );
Signature · 1 line
1.7.7.4
[tip:x86/autoprobe] x86: Autoload microcode driver on Intel and AMD systems
Commit-ID: 13529caa10734c46e3ab049cc1a441f332646b0c Gitweb: http://git.kernel.org/tip/13529caa10734c46e3ab049cc1a441f332646b0c Author: Andi Kleen <[email protected]> AuthorDate: Mon, 19 Dec 2011 15:46:34 -0800 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 19 Dec 2011 15:50:08 -0800
x86: Autoload microcode driver on Intel and AMD systems
Don't try to describe the actual models for now.
--- arch/x86/kernel/microcode_core.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
arch/x86/kernel/microcode_core.c +15 -0
@@ -86,6 +86,7 @@#include <asm/microcode.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> MODULE_DESCRIPTION ("Microcode Update Driver" );MODULE_AUTHOR ("Tigran Aivazian <[email protected]>" );
@@ -502,6 +503,20 @@ static struct notifier_block __refdata mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; +#ifdef MODULE +/* Autoload on Intel and AMD systems */ +static const struct x86_cpu_id microcode_id[] = { +#ifdef CONFIG_MICROCODE_INTEL + {X86_VENDOR_INTEL ,X86_VENDOR_ANY ,X86_MODEL_ANY , }, +#endif +#ifdef CONFIG_MICROCODE_AMD + {X86_VENDOR_AMD ,X86_VENDOR_ANY ,X86_MODEL_ANY , }, +#endif + {} +}; +MODULE_DEVICE_TABLE (x86cpu, microcode_id); +#endif +static int __init microcode_init (void ) {struct cpuinfo_x86 *c = &cpu_data (0 );
[PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
In reply to Andi KleenQuoted 4 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Don't try to describe the actual models for now.
...
Review
Quoted 3 lines
(quoted diff) +3
-0+static const struct x86_cpu_id microcode_id[] = { +#ifdef CONFIG_MICROCODE_INTEL + { X86_VENDOR_INTEL, X86_VENDOR_ANY, X86_MODEL_ANY, },
X86_VENDOR_ANY -> X86_FAMILY_ANY
Review
Quoted 3 lines
(quoted diff) +3
-0+#endif +#ifdef CONFIG_MICROCODE_AMD + { X86_VENDOR_AMD, X86_VENDOR_ANY, X86_MODEL_ANY, },
X86_VENDOR_ANY -> X86_FAMILY_ANY
Otherwise the patchset worked for me as expected and I got quite some (all expected?) drivers autoloaded on a recent CPU as soon as I loaded the cpuid driver:
powernow_k8
mperfcrc32c_intelghash_clmulni_intelaesni_intel
cryptdaes_x86_64
microcode
Additionally I adopted the "use cpuid because cpu is a sysdev device" approach to make use of the cpu device object (after Kay's "removal of sysdev" patches).
Kay's and Andi's patches do not conflict and can go in together. As soon as both are in, this on top patch cleans up X86 autoprobing to use the cpu device object (instead of cpuid driver):
---
CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
This patch is based on Andi Kleen's work:
Implement autoprobing/loading of modules serving CPU specific features (x86cpu autoloading).
And Kay Siever's work to get rid of sysdev cpu structures and making use of struct device instead.
--- arch/x86/Kconfig | 3 ++ arch/x86/kernel/cpu/match.c | 43 ++++++++++++++++++++++++++++++++ arch/x86/kernel/cpuid.c | 58 -------------------------------------------- drivers/base/cpu.c | 11 ++++++++ include/linux/cpu.h | 7 +++++ 5 files changed, 65 insertions(+), 57 deletions(-)
arch/x86/kernel/cpuid.c +1 -57
@@ -40,7 +40,6 @@#include <linux/notifier.h> #include <linux/uaccess.h> #include <linux/gfp.h> -#include <linux/slab.h> #include <asm/processor.h> #include <asm/msr.h>
@@ -139,56 +138,13 @@ static const struct file_operations cpui .open = cpuid_open, }; -static ssize_t print_cpu_modalias (struct device *dev, -struct device_attribute *attr, -char *bufptr) -{ -int size =PAGE_SIZE ; -int i, n; -char *buf = bufptr; - - n =snprintf (buf, size,"x86cpu:vendor:%04x:family:%04x:model:%04x:feature:" , - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -=2 ; -for (i =0 ; i <NCAPINTS *32 ; i++) { -if (boot_cpu_has (i)) { - n =snprintf (buf, size,",%04x" , i); -if (n <0 ) { -WARN (1 ,"x86 features overflow page\n" ); -break ; - } - size -= n; - buf += n; - } - } - *buf++ =',' ; - *buf++ ='\n' ; -return buf - bufptr; -} - -static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); -static __cpuinit int cpuid_device_create (int cpu) {struct device *dev; -int err; dev =device_create (cpuid_class,NULL ,MKDEV (CPUID_MAJOR , cpu),NULL ,"cpu%d" , cpu); -if (IS_ERR (dev)) -return PTR_ERR (dev); - - err =device_create_file (dev, &dev_attr_modalias); -if (err) { -/* keep device around on error. attribute is optional. */ - err =0 ; - } - -return 0 ; +return IS_ERR (dev) ?PTR_ERR (dev) :0 ; }static void cpuid_device_destroy (int cpu)
@@ -226,17 +182,6 @@ static char *cpuid_devnode(struct devicereturn kasprintf (GFP_KERNEL ,"cpu/%u/cpuid" ,MINOR (dev->devt)); } -static int cpuid_dev_uevent (struct device *dev,struct kobj_uevent_env *env) -{ -char *buf =kmalloc (PAGE_SIZE ,GFP_KERNEL ); -if (buf) { -print_cpu_modalias (NULL ,NULL , buf); -add_uevent_var (env,"MODALIAS=%s" , buf); -kfree (buf); - } -return 0 ; -} -static int __init cpuid_init (void ) {int i, err =0 ;
@@ -255,7 +200,6 @@ static int __init cpuid_init(void) goto out_chrdev; } cpuid_class->devnode = cpuid_devnode; - cpuid_class->dev_uevent = cpuid_dev_uevent;for_each_online_cpu (i) { err = cpuid_device_create(i);CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 partsif (err !=0 )
arch/x86/Kconfig +3 -0
@@ -185,6 +185,9 @@ config ARCH_HAS_DEFAULT_IDLE config ARCH_HAS_CACHE_LINE_SIZE def_bool y +config ARCH_HAS_CPU_AUTOPROBE + def_bool y + config HAVE_SETUP_PER_CPU_AREA def_bool y
drivers/base/cpu.c +11 -0
@@ -10,6 +10,7 @@#include <linux/device.h> #include <linux/node.h> #include <linux/gfp.h> +#include <linux/slab.h> #include "base.h"
@@ -221,6 +222,9 @@ int __cpuinit register_cpu(struct cpu *c cpu->node_id =cpu_to_node (num); cpu->dev.id = num; cpu->dev.bus = &cpu_subsys; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + cpu->dev.bus->uevent = arch_cpu_uevent; +#endif error =device_register (&cpu->dev);if (!error && cpu->hotpluggable)register_cpu_control (cpu);
@@ -245,6 +249,10 @@ struct device *get_cpu_device(unsigned c }EXPORT_SYMBOL_GPL (get_cpu_device); +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); +#endif +static struct attribute *cpu_root_attrs[] = { #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE &dev_attr_probe.attr,
@@ -255,6 +263,9 @@ static struct attribute *cpu_root_attrs[ &cpu_attrs[2 ].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + &dev_attr_modalias.attr, +#endif NULL };
arch/x86/kernel/cpu/match.c +43 -0
52 lines not on this page · raw message
include/linux/cpu.h +7 -0
@@ -43,6 +43,13 @@ extern ssize_t arch_cpu_release(const ch#endif struct notifier_block ; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +extern int arch_cpu_uevent (struct device *dev,struct kobj_uevent_env *env); +extern ssize_t arch_print_cpu_modalias (struct device *dev, +struct device_attribute *attr, +char *bufptr); +#endif +/* * CPU notifier priorities. */
Re: [PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
2011/12/21 Thomas Renninger <[email protected]>:
Cool. That sounds good. Nice work. Thanks.
Adding Greg, so he's in the loop.
Greg, Andi's upcoming CPU modaliases are temporarily hooked into the 'cpuid' class devices to make them work with userspace, which isn't possible with the weird sysdev stuff.
We don't want to depend on the 'cpuid' class, but hook into the real 'cpu' subsystem. This switches them over after we have the sysdev-cpu-conversion stuff merged.
Thanks,
Kay
Quoted 248 lines
CPU: Introduce
ARCH_HAS_CPU_AUTOPROBEand X86 partsThis patch is based on Andi Kleen's work:
Implement autoprobing/loading of modules serving CPU specific features (x86cpu autoloading).And Kay Siever's work to get rid of sysdev cpu structures and making use of struct device instead.
Signed-off-by Thomas Renninger <[email protected]>---
arch/x86/Kconfig | 3 ++
arch/x86/kernel/cpu/match.c | 43 ++++++++++++++++++++++++++++++++arch/x86/kernel/cpuid.c| 58 --------------------------------------------drivers/base/cpu.c| 11 ++++++++
include/linux/cpu.h | 7 +++++5 files changed, 65 insertions(+), 57 deletions(-)Index:
linux-3.2-rc6-master/arch/x86/kernel/cpuid.c
===================================================================arch/x86/kernel/cpuid.c +1
-57@@ -40,7 +40,6 @@ #include <linux/notifier.h> #include <linux/uaccess.h> #include <linux/gfp.h> -#include <linux/slab.h> #include <asm/processor.h> #include <asm/msr.h>@@ -139,56 +138,13 @@ static const struct file_operations cpui .open = cpuid_open, }; -static ssize_t print_cpu_modalias (struct device *dev, - struct device_attribute *attr, - char *bufptr) -{ - int size = PAGE_SIZE; - int i, n; - char *buf = bufptr; - - n = snprintf(buf, size, "x86cpu:vendor:%04x:family:%04x:model:%04x:feature:", - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -= 2; - for (i = 0; i < NCAPINTS*32; i++) { - if (boot_cpu_has(i)) { - n = snprintf(buf, size, ",%04x", i); - if (n < 0) { - WARN(1, "x86 features overflow page\n"); - break; - } - size -= n; - buf += n; - } - } - *buf++ = ','; - *buf++ = '\n'; - return buf - bufptr; -} - -static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); - static __cpuinit int cpuid_device_create(int cpu) { struct device *dev; - int err; dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL, "cpu%d", cpu); - if (IS_ERR(dev)) - return PTR_ERR(dev); - - err = device_create_file(dev, &dev_attr_modalias); - if (err) { - /* keep device around on error. attribute is optional. */ - err = 0; - } - - return 0; + return IS_ERR(dev) ? PTR_ERR(dev) : 0; } static void cpuid_device_destroy(int cpu)@@ -226,17 +182,6 @@ static char *cpuid_devnode(struct device return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt)); } -static int cpuid_dev_uevent (struct device *dev,struct kobj_uevent_env *env) -{ - char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - print_cpu_modalias(NULL, NULL, buf); - add_uevent_var(env, "MODALIAS=%s", buf); - kfree(buf); - } - return 0; -} - static int __init cpuid_init(void) { int i, err = 0;@@ -255,7 +200,6 @@ static int __init cpuid_init(void) goto out_chrdev; } cpuid_class->devnode = cpuid_devnode; - cpuid_class->dev_uevent = cpuid_dev_uevent; for_each_online_cpu(i) {err = cpuid_device_create(i);CPU: Introduce
ARCH_HAS_CPU_AUTOPROBEand X86 parts if (err != 0)
Index: linux-3.2-rc6-master/arch/x86/Kconfig
===================================================================arch/x86/Kconfig +0
-0@@ -185,6 +185,9 @@ config ARCH_HAS_DEFAULT_IDLEconfig
ARCH_HAS_CACHE_LINE_SIZE
def_bool yarch/x86/Kconfig +3
-0+config ARCH_HAS_CPU_AUTOPROBE + def_bool y +config
HAVE_SETUP_PER_CPU_AREA
def_bool yIndex:
linux-3.2-rc6-master/drivers/base/cpu.c
===================================================================drivers/base/cpu.c +11
-0@@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/node.h> #include <linux/gfp.h> +#include <linux/slab.h> #include "base.h"@@ -221,6 +222,9 @@ int __cpuinit register_cpu(struct cpu *c cpu->node_id = cpu_to_node(num); cpu->dev.id = num; cpu->dev.bus = &cpu_subsys; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + cpu->dev.bus->uevent = arch_cpu_uevent; +#endif error = device_register(&cpu->dev); if (!error && cpu->hotpluggable) register_cpu_control(cpu);@@ -245,6 +249,10 @@ struct device *get_cpu_device(unsigned c } EXPORT_SYMBOL_GPL(get_cpu_device); +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); +#endif + static struct attribute *cpu_root_attrs[] = { #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE &dev_attr_probe.attr,@@ -255,6 +263,9 @@ static struct attribute *cpu_root_attrs[ &cpu_attrs[2].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + &dev_attr_modalias.attr, +#endif NULL
};Index:
linux-3.2-rc6-master/arch/x86/kernel/cpu/match.c
===================================================================arch/x86/kernel/cpu/match.c +43
-0@@ -2,6 +2,7 @@ #include <asm/processor.h> #include <linux/cpu.h> #include <linux/module.h> +#include <linux/slab.h> /*** x86_match_cpu - match current CPU again an array of x86_cpu_ids @@ -46,3 +47,45 @@ const struct x86_cpu_id *x86_match_cpu(c return NULL; } EXPORT_SYMBOL(x86_match_cpu); + +ssize_t arch_print_cpu_modalias (struct device *dev, + struct device_attribute *attr, + char *bufptr) +{ + int size = PAGE_SIZE; + int i, n; + char *buf = bufptr; + + n = snprintf(buf, size, "x86cpu:vendor:%04x:family:%04x:model:%04x:feature:", + boot_cpu_data.x86_vendor, + boot_cpu_data.x86, + boot_cpu_data.x86_model); + size -= n; + buf += n; + size -= 2; + for (i = 0; i < NCAPINTS*32; i++) { + if (boot_cpu_has(i)) { + n = snprintf(buf, size, ",%04x", i); + if (n < 0) { + WARN(1, "x86 features overflow page\n"); + break; + } + size -= n; + buf += n; + } + } + *buf++ = ','; + *buf++ = '\n'; + return buf - bufptr; +} + +int arch_cpu_uevent (struct device *dev,struct kobj_uevent_env *env) +{ + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + arch_print_cpu_modalias(NULL, NULL, buf); + add_uevent_var(env, "MODALIAS=%s", buf); + kfree(buf); + } + return 0; +}Index:
linux-3.2-rc6-master/include/linux/cpu.h
===================================================================include/linux/cpu.h +0
-0@@ -43,6 +43,13 @@ extern ssize_t arch_cpu_release(const ch #endif struct notifier_block;
include/linux/cpu.h extern ssize_t arch_cpu_release(const ch · line 55
Quoted 10 lines
include/linux/cpu.h +7
-0+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +extern int arch_cpu_uevent (struct device *dev,struct kobj_uevent_env *env); +extern ssize_t arch_print_cpu_modalias (struct device *dev, + struct device_attribute *attr, + char *bufptr); +#endif + /** CPU notifier priorities. */
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Re: [PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
Quoted 6 lines · Kay Sievers
2011/12/21 Thomas Renninger <[email protected]>:
Cool. That sounds good. Nice work. Thanks.
Adding Greg, so he's in the loop.
Quoted 7 lines
Greg, Andi's upcoming CPU modaliases are temporarily hooked into the 'cpuid' class devices to make them work with userspace, which isn't possible with the weird sysdev stuff.
We don't want to depend on the 'cpuid' class, but hook into the real 'cpu' subsystem. This switches them over after we have the sysdev-cpu-conversion stuff merged.
Ok, but what does this mean now for my tree as I've taken your patches?
confused,
greg k-h
H. Peter Anvin
maintainerRe: [PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
Quoted 11 lines · Greg KH
Quoted 10 lines · Kay Sievers
2011/12/21 Thomas Renninger<[email protected]>:
Cool. That sounds good. Nice work. Thanks.
Adding Greg, so he's in the loop.
Greg, Andi's upcoming CPU modaliases are temporarily hooked into the 'cpuid' class devices to make them work with userspace, which isn't possible with the weird sysdev stuff.
Quoted 6 lines
Quoted 3 lines
We don't want to depend on the 'cpuid' class, but hook into the real 'cpu' subsystem. This switches them over after we have the sysdev-cpu-conversion stuff merged.
Ok, but what does this mean now for my tree as I've taken your patches?
If I understand Kay right it means that once this tree and the patches from Kay are both upstream we can apply the cleanup patch.
Kay, is that correct?
-hpa
Re: [PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
Quoted 10 lines · H. Peter Anvin
Quoted 8 lines · Greg KH
Quoted 7 lines
Greg, Andi's upcoming CPU modaliases are temporarily hooked into the 'cpuid' class devices to make them work with userspace, which isn't possible with the weird sysdev stuff.
We don't want to depend on the 'cpuid' class, but hook into the real 'cpu' subsystem. This switches them over after we have the sysdev-cpu-conversion stuff merged.
Quoted 6 lines
Quoted 1 line
Ok, but what does this mean now for my tree as I've taken your patches?
If I understand Kay right it means that once this tree and the patches from Kay are both upstream we can apply the cleanup patch.
Kay, is that correct?
Correct.
Andi added the modalias stuff to the 'cpuid' class because that has the proper userspace hookup. But we want to have the modalias at the real 'cpu' devices.
Thomas' patch (the above) moves them over, now that we can do that with the weird sysdev stuff gone.
Kay
H. Peter Anvin
maintainerRe: [PATCH 9/8] CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts
Quoted 18 lines · Kay Sievers
Quoted 10 lines · H. Peter Anvin
Quoted 8 lines · Greg KH
Quoted 7 lines
Greg, Andi's upcoming CPU modaliases are temporarily hooked into the 'cpuid' class devices to make them work with userspace, which isn't possible with the weird sysdev stuff.
We don't want to depend on the 'cpuid' class, but hook into the real 'cpu' subsystem. This switches them over after we have the sysdev-cpu-conversion stuff merged.
Quoted 6 lines
Quoted 1 line
Ok, but what does this mean now for my tree as I've taken your patches?
If I understand Kay right it means that once this tree and the patches from Kay are both upstream we can apply the cleanup patch.
Kay, is that correct?
Quoted 9 lines
Correct.
Andi added the modalias stuff to the 'cpuid' class because that has the proper userspace hookup. But we want to have the modalias at the real 'cpu' devices.
Thomas' patch (the above) moves them over, now that we can do that with the weird sysdev stuff gone.
But we need Greg's stuff upstream first, right? So the sequence becomes
a) merge Greg's tree b) merge this tree c) merge the cleanup.
-hpa