diff options
-rw-r--r-- | arch/i386/kernel/cpu/intel_cacheinfo.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 7cc84a4a6df9..f0839334881c 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Changes: | 4 | * Changes: |
5 | * Venkatesh Pallipadi : Adding cache identification through cpuid(4) | 5 | * Venkatesh Pallipadi : Adding cache identification through cpuid(4) |
6 | * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure. | ||
6 | */ | 7 | */ |
7 | 8 | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
@@ -28,7 +29,7 @@ struct _cache_table | |||
28 | }; | 29 | }; |
29 | 30 | ||
30 | /* all the cache descriptor types we care about (no TLB or trace cache entries) */ | 31 | /* all the cache descriptor types we care about (no TLB or trace cache entries) */ |
31 | static struct _cache_table cache_table[] __devinitdata = | 32 | static struct _cache_table cache_table[] __cpuinitdata = |
32 | { | 33 | { |
33 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ | 34 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ |
34 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ | 35 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ |
@@ -119,7 +120,7 @@ struct _cpuid4_info { | |||
119 | 120 | ||
120 | static unsigned short num_cache_leaves; | 121 | static unsigned short num_cache_leaves; |
121 | 122 | ||
122 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 123 | static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) |
123 | { | 124 | { |
124 | unsigned int eax, ebx, ecx, edx; | 125 | unsigned int eax, ebx, ecx, edx; |
125 | union _cpuid4_leaf_eax cache_eax; | 126 | union _cpuid4_leaf_eax cache_eax; |
@@ -154,7 +155,7 @@ static int __init find_num_cache_leaves(void) | |||
154 | return i; | 155 | return i; |
155 | } | 156 | } |
156 | 157 | ||
157 | unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | 158 | unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) |
158 | { | 159 | { |
159 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ | 160 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ |
160 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ | 161 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ |
@@ -289,7 +290,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS]; | |||
289 | #define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) | 290 | #define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) |
290 | 291 | ||
291 | #ifdef CONFIG_SMP | 292 | #ifdef CONFIG_SMP |
292 | static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | 293 | static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) |
293 | { | 294 | { |
294 | struct _cpuid4_info *this_leaf; | 295 | struct _cpuid4_info *this_leaf; |
295 | unsigned long num_threads_sharing; | 296 | unsigned long num_threads_sharing; |
@@ -322,7 +323,7 @@ static void free_cache_attributes(unsigned int cpu) | |||
322 | cpuid4_info[cpu] = NULL; | 323 | cpuid4_info[cpu] = NULL; |
323 | } | 324 | } |
324 | 325 | ||
325 | static int __devinit detect_cache_attributes(unsigned int cpu) | 326 | static int __cpuinit detect_cache_attributes(unsigned int cpu) |
326 | { | 327 | { |
327 | struct _cpuid4_info *this_leaf; | 328 | struct _cpuid4_info *this_leaf; |
328 | unsigned long j; | 329 | unsigned long j; |
@@ -499,7 +500,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu) | |||
499 | free_cache_attributes(cpu); | 500 | free_cache_attributes(cpu); |
500 | } | 501 | } |
501 | 502 | ||
502 | static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu) | 503 | static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) |
503 | { | 504 | { |
504 | 505 | ||
505 | if (num_cache_leaves == 0) | 506 | if (num_cache_leaves == 0) |
@@ -530,7 +531,7 @@ err_out: | |||
530 | } | 531 | } |
531 | 532 | ||
532 | /* Add/Remove cache interface for CPU device */ | 533 | /* Add/Remove cache interface for CPU device */ |
533 | static int __devinit cache_add_dev(struct sys_device * sys_dev) | 534 | static int __cpuinit cache_add_dev(struct sys_device * sys_dev) |
534 | { | 535 | { |
535 | unsigned int cpu = sys_dev->id; | 536 | unsigned int cpu = sys_dev->id; |
536 | unsigned long i, j; | 537 | unsigned long i, j; |
@@ -567,7 +568,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev) | |||
567 | return retval; | 568 | return retval; |
568 | } | 569 | } |
569 | 570 | ||
570 | static int __devexit cache_remove_dev(struct sys_device * sys_dev) | 571 | static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) |
571 | { | 572 | { |
572 | unsigned int cpu = sys_dev->id; | 573 | unsigned int cpu = sys_dev->id; |
573 | unsigned long i; | 574 | unsigned long i; |
@@ -576,24 +577,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev) | |||
576 | kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); | 577 | kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); |
577 | kobject_unregister(cache_kobject[cpu]); | 578 | kobject_unregister(cache_kobject[cpu]); |
578 | cpuid4_cache_sysfs_exit(cpu); | 579 | cpuid4_cache_sysfs_exit(cpu); |
579 | return 0; | 580 | return; |
581 | } | ||
582 | |||
583 | static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | ||
584 | unsigned long action, void *hcpu) | ||
585 | { | ||
586 | unsigned int cpu = (unsigned long)hcpu; | ||
587 | struct sys_device *sys_dev; | ||
588 | |||
589 | sys_dev = get_cpu_sysdev(cpu); | ||
590 | switch (action) { | ||
591 | case CPU_ONLINE: | ||
592 | cache_add_dev(sys_dev); | ||
593 | break; | ||
594 | case CPU_DEAD: | ||
595 | cache_remove_dev(sys_dev); | ||
596 | break; | ||
597 | } | ||
598 | return NOTIFY_OK; | ||
580 | } | 599 | } |
581 | 600 | ||
582 | static struct sysdev_driver cache_sysdev_driver = { | 601 | static struct notifier_block cacheinfo_cpu_notifier = |
583 | .add = cache_add_dev, | 602 | { |
584 | .remove = __devexit_p(cache_remove_dev), | 603 | .notifier_call = cacheinfo_cpu_callback, |
585 | }; | 604 | }; |
586 | 605 | ||
587 | /* Register/Unregister the cpu_cache driver */ | 606 | static int __cpuinit cache_sysfs_init(void) |
588 | static int __devinit cache_register_driver(void) | ||
589 | { | 607 | { |
608 | int i; | ||
609 | |||
590 | if (num_cache_leaves == 0) | 610 | if (num_cache_leaves == 0) |
591 | return 0; | 611 | return 0; |
592 | 612 | ||
593 | return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver); | 613 | register_cpu_notifier(&cacheinfo_cpu_notifier); |
614 | |||
615 | for_each_online_cpu(i) { | ||
616 | cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE, | ||
617 | (void *)(long)i); | ||
618 | } | ||
619 | |||
620 | return 0; | ||
594 | } | 621 | } |
595 | 622 | ||
596 | device_initcall(cache_register_driver); | 623 | device_initcall(cache_sysfs_init); |
597 | 624 | ||
598 | #endif | 625 | #endif |
599 | |||