X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fcpuid.c;h=2e2756345bb23964f763ff747e284c7e89050678;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=5a997a3716fc317476148fbe462efbdac5aba6a2;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 5a997a371..2e2756345 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -36,12 +36,17 @@ #include #include #include +#include +#include +#include #include #include #include #include +static struct class_simple *cpuid_class; + #ifdef CONFIG_SMP struct cpuid_command { @@ -153,20 +158,84 @@ static struct file_operations cpuid_fops = { .open = cpuid_open, }; -int __init cpuid_init(void) +static int cpuid_class_simple_device_add(int i) +{ + int err = 0; + struct class_device *class_err; + + class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); + if (IS_ERR(class_err)) + err = PTR_ERR(class_err); + return err; +} + +static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + switch (action) { + case CPU_ONLINE: + cpuid_class_simple_device_add(cpu); + break; + case CPU_DEAD: + class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu)); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block cpuid_class_cpu_notifier = +{ + .notifier_call = cpuid_class_cpu_callback, +}; + +static int __init cpuid_init(void) { + int i, err = 0; + i = 0; + if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) { printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n", CPUID_MAJOR); - return -EBUSY; + err = -EBUSY; + goto out; + } + cpuid_class = class_simple_create(THIS_MODULE, "cpuid"); + if (IS_ERR(cpuid_class)) { + err = PTR_ERR(cpuid_class); + goto out_chrdev; } + for_each_online_cpu(i) { + err = cpuid_class_simple_device_add(i); + if (err != 0) + goto out_class; + } + register_cpu_notifier(&cpuid_class_cpu_notifier); - return 0; + err = 0; + goto out; + +out_class: + i = 0; + for_each_online_cpu(i) { + class_simple_device_remove(MKDEV(CPUID_MAJOR, i)); + } + class_simple_destroy(cpuid_class); +out_chrdev: + unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); +out: + return err; } -void __exit cpuid_exit(void) +static void __exit cpuid_exit(void) { + int cpu = 0; + + for_each_online_cpu(cpu) + class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu)); + class_simple_destroy(cpuid_class); unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); + unregister_cpu_notifier(&cpuid_class_cpu_notifier); } module_init(cpuid_init);