diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-21 04:46:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-21 04:46:54 -0400 |
commit | 8ecee4620e76aae418bfa0e8cc830e92cb559bbb (patch) | |
tree | 49a36784c0a26c8494a37087e37502101013b35d /arch/x86/kernel | |
parent | 6424fb38667fffbbb1b90be0ffd9a0c540db6a4b (diff) | |
parent | a939b96cccdb65df80a52447ec8e4a6d79c56dbb (diff) |
Merge branch 'linus' into x86/mm
Merge reason: refresh the topic: there's been 290 non-merges commits upstream
to arch/x86 alone.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
86 files changed, 2252 insertions, 1588 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 339ce35648e6..145cce75cda7 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -66,11 +66,11 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o | |||
66 | obj-y += apic/ | 66 | obj-y += apic/ |
67 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o | 67 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o |
68 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 68 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
69 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 69 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
70 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | ||
70 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o | 71 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o |
71 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o | 72 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o |
72 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o | 73 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o |
73 | obj-$(CONFIG_X86_VSMP) += vsmp_64.o | ||
74 | obj-$(CONFIG_KPROBES) += kprobes.o | 74 | obj-$(CONFIG_KPROBES) += kprobes.o |
75 | obj-$(CONFIG_MODULES) += module_$(BITS).o | 75 | obj-$(CONFIG_MODULES) += module_$(BITS).o |
76 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o | 76 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o |
@@ -106,7 +106,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o | |||
106 | 106 | ||
107 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o | 107 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o |
108 | 108 | ||
109 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64 | 109 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
110 | 110 | ||
111 | ### | 111 | ### |
112 | # 64 bit specific files | 112 | # 64 bit specific files |
@@ -120,4 +120,5 @@ ifeq ($(CONFIG_X86_64),y) | |||
120 | obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o | 120 | obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o |
121 | 121 | ||
122 | obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o | 122 | obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o |
123 | obj-y += vsmp_64.o | ||
123 | endif | 124 | endif |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a18eb7ce2236..723989d7f802 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | static int __init | 232 | static int __init |
233 | acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) | ||
234 | { | ||
235 | struct acpi_madt_local_x2apic *processor = NULL; | ||
236 | |||
237 | processor = (struct acpi_madt_local_x2apic *)header; | ||
238 | |||
239 | if (BAD_MADT_ENTRY(processor, end)) | ||
240 | return -EINVAL; | ||
241 | |||
242 | acpi_table_print_madt_entry(header); | ||
243 | |||
244 | #ifdef CONFIG_X86_X2APIC | ||
245 | /* | ||
246 | * We need to register disabled CPU as well to permit | ||
247 | * counting disabled CPUs. This allows us to size | ||
248 | * cpus_possible_map more accurately, to permit | ||
249 | * to not preallocating memory for all NR_CPUS | ||
250 | * when we use CPU hotplug. | ||
251 | */ | ||
252 | acpi_register_lapic(processor->local_apic_id, /* APIC ID */ | ||
253 | processor->lapic_flags & ACPI_MADT_ENABLED); | ||
254 | #else | ||
255 | printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); | ||
256 | #endif | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int __init | ||
233 | acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) | 262 | acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) |
234 | { | 263 | { |
235 | struct acpi_madt_local_apic *processor = NULL; | 264 | struct acpi_madt_local_apic *processor = NULL; |
@@ -289,6 +318,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, | |||
289 | } | 318 | } |
290 | 319 | ||
291 | static int __init | 320 | static int __init |
321 | acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, | ||
322 | const unsigned long end) | ||
323 | { | ||
324 | struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL; | ||
325 | |||
326 | x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; | ||
327 | |||
328 | if (BAD_MADT_ENTRY(x2apic_nmi, end)) | ||
329 | return -EINVAL; | ||
330 | |||
331 | acpi_table_print_madt_entry(header); | ||
332 | |||
333 | if (x2apic_nmi->lint != 1) | ||
334 | printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int __init | ||
292 | acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) | 340 | acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) |
293 | { | 341 | { |
294 | struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; | 342 | struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; |
@@ -793,6 +841,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) | |||
793 | static int __init acpi_parse_madt_lapic_entries(void) | 841 | static int __init acpi_parse_madt_lapic_entries(void) |
794 | { | 842 | { |
795 | int count; | 843 | int count; |
844 | int x2count = 0; | ||
796 | 845 | ||
797 | if (!cpu_has_apic) | 846 | if (!cpu_has_apic) |
798 | return -ENODEV; | 847 | return -ENODEV; |
@@ -816,22 +865,28 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
816 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, | 865 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, |
817 | acpi_parse_sapic, MAX_APICS); | 866 | acpi_parse_sapic, MAX_APICS); |
818 | 867 | ||
819 | if (!count) | 868 | if (!count) { |
869 | x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, | ||
870 | acpi_parse_x2apic, MAX_APICS); | ||
820 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, | 871 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, |
821 | acpi_parse_lapic, MAX_APICS); | 872 | acpi_parse_lapic, MAX_APICS); |
822 | if (!count) { | 873 | } |
874 | if (!count && !x2count) { | ||
823 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); | 875 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); |
824 | /* TBD: Cleanup to allow fallback to MPS */ | 876 | /* TBD: Cleanup to allow fallback to MPS */ |
825 | return -ENODEV; | 877 | return -ENODEV; |
826 | } else if (count < 0) { | 878 | } else if (count < 0 || x2count < 0) { |
827 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); | 879 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); |
828 | /* TBD: Cleanup to allow fallback to MPS */ | 880 | /* TBD: Cleanup to allow fallback to MPS */ |
829 | return count; | 881 | return count; |
830 | } | 882 | } |
831 | 883 | ||
884 | x2count = | ||
885 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI, | ||
886 | acpi_parse_x2apic_nmi, 0); | ||
832 | count = | 887 | count = |
833 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); | 888 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); |
834 | if (count < 0) { | 889 | if (count < 0 || x2count < 0) { |
835 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); | 890 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); |
836 | /* TBD: Cleanup to allow fallback to MPS */ | 891 | /* TBD: Cleanup to allow fallback to MPS */ |
837 | return count; | 892 | return count; |
@@ -1470,7 +1525,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) | |||
1470 | 1525 | ||
1471 | /* | 1526 | /* |
1472 | * If your system is blacklisted here, but you find that acpi=force | 1527 | * If your system is blacklisted here, but you find that acpi=force |
1473 | * works for you, please contact acpi-devel@sourceforge.net | 1528 | * works for you, please contact linux-acpi@vger.kernel.org |
1474 | */ | 1529 | */ |
1475 | static struct dmi_system_id __initdata acpi_dmi_table[] = { | 1530 | static struct dmi_system_id __initdata acpi_dmi_table[] = { |
1476 | /* | 1531 | /* |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 4c80f1557433..f57658702571 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kprobes.h> | 5 | #include <linux/kprobes.h> |
6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
7 | #include <linux/vmalloc.h> | 7 | #include <linux/vmalloc.h> |
8 | #include <linux/memory.h> | ||
8 | #include <asm/alternative.h> | 9 | #include <asm/alternative.h> |
9 | #include <asm/sections.h> | 10 | #include <asm/sections.h> |
10 | #include <asm/pgtable.h> | 11 | #include <asm/pgtable.h> |
@@ -12,7 +13,9 @@ | |||
12 | #include <asm/nmi.h> | 13 | #include <asm/nmi.h> |
13 | #include <asm/vsyscall.h> | 14 | #include <asm/vsyscall.h> |
14 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
16 | #include <asm/tlbflush.h> | ||
15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/fixmap.h> | ||
16 | 19 | ||
17 | #define MAX_PATCH_LEN (255-1) | 20 | #define MAX_PATCH_LEN (255-1) |
18 | 21 | ||
@@ -226,6 +229,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) | |||
226 | { | 229 | { |
227 | u8 **ptr; | 230 | u8 **ptr; |
228 | 231 | ||
232 | mutex_lock(&text_mutex); | ||
229 | for (ptr = start; ptr < end; ptr++) { | 233 | for (ptr = start; ptr < end; ptr++) { |
230 | if (*ptr < text) | 234 | if (*ptr < text) |
231 | continue; | 235 | continue; |
@@ -234,6 +238,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) | |||
234 | /* turn DS segment override prefix into lock prefix */ | 238 | /* turn DS segment override prefix into lock prefix */ |
235 | text_poke(*ptr, ((unsigned char []){0xf0}), 1); | 239 | text_poke(*ptr, ((unsigned char []){0xf0}), 1); |
236 | }; | 240 | }; |
241 | mutex_unlock(&text_mutex); | ||
237 | } | 242 | } |
238 | 243 | ||
239 | static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) | 244 | static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) |
@@ -243,6 +248,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end | |||
243 | if (noreplace_smp) | 248 | if (noreplace_smp) |
244 | return; | 249 | return; |
245 | 250 | ||
251 | mutex_lock(&text_mutex); | ||
246 | for (ptr = start; ptr < end; ptr++) { | 252 | for (ptr = start; ptr < end; ptr++) { |
247 | if (*ptr < text) | 253 | if (*ptr < text) |
248 | continue; | 254 | continue; |
@@ -251,6 +257,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end | |||
251 | /* turn lock prefix into DS segment override prefix */ | 257 | /* turn lock prefix into DS segment override prefix */ |
252 | text_poke(*ptr, ((unsigned char []){0x3E}), 1); | 258 | text_poke(*ptr, ((unsigned char []){0x3E}), 1); |
253 | }; | 259 | }; |
260 | mutex_unlock(&text_mutex); | ||
254 | } | 261 | } |
255 | 262 | ||
256 | struct smp_alt_module { | 263 | struct smp_alt_module { |
@@ -500,15 +507,16 @@ void *text_poke_early(void *addr, const void *opcode, size_t len) | |||
500 | * It means the size must be writable atomically and the address must be aligned | 507 | * It means the size must be writable atomically and the address must be aligned |
501 | * in a way that permits an atomic write. It also makes sure we fit on a single | 508 | * in a way that permits an atomic write. It also makes sure we fit on a single |
502 | * page. | 509 | * page. |
510 | * | ||
511 | * Note: Must be called under text_mutex. | ||
503 | */ | 512 | */ |
504 | void *__kprobes text_poke(void *addr, const void *opcode, size_t len) | 513 | void *__kprobes text_poke(void *addr, const void *opcode, size_t len) |
505 | { | 514 | { |
515 | unsigned long flags; | ||
506 | char *vaddr; | 516 | char *vaddr; |
507 | int nr_pages = 2; | ||
508 | struct page *pages[2]; | 517 | struct page *pages[2]; |
509 | int i; | 518 | int i; |
510 | 519 | ||
511 | might_sleep(); | ||
512 | if (!core_kernel_text((unsigned long)addr)) { | 520 | if (!core_kernel_text((unsigned long)addr)) { |
513 | pages[0] = vmalloc_to_page(addr); | 521 | pages[0] = vmalloc_to_page(addr); |
514 | pages[1] = vmalloc_to_page(addr + PAGE_SIZE); | 522 | pages[1] = vmalloc_to_page(addr + PAGE_SIZE); |
@@ -518,18 +526,21 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len) | |||
518 | pages[1] = virt_to_page(addr + PAGE_SIZE); | 526 | pages[1] = virt_to_page(addr + PAGE_SIZE); |
519 | } | 527 | } |
520 | BUG_ON(!pages[0]); | 528 | BUG_ON(!pages[0]); |
521 | if (!pages[1]) | 529 | local_irq_save(flags); |
522 | nr_pages = 1; | 530 | set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0])); |
523 | vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); | 531 | if (pages[1]) |
524 | BUG_ON(!vaddr); | 532 | set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1])); |
525 | local_irq_disable(); | 533 | vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0); |
526 | memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); | 534 | memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); |
527 | local_irq_enable(); | 535 | clear_fixmap(FIX_TEXT_POKE0); |
528 | vunmap(vaddr); | 536 | if (pages[1]) |
537 | clear_fixmap(FIX_TEXT_POKE1); | ||
538 | local_flush_tlb(); | ||
529 | sync_core(); | 539 | sync_core(); |
530 | /* Could also do a CLFLUSH here to speed up CPU recovery; but | 540 | /* Could also do a CLFLUSH here to speed up CPU recovery; but |
531 | that causes hangs on some VIA CPUs. */ | 541 | that causes hangs on some VIA CPUs. */ |
532 | for (i = 0; i < len; i++) | 542 | for (i = 0; i < len; i++) |
533 | BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]); | 543 | BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]); |
544 | local_irq_restore(flags); | ||
534 | return addr; | 545 | return addr; |
535 | } | 546 | } |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 5113c080f0c4..a97db99dad52 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -22,10 +22,9 @@ | |||
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/iommu-helper.h> | 26 | #include <linux/iommu-helper.h> |
26 | #ifdef CONFIG_IOMMU_API | ||
27 | #include <linux/iommu.h> | 27 | #include <linux/iommu.h> |
28 | #endif | ||
29 | #include <asm/proto.h> | 28 | #include <asm/proto.h> |
30 | #include <asm/iommu.h> | 29 | #include <asm/iommu.h> |
31 | #include <asm/gart.h> | 30 | #include <asm/gart.h> |
@@ -1297,8 +1296,10 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
1297 | /* | 1296 | /* |
1298 | * The exported map_single function for dma_ops. | 1297 | * The exported map_single function for dma_ops. |
1299 | */ | 1298 | */ |
1300 | static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | 1299 | static dma_addr_t map_page(struct device *dev, struct page *page, |
1301 | size_t size, int dir) | 1300 | unsigned long offset, size_t size, |
1301 | enum dma_data_direction dir, | ||
1302 | struct dma_attrs *attrs) | ||
1302 | { | 1303 | { |
1303 | unsigned long flags; | 1304 | unsigned long flags; |
1304 | struct amd_iommu *iommu; | 1305 | struct amd_iommu *iommu; |
@@ -1306,6 +1307,7 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | |||
1306 | u16 devid; | 1307 | u16 devid; |
1307 | dma_addr_t addr; | 1308 | dma_addr_t addr; |
1308 | u64 dma_mask; | 1309 | u64 dma_mask; |
1310 | phys_addr_t paddr = page_to_phys(page) + offset; | ||
1309 | 1311 | ||
1310 | INC_STATS_COUNTER(cnt_map_single); | 1312 | INC_STATS_COUNTER(cnt_map_single); |
1311 | 1313 | ||
@@ -1340,8 +1342,8 @@ out: | |||
1340 | /* | 1342 | /* |
1341 | * The exported unmap_single function for dma_ops. | 1343 | * The exported unmap_single function for dma_ops. |
1342 | */ | 1344 | */ |
1343 | static void unmap_single(struct device *dev, dma_addr_t dma_addr, | 1345 | static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, |
1344 | size_t size, int dir) | 1346 | enum dma_data_direction dir, struct dma_attrs *attrs) |
1345 | { | 1347 | { |
1346 | unsigned long flags; | 1348 | unsigned long flags; |
1347 | struct amd_iommu *iommu; | 1349 | struct amd_iommu *iommu; |
@@ -1390,7 +1392,8 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, | |||
1390 | * lists). | 1392 | * lists). |
1391 | */ | 1393 | */ |
1392 | static int map_sg(struct device *dev, struct scatterlist *sglist, | 1394 | static int map_sg(struct device *dev, struct scatterlist *sglist, |
1393 | int nelems, int dir) | 1395 | int nelems, enum dma_data_direction dir, |
1396 | struct dma_attrs *attrs) | ||
1394 | { | 1397 | { |
1395 | unsigned long flags; | 1398 | unsigned long flags; |
1396 | struct amd_iommu *iommu; | 1399 | struct amd_iommu *iommu; |
@@ -1457,7 +1460,8 @@ unmap: | |||
1457 | * lists). | 1460 | * lists). |
1458 | */ | 1461 | */ |
1459 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, | 1462 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, |
1460 | int nelems, int dir) | 1463 | int nelems, enum dma_data_direction dir, |
1464 | struct dma_attrs *attrs) | ||
1461 | { | 1465 | { |
1462 | unsigned long flags; | 1466 | unsigned long flags; |
1463 | struct amd_iommu *iommu; | 1467 | struct amd_iommu *iommu; |
@@ -1644,11 +1648,11 @@ static void prealloc_protection_domains(void) | |||
1644 | } | 1648 | } |
1645 | } | 1649 | } |
1646 | 1650 | ||
1647 | static struct dma_mapping_ops amd_iommu_dma_ops = { | 1651 | static struct dma_map_ops amd_iommu_dma_ops = { |
1648 | .alloc_coherent = alloc_coherent, | 1652 | .alloc_coherent = alloc_coherent, |
1649 | .free_coherent = free_coherent, | 1653 | .free_coherent = free_coherent, |
1650 | .map_single = map_single, | 1654 | .map_page = map_page, |
1651 | .unmap_single = unmap_single, | 1655 | .unmap_page = unmap_page, |
1652 | .map_sg = map_sg, | 1656 | .map_sg = map_sg, |
1653 | .unmap_sg = unmap_sg, | 1657 | .unmap_sg = unmap_sg, |
1654 | .dma_supported = amd_iommu_dma_supported, | 1658 | .dma_supported = amd_iommu_dma_supported, |
@@ -1924,6 +1928,12 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | |||
1924 | return paddr; | 1928 | return paddr; |
1925 | } | 1929 | } |
1926 | 1930 | ||
1931 | static int amd_iommu_domain_has_cap(struct iommu_domain *domain, | ||
1932 | unsigned long cap) | ||
1933 | { | ||
1934 | return 0; | ||
1935 | } | ||
1936 | |||
1927 | static struct iommu_ops amd_iommu_ops = { | 1937 | static struct iommu_ops amd_iommu_ops = { |
1928 | .domain_init = amd_iommu_domain_init, | 1938 | .domain_init = amd_iommu_domain_init, |
1929 | .domain_destroy = amd_iommu_domain_destroy, | 1939 | .domain_destroy = amd_iommu_domain_destroy, |
@@ -1932,5 +1942,6 @@ static struct iommu_ops amd_iommu_ops = { | |||
1932 | .map = amd_iommu_map_range, | 1942 | .map = amd_iommu_map_range, |
1933 | .unmap = amd_iommu_unmap_range, | 1943 | .unmap = amd_iommu_unmap_range, |
1934 | .iova_to_phys = amd_iommu_iova_to_phys, | 1944 | .iova_to_phys = amd_iommu_iova_to_phys, |
1945 | .domain_has_cap = amd_iommu_domain_has_cap, | ||
1935 | }; | 1946 | }; |
1936 | 1947 | ||
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 85eb8e100818..f2870920f246 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -431,6 +431,12 @@ static void __cpuinit setup_APIC_timer(void) | |||
431 | { | 431 | { |
432 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); | 432 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); |
433 | 433 | ||
434 | if (cpu_has(¤t_cpu_data, X86_FEATURE_ARAT)) { | ||
435 | lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP; | ||
436 | /* Make LAPIC timer preferrable over percpu HPET */ | ||
437 | lapic_clockevent.rating = 150; | ||
438 | } | ||
439 | |||
434 | memcpy(levt, &lapic_clockevent, sizeof(*levt)); | 440 | memcpy(levt, &lapic_clockevent, sizeof(*levt)); |
435 | levt->cpumask = cpumask_of(smp_processor_id()); | 441 | levt->cpumask = cpumask_of(smp_processor_id()); |
436 | 442 | ||
@@ -1304,6 +1310,7 @@ void __init enable_IR_x2apic(void) | |||
1304 | #ifdef CONFIG_INTR_REMAP | 1310 | #ifdef CONFIG_INTR_REMAP |
1305 | int ret; | 1311 | int ret; |
1306 | unsigned long flags; | 1312 | unsigned long flags; |
1313 | struct IO_APIC_route_entry **ioapic_entries = NULL; | ||
1307 | 1314 | ||
1308 | if (!cpu_has_x2apic) | 1315 | if (!cpu_has_x2apic) |
1309 | return; | 1316 | return; |
@@ -1334,17 +1341,23 @@ void __init enable_IR_x2apic(void) | |||
1334 | return; | 1341 | return; |
1335 | } | 1342 | } |
1336 | 1343 | ||
1337 | ret = save_IO_APIC_setup(); | 1344 | ioapic_entries = alloc_ioapic_entries(); |
1345 | if (!ioapic_entries) { | ||
1346 | pr_info("Allocate ioapic_entries failed: %d\n", ret); | ||
1347 | goto end; | ||
1348 | } | ||
1349 | |||
1350 | ret = save_IO_APIC_setup(ioapic_entries); | ||
1338 | if (ret) { | 1351 | if (ret) { |
1339 | pr_info("Saving IO-APIC state failed: %d\n", ret); | 1352 | pr_info("Saving IO-APIC state failed: %d\n", ret); |
1340 | goto end; | 1353 | goto end; |
1341 | } | 1354 | } |
1342 | 1355 | ||
1343 | local_irq_save(flags); | 1356 | local_irq_save(flags); |
1344 | mask_IO_APIC_setup(); | 1357 | mask_IO_APIC_setup(ioapic_entries); |
1345 | mask_8259A(); | 1358 | mask_8259A(); |
1346 | 1359 | ||
1347 | ret = enable_intr_remapping(1); | 1360 | ret = enable_intr_remapping(EIM_32BIT_APIC_ID); |
1348 | 1361 | ||
1349 | if (ret && x2apic_preenabled) { | 1362 | if (ret && x2apic_preenabled) { |
1350 | local_irq_restore(flags); | 1363 | local_irq_restore(flags); |
@@ -1364,9 +1377,9 @@ end_restore: | |||
1364 | /* | 1377 | /* |
1365 | * IR enabling failed | 1378 | * IR enabling failed |
1366 | */ | 1379 | */ |
1367 | restore_IO_APIC_setup(); | 1380 | restore_IO_APIC_setup(ioapic_entries); |
1368 | else | 1381 | else |
1369 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); | 1382 | reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries); |
1370 | 1383 | ||
1371 | unmask_8259A(); | 1384 | unmask_8259A(); |
1372 | local_irq_restore(flags); | 1385 | local_irq_restore(flags); |
@@ -1379,6 +1392,8 @@ end: | |||
1379 | pr_info("Enabled Interrupt-remapping\n"); | 1392 | pr_info("Enabled Interrupt-remapping\n"); |
1380 | } else | 1393 | } else |
1381 | pr_err("Failed to enable Interrupt-remapping and x2apic\n"); | 1394 | pr_err("Failed to enable Interrupt-remapping and x2apic\n"); |
1395 | if (ioapic_entries) | ||
1396 | free_ioapic_entries(ioapic_entries); | ||
1382 | #else | 1397 | #else |
1383 | if (!cpu_has_x2apic) | 1398 | if (!cpu_has_x2apic) |
1384 | return; | 1399 | return; |
@@ -1954,6 +1969,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1954 | 1969 | ||
1955 | local_irq_save(flags); | 1970 | local_irq_save(flags); |
1956 | disable_local_APIC(); | 1971 | disable_local_APIC(); |
1972 | #ifdef CONFIG_INTR_REMAP | ||
1973 | if (intr_remapping_enabled) | ||
1974 | disable_intr_remapping(); | ||
1975 | #endif | ||
1957 | local_irq_restore(flags); | 1976 | local_irq_restore(flags); |
1958 | return 0; | 1977 | return 0; |
1959 | } | 1978 | } |
@@ -1964,15 +1983,41 @@ static int lapic_resume(struct sys_device *dev) | |||
1964 | unsigned long flags; | 1983 | unsigned long flags; |
1965 | int maxlvt; | 1984 | int maxlvt; |
1966 | 1985 | ||
1986 | #ifdef CONFIG_INTR_REMAP | ||
1987 | int ret; | ||
1988 | struct IO_APIC_route_entry **ioapic_entries = NULL; | ||
1989 | |||
1967 | if (!apic_pm_state.active) | 1990 | if (!apic_pm_state.active) |
1968 | return 0; | 1991 | return 0; |
1969 | 1992 | ||
1970 | maxlvt = lapic_get_maxlvt(); | ||
1971 | |||
1972 | local_irq_save(flags); | 1993 | local_irq_save(flags); |
1994 | if (x2apic) { | ||
1995 | ioapic_entries = alloc_ioapic_entries(); | ||
1996 | if (!ioapic_entries) { | ||
1997 | WARN(1, "Alloc ioapic_entries in lapic resume failed."); | ||
1998 | return -ENOMEM; | ||
1999 | } | ||
2000 | |||
2001 | ret = save_IO_APIC_setup(ioapic_entries); | ||
2002 | if (ret) { | ||
2003 | WARN(1, "Saving IO-APIC state failed: %d\n", ret); | ||
2004 | free_ioapic_entries(ioapic_entries); | ||
2005 | return ret; | ||
2006 | } | ||
2007 | |||
2008 | mask_IO_APIC_setup(ioapic_entries); | ||
2009 | mask_8259A(); | ||
2010 | enable_x2apic(); | ||
2011 | } | ||
2012 | #else | ||
2013 | if (!apic_pm_state.active) | ||
2014 | return 0; | ||
1973 | 2015 | ||
2016 | local_irq_save(flags); | ||
1974 | if (x2apic) | 2017 | if (x2apic) |
1975 | enable_x2apic(); | 2018 | enable_x2apic(); |
2019 | #endif | ||
2020 | |||
1976 | else { | 2021 | else { |
1977 | /* | 2022 | /* |
1978 | * Make sure the APICBASE points to the right address | 2023 | * Make sure the APICBASE points to the right address |
@@ -1986,6 +2031,7 @@ static int lapic_resume(struct sys_device *dev) | |||
1986 | wrmsr(MSR_IA32_APICBASE, l, h); | 2031 | wrmsr(MSR_IA32_APICBASE, l, h); |
1987 | } | 2032 | } |
1988 | 2033 | ||
2034 | maxlvt = lapic_get_maxlvt(); | ||
1989 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); | 2035 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); |
1990 | apic_write(APIC_ID, apic_pm_state.apic_id); | 2036 | apic_write(APIC_ID, apic_pm_state.apic_id); |
1991 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); | 2037 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); |
@@ -2009,8 +2055,20 @@ static int lapic_resume(struct sys_device *dev) | |||
2009 | apic_write(APIC_ESR, 0); | 2055 | apic_write(APIC_ESR, 0); |
2010 | apic_read(APIC_ESR); | 2056 | apic_read(APIC_ESR); |
2011 | 2057 | ||
2058 | #ifdef CONFIG_INTR_REMAP | ||
2059 | if (intr_remapping_enabled) | ||
2060 | reenable_intr_remapping(EIM_32BIT_APIC_ID); | ||
2061 | |||
2062 | if (x2apic) { | ||
2063 | unmask_8259A(); | ||
2064 | restore_IO_APIC_setup(ioapic_entries); | ||
2065 | free_ioapic_entries(ioapic_entries); | ||
2066 | } | ||
2067 | #endif | ||
2068 | |||
2012 | local_irq_restore(flags); | 2069 | local_irq_restore(flags); |
2013 | 2070 | ||
2071 | |||
2014 | return 0; | 2072 | return 0; |
2015 | } | 2073 | } |
2016 | 2074 | ||
@@ -2048,7 +2106,9 @@ static int __init init_lapic_sysfs(void) | |||
2048 | error = sysdev_register(&device_lapic); | 2106 | error = sysdev_register(&device_lapic); |
2049 | return error; | 2107 | return error; |
2050 | } | 2108 | } |
2051 | device_initcall(init_lapic_sysfs); | 2109 | |
2110 | /* local apic needs to resume before other devices access its registers. */ | ||
2111 | core_initcall(init_lapic_sysfs); | ||
2052 | 2112 | ||
2053 | #else /* CONFIG_PM */ | 2113 | #else /* CONFIG_PM */ |
2054 | 2114 | ||
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index f933822dba18..306e5e88fb6f 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -159,20 +159,6 @@ static int flat_apic_id_registered(void) | |||
159 | return physid_isset(read_xapic_id(), phys_cpu_present_map); | 159 | return physid_isset(read_xapic_id(), phys_cpu_present_map); |
160 | } | 160 | } |
161 | 161 | ||
162 | static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
163 | { | ||
164 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | ||
165 | } | ||
166 | |||
167 | static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
168 | const struct cpumask *andmask) | ||
169 | { | ||
170 | unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | ||
171 | unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS; | ||
172 | |||
173 | return mask1 & mask2; | ||
174 | } | ||
175 | |||
176 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) | 162 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) |
177 | { | 163 | { |
178 | return hard_smp_processor_id() >> index_msb; | 164 | return hard_smp_processor_id() >> index_msb; |
@@ -213,8 +199,8 @@ struct apic apic_flat = { | |||
213 | .set_apic_id = set_apic_id, | 199 | .set_apic_id = set_apic_id, |
214 | .apic_id_mask = 0xFFu << 24, | 200 | .apic_id_mask = 0xFFu << 24, |
215 | 201 | ||
216 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, | 202 | .cpu_mask_to_apicid = default_cpu_mask_to_apicid, |
217 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, | 203 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
218 | 204 | ||
219 | .send_IPI_mask = flat_send_IPI_mask, | 205 | .send_IPI_mask = flat_send_IPI_mask, |
220 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, | 206 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, |
@@ -226,7 +212,7 @@ struct apic apic_flat = { | |||
226 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 212 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
227 | .wait_for_init_deassert = NULL, | 213 | .wait_for_init_deassert = NULL, |
228 | .smp_callin_clear_local_apic = NULL, | 214 | .smp_callin_clear_local_apic = NULL, |
229 | .inquire_remote_apic = NULL, | 215 | .inquire_remote_apic = default_inquire_remote_apic, |
230 | 216 | ||
231 | .read = native_apic_mem_read, | 217 | .read = native_apic_mem_read, |
232 | .write = native_apic_mem_write, | 218 | .write = native_apic_mem_write, |
@@ -376,7 +362,7 @@ struct apic apic_physflat = { | |||
376 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 362 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
377 | .wait_for_init_deassert = NULL, | 363 | .wait_for_init_deassert = NULL, |
378 | .smp_callin_clear_local_apic = NULL, | 364 | .smp_callin_clear_local_apic = NULL, |
379 | .inquire_remote_apic = NULL, | 365 | .inquire_remote_apic = default_inquire_remote_apic, |
380 | 366 | ||
381 | .read = native_apic_mem_read, | 367 | .read = native_apic_mem_read, |
382 | .write = native_apic_mem_write, | 368 | .write = native_apic_mem_write, |
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index d806ecaa948f..676cdac385c0 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -26,12 +26,12 @@ static int bigsmp_apic_id_registered(void) | |||
26 | return 1; | 26 | return 1; |
27 | } | 27 | } |
28 | 28 | ||
29 | static const cpumask_t *bigsmp_target_cpus(void) | 29 | static const struct cpumask *bigsmp_target_cpus(void) |
30 | { | 30 | { |
31 | #ifdef CONFIG_SMP | 31 | #ifdef CONFIG_SMP |
32 | return &cpu_online_map; | 32 | return cpu_online_mask; |
33 | #else | 33 | #else |
34 | return &cpumask_of_cpu(0); | 34 | return cpumask_of(0); |
35 | #endif | 35 | #endif |
36 | } | 36 | } |
37 | 37 | ||
@@ -118,9 +118,9 @@ static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | /* As we are using single CPU as destination, pick only one CPU here */ | 120 | /* As we are using single CPU as destination, pick only one CPU here */ |
121 | static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask) | 121 | static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask) |
122 | { | 122 | { |
123 | return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); | 123 | return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask)); |
124 | } | 124 | } |
125 | 125 | ||
126 | static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 126 | static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
@@ -188,10 +188,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = { | |||
188 | { } /* NULL entry stops DMI scanning */ | 188 | { } /* NULL entry stops DMI scanning */ |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask) | 191 | static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask) |
192 | { | 192 | { |
193 | cpus_clear(*retmask); | 193 | cpumask_clear(retmask); |
194 | cpu_set(cpu, *retmask); | 194 | cpumask_set_cpu(cpu, retmask); |
195 | } | 195 | } |
196 | 196 | ||
197 | static int probe_bigsmp(void) | 197 | static int probe_bigsmp(void) |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 19588f2770ee..1c11b819f245 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -410,7 +410,7 @@ static void es7000_enable_apic_mode(void) | |||
410 | WARN(1, "Command failed, status = %x\n", mip_status); | 410 | WARN(1, "Command failed, status = %x\n", mip_status); |
411 | } | 411 | } |
412 | 412 | ||
413 | static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | 413 | static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask) |
414 | { | 414 | { |
415 | /* Careful. Some cpus do not strictly honor the set of cpus | 415 | /* Careful. Some cpus do not strictly honor the set of cpus |
416 | * specified in the interrupt destination when using lowest | 416 | * specified in the interrupt destination when using lowest |
@@ -420,7 +420,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
420 | * deliver interrupts to the wrong hyperthread when only one | 420 | * deliver interrupts to the wrong hyperthread when only one |
421 | * hyperthread was specified in the interrupt desitination. | 421 | * hyperthread was specified in the interrupt desitination. |
422 | */ | 422 | */ |
423 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 423 | cpumask_clear(retmask); |
424 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
424 | } | 425 | } |
425 | 426 | ||
426 | 427 | ||
@@ -455,14 +456,14 @@ static int es7000_apic_id_registered(void) | |||
455 | return 1; | 456 | return 1; |
456 | } | 457 | } |
457 | 458 | ||
458 | static const cpumask_t *target_cpus_cluster(void) | 459 | static const struct cpumask *target_cpus_cluster(void) |
459 | { | 460 | { |
460 | return &CPU_MASK_ALL; | 461 | return cpu_all_mask; |
461 | } | 462 | } |
462 | 463 | ||
463 | static const cpumask_t *es7000_target_cpus(void) | 464 | static const struct cpumask *es7000_target_cpus(void) |
464 | { | 465 | { |
465 | return &cpumask_of_cpu(smp_processor_id()); | 466 | return cpumask_of(smp_processor_id()); |
466 | } | 467 | } |
467 | 468 | ||
468 | static unsigned long | 469 | static unsigned long |
@@ -517,7 +518,7 @@ static void es7000_setup_apic_routing(void) | |||
517 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | 518 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", |
518 | (apic_version[apic] == 0x14) ? | 519 | (apic_version[apic] == 0x14) ? |
519 | "Physical Cluster" : "Logical Cluster", | 520 | "Physical Cluster" : "Logical Cluster", |
520 | nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); | 521 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); |
521 | } | 522 | } |
522 | 523 | ||
523 | static int es7000_apicid_to_node(int logical_apicid) | 524 | static int es7000_apicid_to_node(int logical_apicid) |
@@ -572,7 +573,7 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | |||
572 | return 1; | 573 | return 1; |
573 | } | 574 | } |
574 | 575 | ||
575 | static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) | 576 | static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) |
576 | { | 577 | { |
577 | unsigned int round = 0; | 578 | unsigned int round = 0; |
578 | int cpu, uninitialized_var(apicid); | 579 | int cpu, uninitialized_var(apicid); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 86827d85488a..a2789e42e162 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -592,10 +592,12 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | |||
592 | if (assign_irq_vector(irq, cfg, mask)) | 592 | if (assign_irq_vector(irq, cfg, mask)) |
593 | return BAD_APICID; | 593 | return BAD_APICID; |
594 | 594 | ||
595 | cpumask_and(desc->affinity, cfg->domain, mask); | 595 | /* check that before desc->addinity get updated */ |
596 | set_extra_move_desc(desc, mask); | 596 | set_extra_move_desc(desc, mask); |
597 | 597 | ||
598 | return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask); | 598 | cpumask_copy(desc->affinity, mask); |
599 | |||
600 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
599 | } | 601 | } |
600 | 602 | ||
601 | static void | 603 | static void |
@@ -849,63 +851,74 @@ __setup("pirq=", ioapic_pirq_setup); | |||
849 | #endif /* CONFIG_X86_32 */ | 851 | #endif /* CONFIG_X86_32 */ |
850 | 852 | ||
851 | #ifdef CONFIG_INTR_REMAP | 853 | #ifdef CONFIG_INTR_REMAP |
852 | /* I/O APIC RTE contents at the OS boot up */ | 854 | struct IO_APIC_route_entry **alloc_ioapic_entries(void) |
853 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; | 855 | { |
856 | int apic; | ||
857 | struct IO_APIC_route_entry **ioapic_entries; | ||
858 | |||
859 | ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics, | ||
860 | GFP_ATOMIC); | ||
861 | if (!ioapic_entries) | ||
862 | return 0; | ||
863 | |||
864 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
865 | ioapic_entries[apic] = | ||
866 | kzalloc(sizeof(struct IO_APIC_route_entry) * | ||
867 | nr_ioapic_registers[apic], GFP_ATOMIC); | ||
868 | if (!ioapic_entries[apic]) | ||
869 | goto nomem; | ||
870 | } | ||
871 | |||
872 | return ioapic_entries; | ||
873 | |||
874 | nomem: | ||
875 | while (--apic >= 0) | ||
876 | kfree(ioapic_entries[apic]); | ||
877 | kfree(ioapic_entries); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
854 | 881 | ||
855 | /* | 882 | /* |
856 | * Saves all the IO-APIC RTE's | 883 | * Saves all the IO-APIC RTE's |
857 | */ | 884 | */ |
858 | int save_IO_APIC_setup(void) | 885 | int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) |
859 | { | 886 | { |
860 | union IO_APIC_reg_01 reg_01; | ||
861 | unsigned long flags; | ||
862 | int apic, pin; | 887 | int apic, pin; |
863 | 888 | ||
864 | /* | 889 | if (!ioapic_entries) |
865 | * The number of IO-APIC IRQ registers (== #pins): | 890 | return -ENOMEM; |
866 | */ | ||
867 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
868 | spin_lock_irqsave(&ioapic_lock, flags); | ||
869 | reg_01.raw = io_apic_read(apic, 1); | ||
870 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
871 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; | ||
872 | } | ||
873 | 891 | ||
874 | for (apic = 0; apic < nr_ioapics; apic++) { | 892 | for (apic = 0; apic < nr_ioapics; apic++) { |
875 | early_ioapic_entries[apic] = | 893 | if (!ioapic_entries[apic]) |
876 | kzalloc(sizeof(struct IO_APIC_route_entry) * | 894 | return -ENOMEM; |
877 | nr_ioapic_registers[apic], GFP_KERNEL); | ||
878 | if (!early_ioapic_entries[apic]) | ||
879 | goto nomem; | ||
880 | } | ||
881 | 895 | ||
882 | for (apic = 0; apic < nr_ioapics; apic++) | ||
883 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 896 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) |
884 | early_ioapic_entries[apic][pin] = | 897 | ioapic_entries[apic][pin] = |
885 | ioapic_read_entry(apic, pin); | 898 | ioapic_read_entry(apic, pin); |
899 | } | ||
886 | 900 | ||
887 | return 0; | 901 | return 0; |
888 | |||
889 | nomem: | ||
890 | while (apic >= 0) | ||
891 | kfree(early_ioapic_entries[apic--]); | ||
892 | memset(early_ioapic_entries, 0, | ||
893 | ARRAY_SIZE(early_ioapic_entries)); | ||
894 | |||
895 | return -ENOMEM; | ||
896 | } | 902 | } |
897 | 903 | ||
898 | void mask_IO_APIC_setup(void) | 904 | /* |
905 | * Mask all IO APIC entries. | ||
906 | */ | ||
907 | void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | ||
899 | { | 908 | { |
900 | int apic, pin; | 909 | int apic, pin; |
901 | 910 | ||
911 | if (!ioapic_entries) | ||
912 | return; | ||
913 | |||
902 | for (apic = 0; apic < nr_ioapics; apic++) { | 914 | for (apic = 0; apic < nr_ioapics; apic++) { |
903 | if (!early_ioapic_entries[apic]) | 915 | if (!ioapic_entries[apic]) |
904 | break; | 916 | break; |
917 | |||
905 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 918 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { |
906 | struct IO_APIC_route_entry entry; | 919 | struct IO_APIC_route_entry entry; |
907 | 920 | ||
908 | entry = early_ioapic_entries[apic][pin]; | 921 | entry = ioapic_entries[apic][pin]; |
909 | if (!entry.mask) { | 922 | if (!entry.mask) { |
910 | entry.mask = 1; | 923 | entry.mask = 1; |
911 | ioapic_write_entry(apic, pin, entry); | 924 | ioapic_write_entry(apic, pin, entry); |
@@ -914,22 +927,30 @@ void mask_IO_APIC_setup(void) | |||
914 | } | 927 | } |
915 | } | 928 | } |
916 | 929 | ||
917 | void restore_IO_APIC_setup(void) | 930 | /* |
931 | * Restore IO APIC entries which was saved in ioapic_entries. | ||
932 | */ | ||
933 | int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | ||
918 | { | 934 | { |
919 | int apic, pin; | 935 | int apic, pin; |
920 | 936 | ||
937 | if (!ioapic_entries) | ||
938 | return -ENOMEM; | ||
939 | |||
921 | for (apic = 0; apic < nr_ioapics; apic++) { | 940 | for (apic = 0; apic < nr_ioapics; apic++) { |
922 | if (!early_ioapic_entries[apic]) | 941 | if (!ioapic_entries[apic]) |
923 | break; | 942 | return -ENOMEM; |
943 | |||
924 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 944 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) |
925 | ioapic_write_entry(apic, pin, | 945 | ioapic_write_entry(apic, pin, |
926 | early_ioapic_entries[apic][pin]); | 946 | ioapic_entries[apic][pin]); |
927 | kfree(early_ioapic_entries[apic]); | ||
928 | early_ioapic_entries[apic] = NULL; | ||
929 | } | 947 | } |
948 | return 0; | ||
930 | } | 949 | } |
931 | 950 | ||
932 | void reinit_intr_remapped_IO_APIC(int intr_remapping) | 951 | void reinit_intr_remapped_IO_APIC(int intr_remapping, |
952 | struct IO_APIC_route_entry **ioapic_entries) | ||
953 | |||
933 | { | 954 | { |
934 | /* | 955 | /* |
935 | * for now plain restore of previous settings. | 956 | * for now plain restore of previous settings. |
@@ -938,7 +959,17 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping) | |||
938 | * table entries. for now, do a plain restore, and wait for | 959 | * table entries. for now, do a plain restore, and wait for |
939 | * the setup_IO_APIC_irqs() to do proper initialization. | 960 | * the setup_IO_APIC_irqs() to do proper initialization. |
940 | */ | 961 | */ |
941 | restore_IO_APIC_setup(); | 962 | restore_IO_APIC_setup(ioapic_entries); |
963 | } | ||
964 | |||
965 | void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) | ||
966 | { | ||
967 | int apic; | ||
968 | |||
969 | for (apic = 0; apic < nr_ioapics; apic++) | ||
970 | kfree(ioapic_entries[apic]); | ||
971 | |||
972 | kfree(ioapic_entries); | ||
942 | } | 973 | } |
943 | #endif | 974 | #endif |
944 | 975 | ||
@@ -1428,7 +1459,6 @@ void __setup_vector_irq(int cpu) | |||
1428 | 1459 | ||
1429 | static struct irq_chip ioapic_chip; | 1460 | static struct irq_chip ioapic_chip; |
1430 | static struct irq_chip ir_ioapic_chip; | 1461 | static struct irq_chip ir_ioapic_chip; |
1431 | static struct irq_chip msi_ir_chip; | ||
1432 | 1462 | ||
1433 | #define IOAPIC_AUTO -1 | 1463 | #define IOAPIC_AUTO -1 |
1434 | #define IOAPIC_EDGE 0 | 1464 | #define IOAPIC_EDGE 0 |
@@ -2494,7 +2524,6 @@ static void irq_complete_move(struct irq_desc **descp) | |||
2494 | static inline void irq_complete_move(struct irq_desc **descp) {} | 2524 | static inline void irq_complete_move(struct irq_desc **descp) {} |
2495 | #endif | 2525 | #endif |
2496 | 2526 | ||
2497 | #ifdef CONFIG_INTR_REMAP | ||
2498 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | 2527 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) |
2499 | { | 2528 | { |
2500 | int apic, pin; | 2529 | int apic, pin; |
@@ -2528,6 +2557,7 @@ eoi_ioapic_irq(struct irq_desc *desc) | |||
2528 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2557 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2529 | } | 2558 | } |
2530 | 2559 | ||
2560 | #ifdef CONFIG_X86_X2APIC | ||
2531 | static void ack_x2apic_level(unsigned int irq) | 2561 | static void ack_x2apic_level(unsigned int irq) |
2532 | { | 2562 | { |
2533 | struct irq_desc *desc = irq_to_desc(irq); | 2563 | struct irq_desc *desc = irq_to_desc(irq); |
@@ -2539,7 +2569,6 @@ static void ack_x2apic_edge(unsigned int irq) | |||
2539 | { | 2569 | { |
2540 | ack_x2APIC_irq(); | 2570 | ack_x2APIC_irq(); |
2541 | } | 2571 | } |
2542 | |||
2543 | #endif | 2572 | #endif |
2544 | 2573 | ||
2545 | static void ack_apic_edge(unsigned int irq) | 2574 | static void ack_apic_edge(unsigned int irq) |
@@ -2605,6 +2634,9 @@ static void ack_apic_level(unsigned int irq) | |||
2605 | */ | 2634 | */ |
2606 | ack_APIC_irq(); | 2635 | ack_APIC_irq(); |
2607 | 2636 | ||
2637 | if (irq_remapped(irq)) | ||
2638 | eoi_ioapic_irq(desc); | ||
2639 | |||
2608 | /* Now we can move and renable the irq */ | 2640 | /* Now we can move and renable the irq */ |
2609 | if (unlikely(do_unmask_irq)) { | 2641 | if (unlikely(do_unmask_irq)) { |
2610 | /* Only migrate the irq if the ack has been received. | 2642 | /* Only migrate the irq if the ack has been received. |
@@ -2650,6 +2682,26 @@ static void ack_apic_level(unsigned int irq) | |||
2650 | #endif | 2682 | #endif |
2651 | } | 2683 | } |
2652 | 2684 | ||
2685 | #ifdef CONFIG_INTR_REMAP | ||
2686 | static void ir_ack_apic_edge(unsigned int irq) | ||
2687 | { | ||
2688 | #ifdef CONFIG_X86_X2APIC | ||
2689 | if (x2apic_enabled()) | ||
2690 | return ack_x2apic_edge(irq); | ||
2691 | #endif | ||
2692 | return ack_apic_edge(irq); | ||
2693 | } | ||
2694 | |||
2695 | static void ir_ack_apic_level(unsigned int irq) | ||
2696 | { | ||
2697 | #ifdef CONFIG_X86_X2APIC | ||
2698 | if (x2apic_enabled()) | ||
2699 | return ack_x2apic_level(irq); | ||
2700 | #endif | ||
2701 | return ack_apic_level(irq); | ||
2702 | } | ||
2703 | #endif /* CONFIG_INTR_REMAP */ | ||
2704 | |||
2653 | static struct irq_chip ioapic_chip __read_mostly = { | 2705 | static struct irq_chip ioapic_chip __read_mostly = { |
2654 | .name = "IO-APIC", | 2706 | .name = "IO-APIC", |
2655 | .startup = startup_ioapic_irq, | 2707 | .startup = startup_ioapic_irq, |
@@ -2663,20 +2715,20 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
2663 | .retrigger = ioapic_retrigger_irq, | 2715 | .retrigger = ioapic_retrigger_irq, |
2664 | }; | 2716 | }; |
2665 | 2717 | ||
2666 | #ifdef CONFIG_INTR_REMAP | ||
2667 | static struct irq_chip ir_ioapic_chip __read_mostly = { | 2718 | static struct irq_chip ir_ioapic_chip __read_mostly = { |
2668 | .name = "IR-IO-APIC", | 2719 | .name = "IR-IO-APIC", |
2669 | .startup = startup_ioapic_irq, | 2720 | .startup = startup_ioapic_irq, |
2670 | .mask = mask_IO_APIC_irq, | 2721 | .mask = mask_IO_APIC_irq, |
2671 | .unmask = unmask_IO_APIC_irq, | 2722 | .unmask = unmask_IO_APIC_irq, |
2672 | .ack = ack_x2apic_edge, | 2723 | #ifdef CONFIG_INTR_REMAP |
2673 | .eoi = ack_x2apic_level, | 2724 | .ack = ir_ack_apic_edge, |
2725 | .eoi = ir_ack_apic_level, | ||
2674 | #ifdef CONFIG_SMP | 2726 | #ifdef CONFIG_SMP |
2675 | .set_affinity = set_ir_ioapic_affinity_irq, | 2727 | .set_affinity = set_ir_ioapic_affinity_irq, |
2676 | #endif | 2728 | #endif |
2729 | #endif | ||
2677 | .retrigger = ioapic_retrigger_irq, | 2730 | .retrigger = ioapic_retrigger_irq, |
2678 | }; | 2731 | }; |
2679 | #endif | ||
2680 | 2732 | ||
2681 | static inline void init_IO_APIC_traps(void) | 2733 | static inline void init_IO_APIC_traps(void) |
2682 | { | 2734 | { |
@@ -3391,18 +3443,18 @@ static struct irq_chip msi_chip = { | |||
3391 | .retrigger = ioapic_retrigger_irq, | 3443 | .retrigger = ioapic_retrigger_irq, |
3392 | }; | 3444 | }; |
3393 | 3445 | ||
3394 | #ifdef CONFIG_INTR_REMAP | ||
3395 | static struct irq_chip msi_ir_chip = { | 3446 | static struct irq_chip msi_ir_chip = { |
3396 | .name = "IR-PCI-MSI", | 3447 | .name = "IR-PCI-MSI", |
3397 | .unmask = unmask_msi_irq, | 3448 | .unmask = unmask_msi_irq, |
3398 | .mask = mask_msi_irq, | 3449 | .mask = mask_msi_irq, |
3399 | .ack = ack_x2apic_edge, | 3450 | #ifdef CONFIG_INTR_REMAP |
3451 | .ack = ir_ack_apic_edge, | ||
3400 | #ifdef CONFIG_SMP | 3452 | #ifdef CONFIG_SMP |
3401 | .set_affinity = ir_set_msi_irq_affinity, | 3453 | .set_affinity = ir_set_msi_irq_affinity, |
3402 | #endif | 3454 | #endif |
3455 | #endif | ||
3403 | .retrigger = ioapic_retrigger_irq, | 3456 | .retrigger = ioapic_retrigger_irq, |
3404 | }; | 3457 | }; |
3405 | #endif | ||
3406 | 3458 | ||
3407 | /* | 3459 | /* |
3408 | * Map the PCI dev to the corresponding remapping hardware unit | 3460 | * Map the PCI dev to the corresponding remapping hardware unit |
@@ -3467,6 +3519,10 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3467 | struct intel_iommu *iommu = NULL; | 3519 | struct intel_iommu *iommu = NULL; |
3468 | int index = 0; | 3520 | int index = 0; |
3469 | 3521 | ||
3522 | /* x86 doesn't support multiple MSI yet */ | ||
3523 | if (type == PCI_CAP_ID_MSI && nvec > 1) | ||
3524 | return 1; | ||
3525 | |||
3470 | irq_want = nr_irqs_gsi; | 3526 | irq_want = nr_irqs_gsi; |
3471 | sub_handle = 0; | 3527 | sub_handle = 0; |
3472 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 3528 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index bdfad80c3cf1..d6bd62407152 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
@@ -39,7 +39,7 @@ | |||
39 | int unknown_nmi_panic; | 39 | int unknown_nmi_panic; |
40 | int nmi_watchdog_enabled; | 40 | int nmi_watchdog_enabled; |
41 | 41 | ||
42 | static cpumask_t backtrace_mask = CPU_MASK_NONE; | 42 | static cpumask_var_t backtrace_mask; |
43 | 43 | ||
44 | /* nmi_active: | 44 | /* nmi_active: |
45 | * >0: the lapic NMI watchdog is active, but can be disabled | 45 | * >0: the lapic NMI watchdog is active, but can be disabled |
@@ -138,6 +138,7 @@ int __init check_nmi_watchdog(void) | |||
138 | if (!prev_nmi_count) | 138 | if (!prev_nmi_count) |
139 | goto error; | 139 | goto error; |
140 | 140 | ||
141 | alloc_cpumask_var(&backtrace_mask, GFP_KERNEL); | ||
141 | printk(KERN_INFO "Testing NMI watchdog ... "); | 142 | printk(KERN_INFO "Testing NMI watchdog ... "); |
142 | 143 | ||
143 | #ifdef CONFIG_SMP | 144 | #ifdef CONFIG_SMP |
@@ -413,14 +414,14 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | |||
413 | touched = 1; | 414 | touched = 1; |
414 | } | 415 | } |
415 | 416 | ||
416 | if (cpu_isset(cpu, backtrace_mask)) { | 417 | if (cpumask_test_cpu(cpu, backtrace_mask)) { |
417 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ | 418 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ |
418 | 419 | ||
419 | spin_lock(&lock); | 420 | spin_lock(&lock); |
420 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | 421 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); |
421 | dump_stack(); | 422 | dump_stack(); |
422 | spin_unlock(&lock); | 423 | spin_unlock(&lock); |
423 | cpu_clear(cpu, backtrace_mask); | 424 | cpumask_clear_cpu(cpu, backtrace_mask); |
424 | } | 425 | } |
425 | 426 | ||
426 | /* Could check oops_in_progress here too, but it's safer not to */ | 427 | /* Could check oops_in_progress here too, but it's safer not to */ |
@@ -554,10 +555,10 @@ void __trigger_all_cpu_backtrace(void) | |||
554 | { | 555 | { |
555 | int i; | 556 | int i; |
556 | 557 | ||
557 | backtrace_mask = cpu_online_map; | 558 | cpumask_copy(backtrace_mask, cpu_online_mask); |
558 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | 559 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ |
559 | for (i = 0; i < 10 * 1000; i++) { | 560 | for (i = 0; i < 10 * 1000; i++) { |
560 | if (cpus_empty(backtrace_mask)) | 561 | if (cpumask_empty(backtrace_mask)) |
561 | break; | 562 | break; |
562 | mdelay(1); | 563 | mdelay(1); |
563 | } | 564 | } |
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index ba2fc6465534..533e59c6fc82 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -334,9 +334,9 @@ static inline void numaq_smp_callin_clear_local_apic(void) | |||
334 | clear_local_APIC(); | 334 | clear_local_APIC(); |
335 | } | 335 | } |
336 | 336 | ||
337 | static inline const cpumask_t *numaq_target_cpus(void) | 337 | static inline const struct cpumask *numaq_target_cpus(void) |
338 | { | 338 | { |
339 | return &CPU_MASK_ALL; | 339 | return cpu_all_mask; |
340 | } | 340 | } |
341 | 341 | ||
342 | static inline unsigned long | 342 | static inline unsigned long |
@@ -427,7 +427,7 @@ static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid) | |||
427 | * We use physical apicids here, not logical, so just return the default | 427 | * We use physical apicids here, not logical, so just return the default |
428 | * physical broadcast to stop people from breaking us | 428 | * physical broadcast to stop people from breaking us |
429 | */ | 429 | */ |
430 | static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask) | 430 | static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) |
431 | { | 431 | { |
432 | return 0x0F; | 432 | return 0x0F; |
433 | } | 433 | } |
@@ -462,7 +462,7 @@ static int probe_numaq(void) | |||
462 | return found_numaq; | 462 | return found_numaq; |
463 | } | 463 | } |
464 | 464 | ||
465 | static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) | 465 | static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask) |
466 | { | 466 | { |
467 | /* Careful. Some cpus do not strictly honor the set of cpus | 467 | /* Careful. Some cpus do not strictly honor the set of cpus |
468 | * specified in the interrupt destination when using lowest | 468 | * specified in the interrupt destination when using lowest |
@@ -472,7 +472,8 @@ static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
472 | * deliver interrupts to the wrong hyperthread when only one | 472 | * deliver interrupts to the wrong hyperthread when only one |
473 | * hyperthread was specified in the interrupt desitination. | 473 | * hyperthread was specified in the interrupt desitination. |
474 | */ | 474 | */ |
475 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 475 | cpumask_clear(retmask); |
476 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
476 | } | 477 | } |
477 | 478 | ||
478 | static void numaq_setup_portio_remap(void) | 479 | static void numaq_setup_portio_remap(void) |
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 141c99a1c264..01eda2ac65e4 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -83,7 +83,8 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
83 | * deliver interrupts to the wrong hyperthread when only one | 83 | * deliver interrupts to the wrong hyperthread when only one |
84 | * hyperthread was specified in the interrupt desitination. | 84 | * hyperthread was specified in the interrupt desitination. |
85 | */ | 85 | */ |
86 | *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } }; | 86 | cpumask_clear(retmask); |
87 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
87 | } | 88 | } |
88 | 89 | ||
89 | /* should be called last. */ | 90 | /* should be called last. */ |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index aac52fa873ff..9cfe1f415d81 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -53,23 +53,19 @@ static unsigned summit_get_apic_id(unsigned long x) | |||
53 | return (x >> 24) & 0xFF; | 53 | return (x >> 24) & 0xFF; |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) | 56 | static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector) |
57 | { | 57 | { |
58 | default_send_IPI_mask_sequence_logical(mask, vector); | 58 | default_send_IPI_mask_sequence_logical(mask, vector); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void summit_send_IPI_allbutself(int vector) | 61 | static void summit_send_IPI_allbutself(int vector) |
62 | { | 62 | { |
63 | cpumask_t mask = cpu_online_map; | 63 | default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector); |
64 | cpu_clear(smp_processor_id(), mask); | ||
65 | |||
66 | if (!cpus_empty(mask)) | ||
67 | summit_send_IPI_mask(&mask, vector); | ||
68 | } | 64 | } |
69 | 65 | ||
70 | static void summit_send_IPI_all(int vector) | 66 | static void summit_send_IPI_all(int vector) |
71 | { | 67 | { |
72 | summit_send_IPI_mask(&cpu_online_map, vector); | 68 | summit_send_IPI_mask(cpu_online_mask, vector); |
73 | } | 69 | } |
74 | 70 | ||
75 | #include <asm/tsc.h> | 71 | #include <asm/tsc.h> |
@@ -186,13 +182,13 @@ static inline int is_WPEG(struct rio_detail *rio){ | |||
186 | 182 | ||
187 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) | 183 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) |
188 | 184 | ||
189 | static const cpumask_t *summit_target_cpus(void) | 185 | static const struct cpumask *summit_target_cpus(void) |
190 | { | 186 | { |
191 | /* CPU_MASK_ALL (0xff) has undefined behaviour with | 187 | /* CPU_MASK_ALL (0xff) has undefined behaviour with |
192 | * dest_LowestPrio mode logical clustered apic interrupt routing | 188 | * dest_LowestPrio mode logical clustered apic interrupt routing |
193 | * Just start on cpu 0. IRQ balancing will spread load | 189 | * Just start on cpu 0. IRQ balancing will spread load |
194 | */ | 190 | */ |
195 | return &cpumask_of_cpu(0); | 191 | return cpumask_of(0); |
196 | } | 192 | } |
197 | 193 | ||
198 | static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) | 194 | static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) |
@@ -289,7 +285,7 @@ static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) | |||
289 | return 1; | 285 | return 1; |
290 | } | 286 | } |
291 | 287 | ||
292 | static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) | 288 | static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) |
293 | { | 289 | { |
294 | unsigned int round = 0; | 290 | unsigned int round = 0; |
295 | int cpu, apicid = 0; | 291 | int cpu, apicid = 0; |
@@ -346,7 +342,7 @@ static int probe_summit(void) | |||
346 | return 0; | 342 | return 0; |
347 | } | 343 | } |
348 | 344 | ||
349 | static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) | 345 | static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask) |
350 | { | 346 | { |
351 | /* Careful. Some cpus do not strictly honor the set of cpus | 347 | /* Careful. Some cpus do not strictly honor the set of cpus |
352 | * specified in the interrupt destination when using lowest | 348 | * specified in the interrupt destination when using lowest |
@@ -356,7 +352,8 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
356 | * deliver interrupts to the wrong hyperthread when only one | 352 | * deliver interrupts to the wrong hyperthread when only one |
357 | * hyperthread was specified in the interrupt desitination. | 353 | * hyperthread was specified in the interrupt desitination. |
358 | */ | 354 | */ |
359 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 355 | cpumask_clear(retmask); |
356 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
360 | } | 357 | } |
361 | 358 | ||
362 | #ifdef CONFIG_X86_SUMMIT_NUMA | 359 | #ifdef CONFIG_X86_SUMMIT_NUMA |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 1bd6da1f8fad..de1a50af807b 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -118,17 +118,12 @@ static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) | |||
118 | 118 | ||
119 | static void uv_send_IPI_one(int cpu, int vector) | 119 | static void uv_send_IPI_one(int cpu, int vector) |
120 | { | 120 | { |
121 | unsigned long val, apicid; | 121 | unsigned long apicid; |
122 | int pnode; | 122 | int pnode; |
123 | 123 | ||
124 | apicid = per_cpu(x86_cpu_to_apicid, cpu); | 124 | apicid = per_cpu(x86_cpu_to_apicid, cpu); |
125 | pnode = uv_apicid_to_pnode(apicid); | 125 | pnode = uv_apicid_to_pnode(apicid); |
126 | 126 | uv_hub_send_ipi(pnode, apicid, vector); | |
127 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | ||
128 | (apicid << UVH_IPI_INT_APIC_ID_SHFT) | | ||
129 | (vector << UVH_IPI_INT_VECTOR_SHFT); | ||
130 | |||
131 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); | ||
132 | } | 127 | } |
133 | 128 | ||
134 | static void uv_send_IPI_mask(const struct cpumask *mask, int vector) | 129 | static void uv_send_IPI_mask(const struct cpumask *mask, int vector) |
@@ -554,7 +549,8 @@ void __init uv_system_init(void) | |||
554 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; | 549 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; |
555 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; | 550 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; |
556 | int max_pnode = 0; | 551 | int max_pnode = 0; |
557 | unsigned long mmr_base, present; | 552 | unsigned long mmr_base, present, paddr; |
553 | unsigned short pnode_mask; | ||
558 | 554 | ||
559 | map_low_mmrs(); | 555 | map_low_mmrs(); |
560 | 556 | ||
@@ -597,6 +593,7 @@ void __init uv_system_init(void) | |||
597 | } | 593 | } |
598 | } | 594 | } |
599 | 595 | ||
596 | pnode_mask = (1 << n_val) - 1; | ||
600 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); | 597 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); |
601 | gnode_upper = (((unsigned long)node_id.s.node_id) & | 598 | gnode_upper = (((unsigned long)node_id.s.node_id) & |
602 | ~((1 << n_val) - 1)) << m_val; | 599 | ~((1 << n_val) - 1)) << m_val; |
@@ -620,7 +617,7 @@ void __init uv_system_init(void) | |||
620 | uv_cpu_hub_info(cpu)->numa_blade_id = blade; | 617 | uv_cpu_hub_info(cpu)->numa_blade_id = blade; |
621 | uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; | 618 | uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; |
622 | uv_cpu_hub_info(cpu)->pnode = pnode; | 619 | uv_cpu_hub_info(cpu)->pnode = pnode; |
623 | uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) - 1; | 620 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; |
624 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; | 621 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; |
625 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; | 622 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; |
626 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; | 623 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; |
@@ -636,6 +633,16 @@ void __init uv_system_init(void) | |||
636 | lcpu, blade); | 633 | lcpu, blade); |
637 | } | 634 | } |
638 | 635 | ||
636 | /* Add blade/pnode info for nodes without cpus */ | ||
637 | for_each_online_node(nid) { | ||
638 | if (uv_node_to_blade[nid] >= 0) | ||
639 | continue; | ||
640 | paddr = node_start_pfn(nid) << PAGE_SHIFT; | ||
641 | pnode = (paddr >> m_val) & pnode_mask; | ||
642 | blade = boot_pnode_to_blade(pnode); | ||
643 | uv_node_to_blade[nid] = blade; | ||
644 | } | ||
645 | |||
639 | map_gru_high(max_pnode); | 646 | map_gru_high(max_pnode); |
640 | map_mmr_high(max_pnode); | 647 | map_mmr_high(max_pnode); |
641 | map_config_high(max_pnode); | 648 | map_config_high(max_pnode); |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 10033fe718e0..49e0939bac42 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -466,7 +466,7 @@ static const lookup_t error_table[] = { | |||
466 | * @err: APM BIOS return code | 466 | * @err: APM BIOS return code |
467 | * | 467 | * |
468 | * Write a meaningful log entry to the kernel log in the event of | 468 | * Write a meaningful log entry to the kernel log in the event of |
469 | * an APM error. | 469 | * an APM error. Note that this also handles (negative) kernel errors. |
470 | */ | 470 | */ |
471 | 471 | ||
472 | static void apm_error(char *str, int err) | 472 | static void apm_error(char *str, int err) |
@@ -478,43 +478,14 @@ static void apm_error(char *str, int err) | |||
478 | break; | 478 | break; |
479 | if (i < ERROR_COUNT) | 479 | if (i < ERROR_COUNT) |
480 | printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); | 480 | printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); |
481 | else if (err < 0) | ||
482 | printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err); | ||
481 | else | 483 | else |
482 | printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", | 484 | printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", |
483 | str, err); | 485 | str, err); |
484 | } | 486 | } |
485 | 487 | ||
486 | /* | 488 | /* |
487 | * Lock APM functionality to physical CPU 0 | ||
488 | */ | ||
489 | |||
490 | #ifdef CONFIG_SMP | ||
491 | |||
492 | static cpumask_t apm_save_cpus(void) | ||
493 | { | ||
494 | cpumask_t x = current->cpus_allowed; | ||
495 | /* Some bioses don't like being called from CPU != 0 */ | ||
496 | set_cpus_allowed(current, cpumask_of_cpu(0)); | ||
497 | BUG_ON(smp_processor_id() != 0); | ||
498 | return x; | ||
499 | } | ||
500 | |||
501 | static inline void apm_restore_cpus(cpumask_t mask) | ||
502 | { | ||
503 | set_cpus_allowed(current, mask); | ||
504 | } | ||
505 | |||
506 | #else | ||
507 | |||
508 | /* | ||
509 | * No CPU lockdown needed on a uniprocessor | ||
510 | */ | ||
511 | |||
512 | #define apm_save_cpus() (current->cpus_allowed) | ||
513 | #define apm_restore_cpus(x) (void)(x) | ||
514 | |||
515 | #endif | ||
516 | |||
517 | /* | ||
518 | * These are the actual BIOS calls. Depending on APM_ZERO_SEGS and | 489 | * These are the actual BIOS calls. Depending on APM_ZERO_SEGS and |
519 | * apm_info.allow_ints, we are being really paranoid here! Not only | 490 | * apm_info.allow_ints, we are being really paranoid here! Not only |
520 | * are interrupts disabled, but all the segment registers (except SS) | 491 | * are interrupts disabled, but all the segment registers (except SS) |
@@ -568,16 +539,23 @@ static inline void apm_irq_restore(unsigned long flags) | |||
568 | # define APM_DO_RESTORE_SEGS | 539 | # define APM_DO_RESTORE_SEGS |
569 | #endif | 540 | #endif |
570 | 541 | ||
542 | struct apm_bios_call { | ||
543 | u32 func; | ||
544 | /* In and out */ | ||
545 | u32 ebx; | ||
546 | u32 ecx; | ||
547 | /* Out only */ | ||
548 | u32 eax; | ||
549 | u32 edx; | ||
550 | u32 esi; | ||
551 | |||
552 | /* Error: -ENOMEM, or bits 8-15 of eax */ | ||
553 | int err; | ||
554 | }; | ||
555 | |||
571 | /** | 556 | /** |
572 | * apm_bios_call - Make an APM BIOS 32bit call | 557 | * __apm_bios_call - Make an APM BIOS 32bit call |
573 | * @func: APM function to execute | 558 | * @_call: pointer to struct apm_bios_call. |
574 | * @ebx_in: EBX register for call entry | ||
575 | * @ecx_in: ECX register for call entry | ||
576 | * @eax: EAX register return | ||
577 | * @ebx: EBX register return | ||
578 | * @ecx: ECX register return | ||
579 | * @edx: EDX register return | ||
580 | * @esi: ESI register return | ||
581 | * | 559 | * |
582 | * Make an APM call using the 32bit protected mode interface. The | 560 | * Make an APM call using the 32bit protected mode interface. The |
583 | * caller is responsible for knowing if APM BIOS is configured and | 561 | * caller is responsible for knowing if APM BIOS is configured and |
@@ -586,80 +564,142 @@ static inline void apm_irq_restore(unsigned long flags) | |||
586 | * flag is loaded into AL. If there is an error, then the error | 564 | * flag is loaded into AL. If there is an error, then the error |
587 | * code is returned in AH (bits 8-15 of eax) and this function | 565 | * code is returned in AH (bits 8-15 of eax) and this function |
588 | * returns non-zero. | 566 | * returns non-zero. |
567 | * | ||
568 | * Note: this makes the call on the current CPU. | ||
589 | */ | 569 | */ |
590 | 570 | static long __apm_bios_call(void *_call) | |
591 | static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, | ||
592 | u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi) | ||
593 | { | 571 | { |
594 | APM_DECL_SEGS | 572 | APM_DECL_SEGS |
595 | unsigned long flags; | 573 | unsigned long flags; |
596 | cpumask_t cpus; | ||
597 | int cpu; | 574 | int cpu; |
598 | struct desc_struct save_desc_40; | 575 | struct desc_struct save_desc_40; |
599 | struct desc_struct *gdt; | 576 | struct desc_struct *gdt; |
600 | 577 | struct apm_bios_call *call = _call; | |
601 | cpus = apm_save_cpus(); | ||
602 | 578 | ||
603 | cpu = get_cpu(); | 579 | cpu = get_cpu(); |
580 | BUG_ON(cpu != 0); | ||
604 | gdt = get_cpu_gdt_table(cpu); | 581 | gdt = get_cpu_gdt_table(cpu); |
605 | save_desc_40 = gdt[0x40 / 8]; | 582 | save_desc_40 = gdt[0x40 / 8]; |
606 | gdt[0x40 / 8] = bad_bios_desc; | 583 | gdt[0x40 / 8] = bad_bios_desc; |
607 | 584 | ||
608 | apm_irq_save(flags); | 585 | apm_irq_save(flags); |
609 | APM_DO_SAVE_SEGS; | 586 | APM_DO_SAVE_SEGS; |
610 | apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); | 587 | apm_bios_call_asm(call->func, call->ebx, call->ecx, |
588 | &call->eax, &call->ebx, &call->ecx, &call->edx, | ||
589 | &call->esi); | ||
611 | APM_DO_RESTORE_SEGS; | 590 | APM_DO_RESTORE_SEGS; |
612 | apm_irq_restore(flags); | 591 | apm_irq_restore(flags); |
613 | gdt[0x40 / 8] = save_desc_40; | 592 | gdt[0x40 / 8] = save_desc_40; |
614 | put_cpu(); | 593 | put_cpu(); |
615 | apm_restore_cpus(cpus); | ||
616 | 594 | ||
617 | return *eax & 0xff; | 595 | return call->eax & 0xff; |
596 | } | ||
597 | |||
598 | /* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */ | ||
599 | static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call) | ||
600 | { | ||
601 | int ret; | ||
602 | |||
603 | /* Don't bother with work_on_cpu in the common case, so we don't | ||
604 | * have to worry about OOM or overhead. */ | ||
605 | if (get_cpu() == 0) { | ||
606 | ret = fn(call); | ||
607 | put_cpu(); | ||
608 | } else { | ||
609 | put_cpu(); | ||
610 | ret = work_on_cpu(0, fn, call); | ||
611 | } | ||
612 | |||
613 | /* work_on_cpu can fail with -ENOMEM */ | ||
614 | if (ret < 0) | ||
615 | call->err = ret; | ||
616 | else | ||
617 | call->err = (call->eax >> 8) & 0xff; | ||
618 | |||
619 | return ret; | ||
618 | } | 620 | } |
619 | 621 | ||
620 | /** | 622 | /** |
621 | * apm_bios_call_simple - make a simple APM BIOS 32bit call | 623 | * apm_bios_call - Make an APM BIOS 32bit call (on CPU 0) |
622 | * @func: APM function to invoke | 624 | * @call: the apm_bios_call registers. |
623 | * @ebx_in: EBX register value for BIOS call | 625 | * |
624 | * @ecx_in: ECX register value for BIOS call | 626 | * If there is an error, it is returned in @call.err. |
625 | * @eax: EAX register on return from the BIOS call | 627 | */ |
628 | static int apm_bios_call(struct apm_bios_call *call) | ||
629 | { | ||
630 | return on_cpu0(__apm_bios_call, call); | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * __apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0) | ||
635 | * @_call: pointer to struct apm_bios_call. | ||
626 | * | 636 | * |
627 | * Make a BIOS call that returns one value only, or just status. | 637 | * Make a BIOS call that returns one value only, or just status. |
628 | * If there is an error, then the error code is returned in AH | 638 | * If there is an error, then the error code is returned in AH |
629 | * (bits 8-15 of eax) and this function returns non-zero. This is | 639 | * (bits 8-15 of eax) and this function returns non-zero (it can |
630 | * used for simpler BIOS operations. This call may hold interrupts | 640 | * also return -ENOMEM). This is used for simpler BIOS operations. |
631 | * off for a long time on some laptops. | 641 | * This call may hold interrupts off for a long time on some laptops. |
642 | * | ||
643 | * Note: this makes the call on the current CPU. | ||
632 | */ | 644 | */ |
633 | 645 | static long __apm_bios_call_simple(void *_call) | |
634 | static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) | ||
635 | { | 646 | { |
636 | u8 error; | 647 | u8 error; |
637 | APM_DECL_SEGS | 648 | APM_DECL_SEGS |
638 | unsigned long flags; | 649 | unsigned long flags; |
639 | cpumask_t cpus; | ||
640 | int cpu; | 650 | int cpu; |
641 | struct desc_struct save_desc_40; | 651 | struct desc_struct save_desc_40; |
642 | struct desc_struct *gdt; | 652 | struct desc_struct *gdt; |
643 | 653 | struct apm_bios_call *call = _call; | |
644 | cpus = apm_save_cpus(); | ||
645 | 654 | ||
646 | cpu = get_cpu(); | 655 | cpu = get_cpu(); |
656 | BUG_ON(cpu != 0); | ||
647 | gdt = get_cpu_gdt_table(cpu); | 657 | gdt = get_cpu_gdt_table(cpu); |
648 | save_desc_40 = gdt[0x40 / 8]; | 658 | save_desc_40 = gdt[0x40 / 8]; |
649 | gdt[0x40 / 8] = bad_bios_desc; | 659 | gdt[0x40 / 8] = bad_bios_desc; |
650 | 660 | ||
651 | apm_irq_save(flags); | 661 | apm_irq_save(flags); |
652 | APM_DO_SAVE_SEGS; | 662 | APM_DO_SAVE_SEGS; |
653 | error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); | 663 | error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx, |
664 | &call->eax); | ||
654 | APM_DO_RESTORE_SEGS; | 665 | APM_DO_RESTORE_SEGS; |
655 | apm_irq_restore(flags); | 666 | apm_irq_restore(flags); |
656 | gdt[0x40 / 8] = save_desc_40; | 667 | gdt[0x40 / 8] = save_desc_40; |
657 | put_cpu(); | 668 | put_cpu(); |
658 | apm_restore_cpus(cpus); | ||
659 | return error; | 669 | return error; |
660 | } | 670 | } |
661 | 671 | ||
662 | /** | 672 | /** |
673 | * apm_bios_call_simple - make a simple APM BIOS 32bit call | ||
674 | * @func: APM function to invoke | ||
675 | * @ebx_in: EBX register value for BIOS call | ||
676 | * @ecx_in: ECX register value for BIOS call | ||
677 | * @eax: EAX register on return from the BIOS call | ||
678 | * @err: bits | ||
679 | * | ||
680 | * Make a BIOS call that returns one value only, or just status. | ||
681 | * If there is an error, then the error code is returned in @err | ||
682 | * and this function returns non-zero. This is used for simpler | ||
683 | * BIOS operations. This call may hold interrupts off for a long | ||
684 | * time on some laptops. | ||
685 | */ | ||
686 | static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax, | ||
687 | int *err) | ||
688 | { | ||
689 | struct apm_bios_call call; | ||
690 | int ret; | ||
691 | |||
692 | call.func = func; | ||
693 | call.ebx = ebx_in; | ||
694 | call.ecx = ecx_in; | ||
695 | |||
696 | ret = on_cpu0(__apm_bios_call_simple, &call); | ||
697 | *eax = call.eax; | ||
698 | *err = call.err; | ||
699 | return ret; | ||
700 | } | ||
701 | |||
702 | /** | ||
663 | * apm_driver_version - APM driver version | 703 | * apm_driver_version - APM driver version |
664 | * @val: loaded with the APM version on return | 704 | * @val: loaded with the APM version on return |
665 | * | 705 | * |
@@ -678,9 +718,10 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) | |||
678 | static int apm_driver_version(u_short *val) | 718 | static int apm_driver_version(u_short *val) |
679 | { | 719 | { |
680 | u32 eax; | 720 | u32 eax; |
721 | int err; | ||
681 | 722 | ||
682 | if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax)) | 723 | if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err)) |
683 | return (eax >> 8) & 0xff; | 724 | return err; |
684 | *val = eax; | 725 | *val = eax; |
685 | return APM_SUCCESS; | 726 | return APM_SUCCESS; |
686 | } | 727 | } |
@@ -701,22 +742,21 @@ static int apm_driver_version(u_short *val) | |||
701 | * that APM 1.2 is in use. If no messges are pending the value 0x80 | 742 | * that APM 1.2 is in use. If no messges are pending the value 0x80 |
702 | * is returned (No power management events pending). | 743 | * is returned (No power management events pending). |
703 | */ | 744 | */ |
704 | |||
705 | static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info) | 745 | static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info) |
706 | { | 746 | { |
707 | u32 eax; | 747 | struct apm_bios_call call; |
708 | u32 ebx; | ||
709 | u32 ecx; | ||
710 | u32 dummy; | ||
711 | 748 | ||
712 | if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx, | 749 | call.func = APM_FUNC_GET_EVENT; |
713 | &dummy, &dummy)) | 750 | call.ebx = call.ecx = 0; |
714 | return (eax >> 8) & 0xff; | 751 | |
715 | *event = ebx; | 752 | if (apm_bios_call(&call)) |
753 | return call.err; | ||
754 | |||
755 | *event = call.ebx; | ||
716 | if (apm_info.connection_version < 0x0102) | 756 | if (apm_info.connection_version < 0x0102) |
717 | *info = ~0; /* indicate info not valid */ | 757 | *info = ~0; /* indicate info not valid */ |
718 | else | 758 | else |
719 | *info = ecx; | 759 | *info = call.ecx; |
720 | return APM_SUCCESS; | 760 | return APM_SUCCESS; |
721 | } | 761 | } |
722 | 762 | ||
@@ -737,9 +777,10 @@ static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info) | |||
737 | static int set_power_state(u_short what, u_short state) | 777 | static int set_power_state(u_short what, u_short state) |
738 | { | 778 | { |
739 | u32 eax; | 779 | u32 eax; |
780 | int err; | ||
740 | 781 | ||
741 | if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax)) | 782 | if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err)) |
742 | return (eax >> 8) & 0xff; | 783 | return err; |
743 | return APM_SUCCESS; | 784 | return APM_SUCCESS; |
744 | } | 785 | } |
745 | 786 | ||
@@ -770,6 +811,7 @@ static int apm_do_idle(void) | |||
770 | u8 ret = 0; | 811 | u8 ret = 0; |
771 | int idled = 0; | 812 | int idled = 0; |
772 | int polling; | 813 | int polling; |
814 | int err; | ||
773 | 815 | ||
774 | polling = !!(current_thread_info()->status & TS_POLLING); | 816 | polling = !!(current_thread_info()->status & TS_POLLING); |
775 | if (polling) { | 817 | if (polling) { |
@@ -782,7 +824,7 @@ static int apm_do_idle(void) | |||
782 | } | 824 | } |
783 | if (!need_resched()) { | 825 | if (!need_resched()) { |
784 | idled = 1; | 826 | idled = 1; |
785 | ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); | 827 | ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err); |
786 | } | 828 | } |
787 | if (polling) | 829 | if (polling) |
788 | current_thread_info()->status |= TS_POLLING; | 830 | current_thread_info()->status |= TS_POLLING; |
@@ -797,8 +839,7 @@ static int apm_do_idle(void) | |||
797 | * Only report the failure the first 5 times. | 839 | * Only report the failure the first 5 times. |
798 | */ | 840 | */ |
799 | if (++t < 5) { | 841 | if (++t < 5) { |
800 | printk(KERN_DEBUG "apm_do_idle failed (%d)\n", | 842 | printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err); |
801 | (eax >> 8) & 0xff); | ||
802 | t = jiffies; | 843 | t = jiffies; |
803 | } | 844 | } |
804 | return -1; | 845 | return -1; |
@@ -816,9 +857,10 @@ static int apm_do_idle(void) | |||
816 | static void apm_do_busy(void) | 857 | static void apm_do_busy(void) |
817 | { | 858 | { |
818 | u32 dummy; | 859 | u32 dummy; |
860 | int err; | ||
819 | 861 | ||
820 | if (clock_slowed || ALWAYS_CALL_BUSY) { | 862 | if (clock_slowed || ALWAYS_CALL_BUSY) { |
821 | (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy); | 863 | (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err); |
822 | clock_slowed = 0; | 864 | clock_slowed = 0; |
823 | } | 865 | } |
824 | } | 866 | } |
@@ -937,7 +979,7 @@ static void apm_power_off(void) | |||
937 | 979 | ||
938 | /* Some bioses don't like being called from CPU != 0 */ | 980 | /* Some bioses don't like being called from CPU != 0 */ |
939 | if (apm_info.realmode_power_off) { | 981 | if (apm_info.realmode_power_off) { |
940 | (void)apm_save_cpus(); | 982 | set_cpus_allowed_ptr(current, cpumask_of(0)); |
941 | machine_real_restart(po_bios_call, sizeof(po_bios_call)); | 983 | machine_real_restart(po_bios_call, sizeof(po_bios_call)); |
942 | } else { | 984 | } else { |
943 | (void)set_system_power_state(APM_STATE_OFF); | 985 | (void)set_system_power_state(APM_STATE_OFF); |
@@ -956,12 +998,13 @@ static void apm_power_off(void) | |||
956 | static int apm_enable_power_management(int enable) | 998 | static int apm_enable_power_management(int enable) |
957 | { | 999 | { |
958 | u32 eax; | 1000 | u32 eax; |
1001 | int err; | ||
959 | 1002 | ||
960 | if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED)) | 1003 | if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED)) |
961 | return APM_NOT_ENGAGED; | 1004 | return APM_NOT_ENGAGED; |
962 | if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL, | 1005 | if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL, |
963 | enable, &eax)) | 1006 | enable, &eax, &err)) |
964 | return (eax >> 8) & 0xff; | 1007 | return err; |
965 | if (enable) | 1008 | if (enable) |
966 | apm_info.bios.flags &= ~APM_BIOS_DISABLED; | 1009 | apm_info.bios.flags &= ~APM_BIOS_DISABLED; |
967 | else | 1010 | else |
@@ -986,24 +1029,23 @@ static int apm_enable_power_management(int enable) | |||
986 | 1029 | ||
987 | static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) | 1030 | static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) |
988 | { | 1031 | { |
989 | u32 eax; | 1032 | struct apm_bios_call call; |
990 | u32 ebx; | 1033 | |
991 | u32 ecx; | 1034 | call.func = APM_FUNC_GET_STATUS; |
992 | u32 edx; | 1035 | call.ebx = APM_DEVICE_ALL; |
993 | u32 dummy; | 1036 | call.ecx = 0; |
994 | 1037 | ||
995 | if (apm_info.get_power_status_broken) | 1038 | if (apm_info.get_power_status_broken) |
996 | return APM_32_UNSUPPORTED; | 1039 | return APM_32_UNSUPPORTED; |
997 | if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0, | 1040 | if (apm_bios_call(&call)) |
998 | &eax, &ebx, &ecx, &edx, &dummy)) | 1041 | return call.err; |
999 | return (eax >> 8) & 0xff; | 1042 | *status = call.ebx; |
1000 | *status = ebx; | 1043 | *bat = call.ecx; |
1001 | *bat = ecx; | ||
1002 | if (apm_info.get_power_status_swabinminutes) { | 1044 | if (apm_info.get_power_status_swabinminutes) { |
1003 | *life = swab16((u16)edx); | 1045 | *life = swab16((u16)call.edx); |
1004 | *life |= 0x8000; | 1046 | *life |= 0x8000; |
1005 | } else | 1047 | } else |
1006 | *life = edx; | 1048 | *life = call.edx; |
1007 | return APM_SUCCESS; | 1049 | return APM_SUCCESS; |
1008 | } | 1050 | } |
1009 | 1051 | ||
@@ -1048,12 +1090,14 @@ static int apm_get_battery_status(u_short which, u_short *status, | |||
1048 | static int apm_engage_power_management(u_short device, int enable) | 1090 | static int apm_engage_power_management(u_short device, int enable) |
1049 | { | 1091 | { |
1050 | u32 eax; | 1092 | u32 eax; |
1093 | int err; | ||
1051 | 1094 | ||
1052 | if ((enable == 0) && (device == APM_DEVICE_ALL) | 1095 | if ((enable == 0) && (device == APM_DEVICE_ALL) |
1053 | && (apm_info.bios.flags & APM_BIOS_DISABLED)) | 1096 | && (apm_info.bios.flags & APM_BIOS_DISABLED)) |
1054 | return APM_DISABLED; | 1097 | return APM_DISABLED; |
1055 | if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax)) | 1098 | if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, |
1056 | return (eax >> 8) & 0xff; | 1099 | &eax, &err)) |
1100 | return err; | ||
1057 | if (device == APM_DEVICE_ALL) { | 1101 | if (device == APM_DEVICE_ALL) { |
1058 | if (enable) | 1102 | if (enable) |
1059 | apm_info.bios.flags &= ~APM_BIOS_DISENGAGED; | 1103 | apm_info.bios.flags &= ~APM_BIOS_DISENGAGED; |
@@ -1190,8 +1234,10 @@ static int suspend(int vetoable) | |||
1190 | struct apm_user *as; | 1234 | struct apm_user *as; |
1191 | 1235 | ||
1192 | device_suspend(PMSG_SUSPEND); | 1236 | device_suspend(PMSG_SUSPEND); |
1193 | local_irq_disable(); | 1237 | |
1194 | device_power_down(PMSG_SUSPEND); | 1238 | device_power_down(PMSG_SUSPEND); |
1239 | |||
1240 | local_irq_disable(); | ||
1195 | sysdev_suspend(PMSG_SUSPEND); | 1241 | sysdev_suspend(PMSG_SUSPEND); |
1196 | 1242 | ||
1197 | local_irq_enable(); | 1243 | local_irq_enable(); |
@@ -1209,9 +1255,12 @@ static int suspend(int vetoable) | |||
1209 | if (err != APM_SUCCESS) | 1255 | if (err != APM_SUCCESS) |
1210 | apm_error("suspend", err); | 1256 | apm_error("suspend", err); |
1211 | err = (err == APM_SUCCESS) ? 0 : -EIO; | 1257 | err = (err == APM_SUCCESS) ? 0 : -EIO; |
1258 | |||
1212 | sysdev_resume(); | 1259 | sysdev_resume(); |
1213 | device_power_up(PMSG_RESUME); | ||
1214 | local_irq_enable(); | 1260 | local_irq_enable(); |
1261 | |||
1262 | device_power_up(PMSG_RESUME); | ||
1263 | |||
1215 | device_resume(PMSG_RESUME); | 1264 | device_resume(PMSG_RESUME); |
1216 | queue_event(APM_NORMAL_RESUME, NULL); | 1265 | queue_event(APM_NORMAL_RESUME, NULL); |
1217 | spin_lock(&user_list_lock); | 1266 | spin_lock(&user_list_lock); |
@@ -1228,8 +1277,9 @@ static void standby(void) | |||
1228 | { | 1277 | { |
1229 | int err; | 1278 | int err; |
1230 | 1279 | ||
1231 | local_irq_disable(); | ||
1232 | device_power_down(PMSG_SUSPEND); | 1280 | device_power_down(PMSG_SUSPEND); |
1281 | |||
1282 | local_irq_disable(); | ||
1233 | sysdev_suspend(PMSG_SUSPEND); | 1283 | sysdev_suspend(PMSG_SUSPEND); |
1234 | local_irq_enable(); | 1284 | local_irq_enable(); |
1235 | 1285 | ||
@@ -1239,8 +1289,9 @@ static void standby(void) | |||
1239 | 1289 | ||
1240 | local_irq_disable(); | 1290 | local_irq_disable(); |
1241 | sysdev_resume(); | 1291 | sysdev_resume(); |
1242 | device_power_up(PMSG_RESUME); | ||
1243 | local_irq_enable(); | 1292 | local_irq_enable(); |
1293 | |||
1294 | device_power_up(PMSG_RESUME); | ||
1244 | } | 1295 | } |
1245 | 1296 | ||
1246 | static apm_event_t get_event(void) | 1297 | static apm_event_t get_event(void) |
@@ -1682,16 +1733,14 @@ static int apm(void *unused) | |||
1682 | char *power_stat; | 1733 | char *power_stat; |
1683 | char *bat_stat; | 1734 | char *bat_stat; |
1684 | 1735 | ||
1685 | #ifdef CONFIG_SMP | ||
1686 | /* 2002/08/01 - WT | 1736 | /* 2002/08/01 - WT |
1687 | * This is to avoid random crashes at boot time during initialization | 1737 | * This is to avoid random crashes at boot time during initialization |
1688 | * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D. | 1738 | * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D. |
1689 | * Some bioses don't like being called from CPU != 0. | 1739 | * Some bioses don't like being called from CPU != 0. |
1690 | * Method suggested by Ingo Molnar. | 1740 | * Method suggested by Ingo Molnar. |
1691 | */ | 1741 | */ |
1692 | set_cpus_allowed(current, cpumask_of_cpu(0)); | 1742 | set_cpus_allowed_ptr(current, cpumask_of(0)); |
1693 | BUG_ON(smp_processor_id() != 0); | 1743 | BUG_ON(smp_processor_id() != 0); |
1694 | #endif | ||
1695 | 1744 | ||
1696 | if (apm_info.connection_version == 0) { | 1745 | if (apm_info.connection_version == 0) { |
1697 | apm_info.connection_version = apm_info.bios.version; | 1746 | apm_info.connection_version = apm_info.bios.version; |
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index fbf2f33e3080..5a6aa1c1162f 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
19 | #include <asm/bootparam.h> | 19 | #include <asm/bootparam.h> |
20 | #include <asm/elf.h> | 20 | #include <asm/elf.h> |
21 | #include <asm/suspend.h> | ||
21 | 22 | ||
22 | #include <xen/interface/xen.h> | 23 | #include <xen/interface/xen.h> |
23 | 24 | ||
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 8793ab33e2c1..e72f062fb4b5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | #include <asm/ia32.h> | 17 | #include <asm/ia32.h> |
18 | #include <asm/bootparam.h> | 18 | #include <asm/bootparam.h> |
19 | #include <asm/suspend.h> | ||
19 | 20 | ||
20 | #include <xen/interface/xen.h> | 21 | #include <xen/interface/xen.h> |
21 | 22 | ||
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c index f63882728d91..63a88e1f987d 100644 --- a/arch/x86/kernel/bios_uv.c +++ b/arch/x86/kernel/bios_uv.c | |||
@@ -182,7 +182,8 @@ void uv_bios_init(void) | |||
182 | memcpy(&uv_systab, tab, sizeof(struct uv_systab)); | 182 | memcpy(&uv_systab, tab, sizeof(struct uv_systab)); |
183 | iounmap(tab); | 183 | iounmap(tab); |
184 | 184 | ||
185 | printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision); | 185 | printk(KERN_INFO "EFI UV System Table Revision %d\n", |
186 | uv_systab.revision); | ||
186 | } | 187 | } |
187 | #else /* !CONFIG_EFI */ | 188 | #else /* !CONFIG_EFI */ |
188 | 189 | ||
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index 8220ae69849d..c965e5212714 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c | |||
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
31 | 31 | ||
32 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | 32 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { |
33 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, | 33 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, |
34 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, | ||
34 | { 0, 0, 0, 0 } | 35 | { 0, 0, 0, 0 } |
35 | }; | 36 | }; |
36 | 37 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index e2962cc1e27b..c4f667896c28 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | #include "cpu.h" | 42 | #include "cpu.h" |
43 | 43 | ||
44 | #ifdef CONFIG_X86_64 | ||
45 | |||
46 | /* all of these masks are initialized in setup_cpu_local_masks() */ | 44 | /* all of these masks are initialized in setup_cpu_local_masks() */ |
47 | cpumask_var_t cpu_initialized_mask; | 45 | cpumask_var_t cpu_initialized_mask; |
48 | cpumask_var_t cpu_callout_mask; | 46 | cpumask_var_t cpu_callout_mask; |
@@ -60,16 +58,6 @@ void __init setup_cpu_local_masks(void) | |||
60 | alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); | 58 | alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); |
61 | } | 59 | } |
62 | 60 | ||
63 | #else /* CONFIG_X86_32 */ | ||
64 | |||
65 | cpumask_t cpu_sibling_setup_map; | ||
66 | cpumask_t cpu_callout_map; | ||
67 | cpumask_t cpu_initialized; | ||
68 | cpumask_t cpu_callin_map; | ||
69 | |||
70 | #endif /* CONFIG_X86_32 */ | ||
71 | |||
72 | |||
73 | static const struct cpu_dev *this_cpu __cpuinitdata; | 61 | static const struct cpu_dev *this_cpu __cpuinitdata; |
74 | 62 | ||
75 | DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | 63 | DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { |
@@ -859,6 +847,7 @@ static void vgetcpu_set_mode(void) | |||
859 | void __init identify_boot_cpu(void) | 847 | void __init identify_boot_cpu(void) |
860 | { | 848 | { |
861 | identify_cpu(&boot_cpu_data); | 849 | identify_cpu(&boot_cpu_data); |
850 | init_c1e_mask(); | ||
862 | #ifdef CONFIG_X86_32 | 851 | #ifdef CONFIG_X86_32 |
863 | sysenter_setup(); | 852 | sysenter_setup(); |
864 | enable_sep_cpu(); | 853 | enable_sep_cpu(); |
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 9469ecb5aeb8..6de9a908e400 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
@@ -3,25 +3,25 @@ | |||
3 | #define ARCH_X86_CPU_H | 3 | #define ARCH_X86_CPU_H |
4 | 4 | ||
5 | struct cpu_model_info { | 5 | struct cpu_model_info { |
6 | int vendor; | 6 | int vendor; |
7 | int family; | 7 | int family; |
8 | const char *model_names[16]; | 8 | const char *model_names[16]; |
9 | }; | 9 | }; |
10 | 10 | ||
11 | /* attempt to consolidate cpu attributes */ | 11 | /* attempt to consolidate cpu attributes */ |
12 | struct cpu_dev { | 12 | struct cpu_dev { |
13 | const char * c_vendor; | 13 | const char *c_vendor; |
14 | 14 | ||
15 | /* some have two possibilities for cpuid string */ | 15 | /* some have two possibilities for cpuid string */ |
16 | const char * c_ident[2]; | 16 | const char *c_ident[2]; |
17 | 17 | ||
18 | struct cpu_model_info c_models[4]; | 18 | struct cpu_model_info c_models[4]; |
19 | 19 | ||
20 | void (*c_early_init)(struct cpuinfo_x86 *c); | 20 | void (*c_early_init)(struct cpuinfo_x86 *); |
21 | void (*c_init)(struct cpuinfo_x86 * c); | 21 | void (*c_init)(struct cpuinfo_x86 *); |
22 | void (*c_identify)(struct cpuinfo_x86 * c); | 22 | void (*c_identify)(struct cpuinfo_x86 *); |
23 | unsigned int (*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size); | 23 | unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); |
24 | int c_x86_vendor; | 24 | int c_x86_vendor; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | #define cpu_dev_register(cpu_devX) \ | 27 | #define cpu_dev_register(cpu_devX) \ |
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c index 46e29ab96c6a..46e29ab96c6a 100755..100644 --- a/arch/x86/kernel/cpu/cpu_debug.c +++ b/arch/x86/kernel/cpu/cpu_debug.c | |||
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig index 65792c2cc462..52c839875478 100644 --- a/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/arch/x86/kernel/cpu/cpufreq/Kconfig | |||
@@ -87,30 +87,15 @@ config X86_POWERNOW_K7_ACPI | |||
87 | config X86_POWERNOW_K8 | 87 | config X86_POWERNOW_K8 |
88 | tristate "AMD Opteron/Athlon64 PowerNow!" | 88 | tristate "AMD Opteron/Athlon64 PowerNow!" |
89 | select CPU_FREQ_TABLE | 89 | select CPU_FREQ_TABLE |
90 | depends on ACPI && ACPI_PROCESSOR | ||
90 | help | 91 | help |
91 | This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. | 92 | This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors. |
92 | 93 | ||
93 | To compile this driver as a module, choose M here: the | 94 | To compile this driver as a module, choose M here: the |
94 | module will be called powernow-k8. | 95 | module will be called powernow-k8. |
95 | 96 | ||
96 | For details, take a look at <file:Documentation/cpu-freq/>. | 97 | For details, take a look at <file:Documentation/cpu-freq/>. |
97 | 98 | ||
98 | If in doubt, say N. | ||
99 | |||
100 | config X86_POWERNOW_K8_ACPI | ||
101 | bool | ||
102 | prompt "ACPI Support" if X86_32 | ||
103 | depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR | ||
104 | depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m) | ||
105 | default y | ||
106 | help | ||
107 | This provides access to the K8s Processor Performance States via ACPI. | ||
108 | This driver is probably required for CPUFreq to work with multi-socket and | ||
109 | SMP systems. It is not required on at least some single-socket yet | ||
110 | multi-core systems, even if SMP is enabled. | ||
111 | |||
112 | It is safe to say Y here. | ||
113 | |||
114 | config X86_GX_SUSPMOD | 99 | config X86_GX_SUSPMOD |
115 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" | 100 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" |
116 | depends on X86_32 && PCI | 101 | depends on X86_32 && PCI |
diff --git a/arch/x86/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile index 560f7760dae5..509296df294d 100644 --- a/arch/x86/kernel/cpu/cpufreq/Makefile +++ b/arch/x86/kernel/cpu/cpufreq/Makefile | |||
@@ -1,6 +1,11 @@ | |||
1 | # Link order matters. K8 is preferred to ACPI because of firmware bugs in early | ||
2 | # K8 systems. ACPI is preferred to all other hardware-specific drivers. | ||
3 | # speedstep-* is preferred over p4-clockmod. | ||
4 | |||
5 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | ||
6 | obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o | ||
1 | obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o | 7 | obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o |
2 | obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o | 8 | obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o |
3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | ||
4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o | 9 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o |
5 | obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o | 10 | obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o |
6 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o | 11 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o |
@@ -10,7 +15,6 @@ obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o | |||
10 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o | 15 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o |
11 | obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o | 16 | obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o |
12 | obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o | 17 | obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o |
13 | obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o | ||
14 | obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o | 18 | obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o |
15 | obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o | 19 | obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o |
16 | obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o | 20 | obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 22590cf688ae..ecdb682ab516 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $) | 2 | * acpi-cpufreq.c - ACPI Processor P-States Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | 4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> |
5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | 5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
@@ -33,19 +33,21 @@ | |||
33 | #include <linux/cpufreq.h> | 33 | #include <linux/cpufreq.h> |
34 | #include <linux/compiler.h> | 34 | #include <linux/compiler.h> |
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | #include <linux/ftrace.h> | 36 | #include <trace/power.h> |
37 | 37 | ||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/io.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/uaccess.h> | ||
42 | |||
39 | #include <acpi/processor.h> | 43 | #include <acpi/processor.h> |
40 | 44 | ||
41 | #include <asm/io.h> | ||
42 | #include <asm/msr.h> | 45 | #include <asm/msr.h> |
43 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
44 | #include <asm/cpufeature.h> | 47 | #include <asm/cpufeature.h> |
45 | #include <asm/delay.h> | ||
46 | #include <asm/uaccess.h> | ||
47 | 48 | ||
48 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg) | 49 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
50 | "acpi-cpufreq", msg) | ||
49 | 51 | ||
50 | MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); | 52 | MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); |
51 | MODULE_DESCRIPTION("ACPI Processor P-States Driver"); | 53 | MODULE_DESCRIPTION("ACPI Processor P-States Driver"); |
@@ -66,10 +68,13 @@ struct acpi_cpufreq_data { | |||
66 | unsigned int max_freq; | 68 | unsigned int max_freq; |
67 | unsigned int resume; | 69 | unsigned int resume; |
68 | unsigned int cpu_feature; | 70 | unsigned int cpu_feature; |
71 | u64 saved_aperf, saved_mperf; | ||
69 | }; | 72 | }; |
70 | 73 | ||
71 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); | 74 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); |
72 | 75 | ||
76 | DEFINE_TRACE(power_mark); | ||
77 | |||
73 | /* acpi_perf_data is a pointer to percpu data. */ | 78 | /* acpi_perf_data is a pointer to percpu data. */ |
74 | static struct acpi_processor_performance *acpi_perf_data; | 79 | static struct acpi_processor_performance *acpi_perf_data; |
75 | 80 | ||
@@ -95,7 +100,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) | |||
95 | 100 | ||
96 | perf = data->acpi_data; | 101 | perf = data->acpi_data; |
97 | 102 | ||
98 | for (i=0; i<perf->state_count; i++) { | 103 | for (i = 0; i < perf->state_count; i++) { |
99 | if (value == perf->states[i].status) | 104 | if (value == perf->states[i].status) |
100 | return data->freq_table[i].frequency; | 105 | return data->freq_table[i].frequency; |
101 | } | 106 | } |
@@ -110,7 +115,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) | |||
110 | msr &= INTEL_MSR_RANGE; | 115 | msr &= INTEL_MSR_RANGE; |
111 | perf = data->acpi_data; | 116 | perf = data->acpi_data; |
112 | 117 | ||
113 | for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { | 118 | for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { |
114 | if (msr == perf->states[data->freq_table[i].index].status) | 119 | if (msr == perf->states[data->freq_table[i].index].status) |
115 | return data->freq_table[i].frequency; | 120 | return data->freq_table[i].frequency; |
116 | } | 121 | } |
@@ -138,19 +143,18 @@ struct io_addr { | |||
138 | u8 bit_width; | 143 | u8 bit_width; |
139 | }; | 144 | }; |
140 | 145 | ||
141 | typedef union { | ||
142 | struct msr_addr msr; | ||
143 | struct io_addr io; | ||
144 | } drv_addr_union; | ||
145 | |||
146 | struct drv_cmd { | 146 | struct drv_cmd { |
147 | unsigned int type; | 147 | unsigned int type; |
148 | const struct cpumask *mask; | 148 | const struct cpumask *mask; |
149 | drv_addr_union addr; | 149 | union { |
150 | struct msr_addr msr; | ||
151 | struct io_addr io; | ||
152 | } addr; | ||
150 | u32 val; | 153 | u32 val; |
151 | }; | 154 | }; |
152 | 155 | ||
153 | static long do_drv_read(void *_cmd) | 156 | /* Called via smp_call_function_single(), on the target CPU */ |
157 | static void do_drv_read(void *_cmd) | ||
154 | { | 158 | { |
155 | struct drv_cmd *cmd = _cmd; | 159 | struct drv_cmd *cmd = _cmd; |
156 | u32 h; | 160 | u32 h; |
@@ -167,10 +171,10 @@ static long do_drv_read(void *_cmd) | |||
167 | default: | 171 | default: |
168 | break; | 172 | break; |
169 | } | 173 | } |
170 | return 0; | ||
171 | } | 174 | } |
172 | 175 | ||
173 | static long do_drv_write(void *_cmd) | 176 | /* Called via smp_call_function_many(), on the target CPUs */ |
177 | static void do_drv_write(void *_cmd) | ||
174 | { | 178 | { |
175 | struct drv_cmd *cmd = _cmd; | 179 | struct drv_cmd *cmd = _cmd; |
176 | u32 lo, hi; | 180 | u32 lo, hi; |
@@ -189,23 +193,24 @@ static long do_drv_write(void *_cmd) | |||
189 | default: | 193 | default: |
190 | break; | 194 | break; |
191 | } | 195 | } |
192 | return 0; | ||
193 | } | 196 | } |
194 | 197 | ||
195 | static void drv_read(struct drv_cmd *cmd) | 198 | static void drv_read(struct drv_cmd *cmd) |
196 | { | 199 | { |
197 | cmd->val = 0; | 200 | cmd->val = 0; |
198 | 201 | ||
199 | work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); | 202 | smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1); |
200 | } | 203 | } |
201 | 204 | ||
202 | static void drv_write(struct drv_cmd *cmd) | 205 | static void drv_write(struct drv_cmd *cmd) |
203 | { | 206 | { |
204 | unsigned int i; | 207 | int this_cpu; |
205 | 208 | ||
206 | for_each_cpu(i, cmd->mask) { | 209 | this_cpu = get_cpu(); |
207 | work_on_cpu(i, do_drv_write, cmd); | 210 | if (cpumask_test_cpu(this_cpu, cmd->mask)) |
208 | } | 211 | do_drv_write(cmd); |
212 | smp_call_function_many(cmd->mask, do_drv_write, cmd, 1); | ||
213 | put_cpu(); | ||
209 | } | 214 | } |
210 | 215 | ||
211 | static u32 get_cur_val(const struct cpumask *mask) | 216 | static u32 get_cur_val(const struct cpumask *mask) |
@@ -239,28 +244,23 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
239 | return cmd.val; | 244 | return cmd.val; |
240 | } | 245 | } |
241 | 246 | ||
242 | struct perf_cur { | 247 | struct perf_pair { |
243 | union { | 248 | union { |
244 | struct { | 249 | struct { |
245 | u32 lo; | 250 | u32 lo; |
246 | u32 hi; | 251 | u32 hi; |
247 | } split; | 252 | } split; |
248 | u64 whole; | 253 | u64 whole; |
249 | } aperf_cur, mperf_cur; | 254 | } aperf, mperf; |
250 | }; | 255 | }; |
251 | 256 | ||
252 | 257 | /* Called via smp_call_function_single(), on the target CPU */ | |
253 | static long read_measured_perf_ctrs(void *_cur) | 258 | static void read_measured_perf_ctrs(void *_cur) |
254 | { | 259 | { |
255 | struct perf_cur *cur = _cur; | 260 | struct perf_pair *cur = _cur; |
256 | |||
257 | rdmsr(MSR_IA32_APERF, cur->aperf_cur.split.lo, cur->aperf_cur.split.hi); | ||
258 | rdmsr(MSR_IA32_MPERF, cur->mperf_cur.split.lo, cur->mperf_cur.split.hi); | ||
259 | 261 | ||
260 | wrmsr(MSR_IA32_APERF, 0, 0); | 262 | rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi); |
261 | wrmsr(MSR_IA32_MPERF, 0, 0); | 263 | rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi); |
262 | |||
263 | return 0; | ||
264 | } | 264 | } |
265 | 265 | ||
266 | /* | 266 | /* |
@@ -279,52 +279,57 @@ static long read_measured_perf_ctrs(void *_cur) | |||
279 | static unsigned int get_measured_perf(struct cpufreq_policy *policy, | 279 | static unsigned int get_measured_perf(struct cpufreq_policy *policy, |
280 | unsigned int cpu) | 280 | unsigned int cpu) |
281 | { | 281 | { |
282 | struct perf_cur cur; | 282 | struct perf_pair readin, cur; |
283 | unsigned int perf_percent; | 283 | unsigned int perf_percent; |
284 | unsigned int retval; | 284 | unsigned int retval; |
285 | 285 | ||
286 | if (!work_on_cpu(cpu, read_measured_perf_ctrs, &cur)) | 286 | if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1)) |
287 | return 0; | 287 | return 0; |
288 | 288 | ||
289 | cur.aperf.whole = readin.aperf.whole - | ||
290 | per_cpu(drv_data, cpu)->saved_aperf; | ||
291 | cur.mperf.whole = readin.mperf.whole - | ||
292 | per_cpu(drv_data, cpu)->saved_mperf; | ||
293 | per_cpu(drv_data, cpu)->saved_aperf = readin.aperf.whole; | ||
294 | per_cpu(drv_data, cpu)->saved_mperf = readin.mperf.whole; | ||
295 | |||
289 | #ifdef __i386__ | 296 | #ifdef __i386__ |
290 | /* | 297 | /* |
291 | * We dont want to do 64 bit divide with 32 bit kernel | 298 | * We dont want to do 64 bit divide with 32 bit kernel |
292 | * Get an approximate value. Return failure in case we cannot get | 299 | * Get an approximate value. Return failure in case we cannot get |
293 | * an approximate value. | 300 | * an approximate value. |
294 | */ | 301 | */ |
295 | if (unlikely(cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) { | 302 | if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) { |
296 | int shift_count; | 303 | int shift_count; |
297 | u32 h; | 304 | u32 h; |
298 | 305 | ||
299 | h = max_t(u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi); | 306 | h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi); |
300 | shift_count = fls(h); | 307 | shift_count = fls(h); |
301 | 308 | ||
302 | cur.aperf_cur.whole >>= shift_count; | 309 | cur.aperf.whole >>= shift_count; |
303 | cur.mperf_cur.whole >>= shift_count; | 310 | cur.mperf.whole >>= shift_count; |
304 | } | 311 | } |
305 | 312 | ||
306 | if (((unsigned long)(-1) / 100) < cur.aperf_cur.split.lo) { | 313 | if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) { |
307 | int shift_count = 7; | 314 | int shift_count = 7; |
308 | cur.aperf_cur.split.lo >>= shift_count; | 315 | cur.aperf.split.lo >>= shift_count; |
309 | cur.mperf_cur.split.lo >>= shift_count; | 316 | cur.mperf.split.lo >>= shift_count; |
310 | } | 317 | } |
311 | 318 | ||
312 | if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo) | 319 | if (cur.aperf.split.lo && cur.mperf.split.lo) |
313 | perf_percent = (cur.aperf_cur.split.lo * 100) / | 320 | perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo; |
314 | cur.mperf_cur.split.lo; | ||
315 | else | 321 | else |
316 | perf_percent = 0; | 322 | perf_percent = 0; |
317 | 323 | ||
318 | #else | 324 | #else |
319 | if (unlikely(((unsigned long)(-1) / 100) < cur.aperf_cur.whole)) { | 325 | if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) { |
320 | int shift_count = 7; | 326 | int shift_count = 7; |
321 | cur.aperf_cur.whole >>= shift_count; | 327 | cur.aperf.whole >>= shift_count; |
322 | cur.mperf_cur.whole >>= shift_count; | 328 | cur.mperf.whole >>= shift_count; |
323 | } | 329 | } |
324 | 330 | ||
325 | if (cur.aperf_cur.whole && cur.mperf_cur.whole) | 331 | if (cur.aperf.whole && cur.mperf.whole) |
326 | perf_percent = (cur.aperf_cur.whole * 100) / | 332 | perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole; |
327 | cur.mperf_cur.whole; | ||
328 | else | 333 | else |
329 | perf_percent = 0; | 334 | perf_percent = 0; |
330 | 335 | ||
@@ -369,7 +374,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, | |||
369 | unsigned int cur_freq; | 374 | unsigned int cur_freq; |
370 | unsigned int i; | 375 | unsigned int i; |
371 | 376 | ||
372 | for (i=0; i<100; i++) { | 377 | for (i = 0; i < 100; i++) { |
373 | cur_freq = extract_freq(get_cur_val(mask), data); | 378 | cur_freq = extract_freq(get_cur_val(mask), data); |
374 | if (cur_freq == freq) | 379 | if (cur_freq == freq) |
375 | return 1; | 380 | return 1; |
@@ -494,7 +499,7 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | |||
494 | unsigned long freq; | 499 | unsigned long freq; |
495 | unsigned long freqn = perf->states[0].core_frequency * 1000; | 500 | unsigned long freqn = perf->states[0].core_frequency * 1000; |
496 | 501 | ||
497 | for (i=0; i<(perf->state_count-1); i++) { | 502 | for (i = 0; i < (perf->state_count-1); i++) { |
498 | freq = freqn; | 503 | freq = freqn; |
499 | freqn = perf->states[i+1].core_frequency * 1000; | 504 | freqn = perf->states[i+1].core_frequency * 1000; |
500 | if ((2 * cpu_khz) > (freqn + freq)) { | 505 | if ((2 * cpu_khz) > (freqn + freq)) { |
@@ -673,17 +678,29 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
673 | 678 | ||
674 | /* detect transition latency */ | 679 | /* detect transition latency */ |
675 | policy->cpuinfo.transition_latency = 0; | 680 | policy->cpuinfo.transition_latency = 0; |
676 | for (i=0; i<perf->state_count; i++) { | 681 | for (i = 0; i < perf->state_count; i++) { |
677 | if ((perf->states[i].transition_latency * 1000) > | 682 | if ((perf->states[i].transition_latency * 1000) > |
678 | policy->cpuinfo.transition_latency) | 683 | policy->cpuinfo.transition_latency) |
679 | policy->cpuinfo.transition_latency = | 684 | policy->cpuinfo.transition_latency = |
680 | perf->states[i].transition_latency * 1000; | 685 | perf->states[i].transition_latency * 1000; |
681 | } | 686 | } |
682 | 687 | ||
688 | /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */ | ||
689 | if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && | ||
690 | policy->cpuinfo.transition_latency > 20 * 1000) { | ||
691 | static int print_once; | ||
692 | policy->cpuinfo.transition_latency = 20 * 1000; | ||
693 | if (!print_once) { | ||
694 | print_once = 1; | ||
695 | printk(KERN_INFO "Capping off P-state tranision latency" | ||
696 | " at 20 uS\n"); | ||
697 | } | ||
698 | } | ||
699 | |||
683 | data->max_freq = perf->states[0].core_frequency * 1000; | 700 | data->max_freq = perf->states[0].core_frequency * 1000; |
684 | /* table init */ | 701 | /* table init */ |
685 | for (i=0; i<perf->state_count; i++) { | 702 | for (i = 0; i < perf->state_count; i++) { |
686 | if (i>0 && perf->states[i].core_frequency >= | 703 | if (i > 0 && perf->states[i].core_frequency >= |
687 | data->freq_table[valid_states-1].frequency / 1000) | 704 | data->freq_table[valid_states-1].frequency / 1000) |
688 | continue; | 705 | continue; |
689 | 706 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c index 965ea52767ac..733093d60436 100644 --- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * nforce2_chipset: | 32 | * nforce2_chipset: |
33 | * FSB is changed using the chipset | 33 | * FSB is changed using the chipset |
34 | */ | 34 | */ |
35 | static struct pci_dev *nforce2_chipset_dev; | 35 | static struct pci_dev *nforce2_dev; |
36 | 36 | ||
37 | /* fid: | 37 | /* fid: |
38 | * multiplier * 10 | 38 | * multiplier * 10 |
@@ -56,7 +56,9 @@ MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)"); | |||
56 | MODULE_PARM_DESC(min_fsb, | 56 | MODULE_PARM_DESC(min_fsb, |
57 | "Minimum FSB to use, if not defined: current FSB - 50"); | 57 | "Minimum FSB to use, if not defined: current FSB - 50"); |
58 | 58 | ||
59 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg) | 59 | #define PFX "cpufreq-nforce2: " |
60 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ | ||
61 | "cpufreq-nforce2", msg) | ||
60 | 62 | ||
61 | /** | 63 | /** |
62 | * nforce2_calc_fsb - calculate FSB | 64 | * nforce2_calc_fsb - calculate FSB |
@@ -118,11 +120,11 @@ static void nforce2_write_pll(int pll) | |||
118 | int temp; | 120 | int temp; |
119 | 121 | ||
120 | /* Set the pll addr. to 0x00 */ | 122 | /* Set the pll addr. to 0x00 */ |
121 | pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0); | 123 | pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0); |
122 | 124 | ||
123 | /* Now write the value in all 64 registers */ | 125 | /* Now write the value in all 64 registers */ |
124 | for (temp = 0; temp <= 0x3f; temp++) | 126 | for (temp = 0; temp <= 0x3f; temp++) |
125 | pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll); | 127 | pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll); |
126 | 128 | ||
127 | return; | 129 | return; |
128 | } | 130 | } |
@@ -139,8 +141,8 @@ static unsigned int nforce2_fsb_read(int bootfsb) | |||
139 | u32 fsb, temp = 0; | 141 | u32 fsb, temp = 0; |
140 | 142 | ||
141 | /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ | 143 | /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ |
142 | nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, | 144 | nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF, |
143 | 0x01EF, PCI_ANY_ID, PCI_ANY_ID, NULL); | 145 | PCI_ANY_ID, PCI_ANY_ID, NULL); |
144 | if (!nforce2_sub5) | 146 | if (!nforce2_sub5) |
145 | return 0; | 147 | return 0; |
146 | 148 | ||
@@ -148,13 +150,13 @@ static unsigned int nforce2_fsb_read(int bootfsb) | |||
148 | fsb /= 1000000; | 150 | fsb /= 1000000; |
149 | 151 | ||
150 | /* Check if PLL register is already set */ | 152 | /* Check if PLL register is already set */ |
151 | pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp); | 153 | pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp); |
152 | 154 | ||
153 | if (bootfsb || !temp) | 155 | if (bootfsb || !temp) |
154 | return fsb; | 156 | return fsb; |
155 | 157 | ||
156 | /* Use PLL register FSB value */ | 158 | /* Use PLL register FSB value */ |
157 | pci_read_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, &temp); | 159 | pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp); |
158 | fsb = nforce2_calc_fsb(temp); | 160 | fsb = nforce2_calc_fsb(temp); |
159 | 161 | ||
160 | return fsb; | 162 | return fsb; |
@@ -174,18 +176,18 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
174 | int pll = 0; | 176 | int pll = 0; |
175 | 177 | ||
176 | if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { | 178 | if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { |
177 | printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); | 179 | printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb); |
178 | return -EINVAL; | 180 | return -EINVAL; |
179 | } | 181 | } |
180 | 182 | ||
181 | tfsb = nforce2_fsb_read(0); | 183 | tfsb = nforce2_fsb_read(0); |
182 | if (!tfsb) { | 184 | if (!tfsb) { |
183 | printk(KERN_ERR "cpufreq: Error while reading the FSB\n"); | 185 | printk(KERN_ERR PFX "Error while reading the FSB\n"); |
184 | return -EINVAL; | 186 | return -EINVAL; |
185 | } | 187 | } |
186 | 188 | ||
187 | /* First write? Then set actual value */ | 189 | /* First write? Then set actual value */ |
188 | pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp); | 190 | pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp); |
189 | if (!temp) { | 191 | if (!temp) { |
190 | pll = nforce2_calc_pll(tfsb); | 192 | pll = nforce2_calc_pll(tfsb); |
191 | 193 | ||
@@ -197,7 +199,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
197 | 199 | ||
198 | /* Enable write access */ | 200 | /* Enable write access */ |
199 | temp = 0x01; | 201 | temp = 0x01; |
200 | pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp); | 202 | pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp); |
201 | 203 | ||
202 | diff = tfsb - fsb; | 204 | diff = tfsb - fsb; |
203 | 205 | ||
@@ -222,7 +224,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
222 | } | 224 | } |
223 | 225 | ||
224 | temp = 0x40; | 226 | temp = 0x40; |
225 | pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp); | 227 | pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp); |
226 | 228 | ||
227 | return 0; | 229 | return 0; |
228 | } | 230 | } |
@@ -244,7 +246,8 @@ static unsigned int nforce2_get(unsigned int cpu) | |||
244 | * nforce2_target - set a new CPUFreq policy | 246 | * nforce2_target - set a new CPUFreq policy |
245 | * @policy: new policy | 247 | * @policy: new policy |
246 | * @target_freq: the target frequency | 248 | * @target_freq: the target frequency |
247 | * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | 249 | * @relation: how that frequency relates to achieved frequency |
250 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
248 | * | 251 | * |
249 | * Sets a new CPUFreq policy. | 252 | * Sets a new CPUFreq policy. |
250 | */ | 253 | */ |
@@ -276,7 +279,7 @@ static int nforce2_target(struct cpufreq_policy *policy, | |||
276 | /* local_irq_save(flags); */ | 279 | /* local_irq_save(flags); */ |
277 | 280 | ||
278 | if (nforce2_set_fsb(target_fsb) < 0) | 281 | if (nforce2_set_fsb(target_fsb) < 0) |
279 | printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n", | 282 | printk(KERN_ERR PFX "Changing FSB to %d failed\n", |
280 | target_fsb); | 283 | target_fsb); |
281 | else | 284 | else |
282 | dprintk("Changed FSB successfully to %d\n", | 285 | dprintk("Changed FSB successfully to %d\n", |
@@ -327,8 +330,8 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) | |||
327 | /* FIX: Get FID from CPU */ | 330 | /* FIX: Get FID from CPU */ |
328 | if (!fid) { | 331 | if (!fid) { |
329 | if (!cpu_khz) { | 332 | if (!cpu_khz) { |
330 | printk(KERN_WARNING | 333 | printk(KERN_WARNING PFX |
331 | "cpufreq: cpu_khz not set, can't calculate multiplier!\n"); | 334 | "cpu_khz not set, can't calculate multiplier!\n"); |
332 | return -ENODEV; | 335 | return -ENODEV; |
333 | } | 336 | } |
334 | 337 | ||
@@ -343,7 +346,7 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) | |||
343 | } | 346 | } |
344 | } | 347 | } |
345 | 348 | ||
346 | printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb, | 349 | printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb, |
347 | fid / 10, fid % 10); | 350 | fid / 10, fid % 10); |
348 | 351 | ||
349 | /* Set maximum FSB to FSB at boot time */ | 352 | /* Set maximum FSB to FSB at boot time */ |
@@ -392,17 +395,18 @@ static struct cpufreq_driver nforce2_driver = { | |||
392 | */ | 395 | */ |
393 | static unsigned int nforce2_detect_chipset(void) | 396 | static unsigned int nforce2_detect_chipset(void) |
394 | { | 397 | { |
395 | nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, | 398 | nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, |
396 | PCI_DEVICE_ID_NVIDIA_NFORCE2, | 399 | PCI_DEVICE_ID_NVIDIA_NFORCE2, |
397 | PCI_ANY_ID, PCI_ANY_ID, NULL); | 400 | PCI_ANY_ID, PCI_ANY_ID, NULL); |
398 | 401 | ||
399 | if (nforce2_chipset_dev == NULL) | 402 | if (nforce2_dev == NULL) |
400 | return -ENODEV; | 403 | return -ENODEV; |
401 | 404 | ||
402 | printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n", | 405 | printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n", |
403 | nforce2_chipset_dev->revision); | 406 | nforce2_dev->revision); |
404 | printk(KERN_INFO | 407 | printk(KERN_INFO PFX |
405 | "cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n"); | 408 | "FSB changing is maybe unstable and can lead to " |
409 | "crashes and data loss.\n"); | ||
406 | 410 | ||
407 | return 0; | 411 | return 0; |
408 | } | 412 | } |
@@ -420,7 +424,7 @@ static int __init nforce2_init(void) | |||
420 | 424 | ||
421 | /* detect chipset */ | 425 | /* detect chipset */ |
422 | if (nforce2_detect_chipset()) { | 426 | if (nforce2_detect_chipset()) { |
423 | printk(KERN_ERR "cpufreq: No nForce2 chipset.\n"); | 427 | printk(KERN_INFO PFX "No nForce2 chipset.\n"); |
424 | return -ENODEV; | 428 | return -ENODEV; |
425 | } | 429 | } |
426 | 430 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index 41ab3f064cb1..35a257dd4bb7 100644 --- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c | |||
@@ -12,12 +12,12 @@ | |||
12 | #include <linux/cpufreq.h> | 12 | #include <linux/cpufreq.h> |
13 | #include <linux/ioport.h> | 13 | #include <linux/ioport.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/timex.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
15 | 18 | ||
16 | #include <asm/msr.h> | 19 | #include <asm/msr.h> |
17 | #include <asm/tsc.h> | 20 | #include <asm/tsc.h> |
18 | #include <asm/timex.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/delay.h> | ||
21 | 21 | ||
22 | #define EPS_BRAND_C7M 0 | 22 | #define EPS_BRAND_C7M 0 |
23 | #define EPS_BRAND_C7 1 | 23 | #define EPS_BRAND_C7 1 |
@@ -184,7 +184,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
184 | break; | 184 | break; |
185 | } | 185 | } |
186 | 186 | ||
187 | switch(brand) { | 187 | switch (brand) { |
188 | case EPS_BRAND_C7M: | 188 | case EPS_BRAND_C7M: |
189 | printk(KERN_CONT "C7-M\n"); | 189 | printk(KERN_CONT "C7-M\n"); |
190 | break; | 190 | break; |
@@ -218,17 +218,20 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
218 | /* Print voltage and multiplier */ | 218 | /* Print voltage and multiplier */ |
219 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 219 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
220 | current_voltage = lo & 0xff; | 220 | current_voltage = lo & 0xff; |
221 | printk(KERN_INFO "eps: Current voltage = %dmV\n", current_voltage * 16 + 700); | 221 | printk(KERN_INFO "eps: Current voltage = %dmV\n", |
222 | current_voltage * 16 + 700); | ||
222 | current_multiplier = (lo >> 8) & 0xff; | 223 | current_multiplier = (lo >> 8) & 0xff; |
223 | printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); | 224 | printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); |
224 | 225 | ||
225 | /* Print limits */ | 226 | /* Print limits */ |
226 | max_voltage = hi & 0xff; | 227 | max_voltage = hi & 0xff; |
227 | printk(KERN_INFO "eps: Highest voltage = %dmV\n", max_voltage * 16 + 700); | 228 | printk(KERN_INFO "eps: Highest voltage = %dmV\n", |
229 | max_voltage * 16 + 700); | ||
228 | max_multiplier = (hi >> 8) & 0xff; | 230 | max_multiplier = (hi >> 8) & 0xff; |
229 | printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier); | 231 | printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier); |
230 | min_voltage = (hi >> 16) & 0xff; | 232 | min_voltage = (hi >> 16) & 0xff; |
231 | printk(KERN_INFO "eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700); | 233 | printk(KERN_INFO "eps: Lowest voltage = %dmV\n", |
234 | min_voltage * 16 + 700); | ||
232 | min_multiplier = (hi >> 24) & 0xff; | 235 | min_multiplier = (hi >> 24) & 0xff; |
233 | printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier); | 236 | printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier); |
234 | 237 | ||
@@ -318,7 +321,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy) | |||
318 | return 0; | 321 | return 0; |
319 | } | 322 | } |
320 | 323 | ||
321 | static struct freq_attr* eps_attr[] = { | 324 | static struct freq_attr *eps_attr[] = { |
322 | &cpufreq_freq_attr_scaling_available_freqs, | 325 | &cpufreq_freq_attr_scaling_available_freqs, |
323 | NULL, | 326 | NULL, |
324 | }; | 327 | }; |
@@ -356,7 +359,7 @@ static void __exit eps_exit(void) | |||
356 | cpufreq_unregister_driver(&eps_driver); | 359 | cpufreq_unregister_driver(&eps_driver); |
357 | } | 360 | } |
358 | 361 | ||
359 | MODULE_AUTHOR("Rafa³ Bilski <rafalbilski@interia.pl>"); | 362 | MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>"); |
360 | MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's."); | 363 | MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's."); |
361 | MODULE_LICENSE("GPL"); | 364 | MODULE_LICENSE("GPL"); |
362 | 365 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index fe613c93b366..006b278b0d5d 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c | |||
@@ -184,7 +184,8 @@ static int elanfreq_target(struct cpufreq_policy *policy, | |||
184 | { | 184 | { |
185 | unsigned int newstate = 0; | 185 | unsigned int newstate = 0; |
186 | 186 | ||
187 | if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate)) | 187 | if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], |
188 | target_freq, relation, &newstate)) | ||
188 | return -EINVAL; | 189 | return -EINVAL; |
189 | 190 | ||
190 | elanfreq_set_cpu_state(newstate); | 191 | elanfreq_set_cpu_state(newstate); |
@@ -301,7 +302,8 @@ static void __exit elanfreq_exit(void) | |||
301 | module_param(max_freq, int, 0444); | 302 | module_param(max_freq, int, 0444); |
302 | 303 | ||
303 | MODULE_LICENSE("GPL"); | 304 | MODULE_LICENSE("GPL"); |
304 | MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>"); | 305 | MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, " |
306 | "Sven Geggus <sven@geggus.net>"); | ||
305 | MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); | 307 | MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); |
306 | 308 | ||
307 | module_init(elanfreq_init); | 309 | module_init(elanfreq_init); |
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index 9d9eae82e60f..ac27ec2264d5 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c | |||
@@ -79,8 +79,9 @@ | |||
79 | #include <linux/smp.h> | 79 | #include <linux/smp.h> |
80 | #include <linux/cpufreq.h> | 80 | #include <linux/cpufreq.h> |
81 | #include <linux/pci.h> | 81 | #include <linux/pci.h> |
82 | #include <linux/errno.h> | ||
83 | |||
82 | #include <asm/processor-cyrix.h> | 84 | #include <asm/processor-cyrix.h> |
83 | #include <asm/errno.h> | ||
84 | 85 | ||
85 | /* PCI config registers, all at F0 */ | 86 | /* PCI config registers, all at F0 */ |
86 | #define PCI_PMER1 0x80 /* power management enable register 1 */ | 87 | #define PCI_PMER1 0x80 /* power management enable register 1 */ |
@@ -122,8 +123,8 @@ static struct gxfreq_params *gx_params; | |||
122 | static int stock_freq; | 123 | static int stock_freq; |
123 | 124 | ||
124 | /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ | 125 | /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ |
125 | static int pci_busclk = 0; | 126 | static int pci_busclk; |
126 | module_param (pci_busclk, int, 0444); | 127 | module_param(pci_busclk, int, 0444); |
127 | 128 | ||
128 | /* maximum duration for which the cpu may be suspended | 129 | /* maximum duration for which the cpu may be suspended |
129 | * (32us * MAX_DURATION). If no parameter is given, this defaults | 130 | * (32us * MAX_DURATION). If no parameter is given, this defaults |
@@ -132,7 +133,7 @@ module_param (pci_busclk, int, 0444); | |||
132 | * is suspended -- processing power is just 0.39% of what it used to be, | 133 | * is suspended -- processing power is just 0.39% of what it used to be, |
133 | * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ | 134 | * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ |
134 | static int max_duration = 255; | 135 | static int max_duration = 255; |
135 | module_param (max_duration, int, 0444); | 136 | module_param(max_duration, int, 0444); |
136 | 137 | ||
137 | /* For the default policy, we want at least some processing power | 138 | /* For the default policy, we want at least some processing power |
138 | * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV) | 139 | * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV) |
@@ -140,7 +141,8 @@ module_param (max_duration, int, 0444); | |||
140 | #define POLICY_MIN_DIV 20 | 141 | #define POLICY_MIN_DIV 20 |
141 | 142 | ||
142 | 143 | ||
143 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) | 144 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
145 | "gx-suspmod", msg) | ||
144 | 146 | ||
145 | /** | 147 | /** |
146 | * we can detect a core multipiler from dir0_lsb | 148 | * we can detect a core multipiler from dir0_lsb |
@@ -166,12 +168,20 @@ static int gx_freq_mult[16] = { | |||
166 | * Low Level chipset interface * | 168 | * Low Level chipset interface * |
167 | ****************************************************************/ | 169 | ****************************************************************/ |
168 | static struct pci_device_id gx_chipset_tbl[] __initdata = { | 170 | static struct pci_device_id gx_chipset_tbl[] __initdata = { |
169 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, | 171 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, |
170 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, | 172 | PCI_ANY_ID, PCI_ANY_ID }, |
171 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, | 173 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, |
174 | PCI_ANY_ID, PCI_ANY_ID }, | ||
175 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, | ||
176 | PCI_ANY_ID, PCI_ANY_ID }, | ||
172 | { 0, }, | 177 | { 0, }, |
173 | }; | 178 | }; |
174 | 179 | ||
180 | static void gx_write_byte(int reg, int value) | ||
181 | { | ||
182 | pci_write_config_byte(gx_params->cs55x0, reg, value); | ||
183 | } | ||
184 | |||
175 | /** | 185 | /** |
176 | * gx_detect_chipset: | 186 | * gx_detect_chipset: |
177 | * | 187 | * |
@@ -200,7 +210,8 @@ static __init struct pci_dev *gx_detect_chipset(void) | |||
200 | /** | 210 | /** |
201 | * gx_get_cpuspeed: | 211 | * gx_get_cpuspeed: |
202 | * | 212 | * |
203 | * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. | 213 | * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi |
214 | * Geode CPU runs. | ||
204 | */ | 215 | */ |
205 | static unsigned int gx_get_cpuspeed(unsigned int cpu) | 216 | static unsigned int gx_get_cpuspeed(unsigned int cpu) |
206 | { | 217 | { |
@@ -217,17 +228,18 @@ static unsigned int gx_get_cpuspeed(unsigned int cpu) | |||
217 | * | 228 | * |
218 | **/ | 229 | **/ |
219 | 230 | ||
220 | static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) | 231 | static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, |
232 | u8 *off_duration) | ||
221 | { | 233 | { |
222 | unsigned int i; | 234 | unsigned int i; |
223 | u8 tmp_on, tmp_off; | 235 | u8 tmp_on, tmp_off; |
224 | int old_tmp_freq = stock_freq; | 236 | int old_tmp_freq = stock_freq; |
225 | int tmp_freq; | 237 | int tmp_freq; |
226 | 238 | ||
227 | *off_duration=1; | 239 | *off_duration = 1; |
228 | *on_duration=0; | 240 | *on_duration = 0; |
229 | 241 | ||
230 | for (i=max_duration; i>0; i--) { | 242 | for (i = max_duration; i > 0; i--) { |
231 | tmp_off = ((khz * i) / stock_freq) & 0xff; | 243 | tmp_off = ((khz * i) / stock_freq) & 0xff; |
232 | tmp_on = i - tmp_off; | 244 | tmp_on = i - tmp_off; |
233 | tmp_freq = (stock_freq * tmp_off) / i; | 245 | tmp_freq = (stock_freq * tmp_off) / i; |
@@ -259,26 +271,34 @@ static void gx_set_cpuspeed(unsigned int khz) | |||
259 | freqs.cpu = 0; | 271 | freqs.cpu = 0; |
260 | freqs.old = gx_get_cpuspeed(0); | 272 | freqs.old = gx_get_cpuspeed(0); |
261 | 273 | ||
262 | new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); | 274 | new_khz = gx_validate_speed(khz, &gx_params->on_duration, |
275 | &gx_params->off_duration); | ||
263 | 276 | ||
264 | freqs.new = new_khz; | 277 | freqs.new = new_khz; |
265 | 278 | ||
266 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 279 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
267 | local_irq_save(flags); | 280 | local_irq_save(flags); |
268 | 281 | ||
269 | if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ | 282 | |
283 | |||
284 | if (new_khz != stock_freq) { | ||
285 | /* if new khz == 100% of CPU speed, it is special case */ | ||
270 | switch (gx_params->cs55x0->device) { | 286 | switch (gx_params->cs55x0->device) { |
271 | case PCI_DEVICE_ID_CYRIX_5530_LEGACY: | 287 | case PCI_DEVICE_ID_CYRIX_5530_LEGACY: |
272 | pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; | 288 | pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; |
273 | /* FIXME: need to test other values -- Zwane,Miura */ | 289 | /* FIXME: need to test other values -- Zwane,Miura */ |
274 | pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */ | 290 | /* typical 2 to 4ms */ |
275 | pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */ | 291 | gx_write_byte(PCI_IRQTC, 4); |
276 | pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1); | 292 | /* typical 50 to 100ms */ |
277 | 293 | gx_write_byte(PCI_VIDTC, 100); | |
278 | if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */ | 294 | gx_write_byte(PCI_PMER1, pmer1); |
279 | suscfg = gx_params->pci_suscfg | SUSMOD; | 295 | |
280 | } else { /* CS5530A,B.. */ | 296 | if (gx_params->cs55x0->revision < 0x10) { |
281 | suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE; | 297 | /* CS5530(rev 1.2, 1.3) */ |
298 | suscfg = gx_params->pci_suscfg|SUSMOD; | ||
299 | } else { | ||
300 | /* CS5530A,B.. */ | ||
301 | suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; | ||
282 | } | 302 | } |
283 | break; | 303 | break; |
284 | case PCI_DEVICE_ID_CYRIX_5520: | 304 | case PCI_DEVICE_ID_CYRIX_5520: |
@@ -294,13 +314,13 @@ static void gx_set_cpuspeed(unsigned int khz) | |||
294 | suscfg = gx_params->pci_suscfg & ~(SUSMOD); | 314 | suscfg = gx_params->pci_suscfg & ~(SUSMOD); |
295 | gx_params->off_duration = 0; | 315 | gx_params->off_duration = 0; |
296 | gx_params->on_duration = 0; | 316 | gx_params->on_duration = 0; |
297 | dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n"); | 317 | dprintk("suspend modulation disabled: cpu runs 100%% speed.\n"); |
298 | } | 318 | } |
299 | 319 | ||
300 | pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); | 320 | gx_write_byte(PCI_MODOFF, gx_params->off_duration); |
301 | pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); | 321 | gx_write_byte(PCI_MODON, gx_params->on_duration); |
302 | 322 | ||
303 | pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); | 323 | gx_write_byte(PCI_SUSCFG, suscfg); |
304 | pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); | 324 | pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); |
305 | 325 | ||
306 | local_irq_restore(flags); | 326 | local_irq_restore(flags); |
@@ -334,7 +354,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) | |||
334 | return -EINVAL; | 354 | return -EINVAL; |
335 | 355 | ||
336 | policy->cpu = 0; | 356 | policy->cpu = 0; |
337 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); | 357 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), |
358 | stock_freq); | ||
338 | 359 | ||
339 | /* it needs to be assured that at least one supported frequency is | 360 | /* it needs to be assured that at least one supported frequency is |
340 | * within policy->min and policy->max. If it is not, policy->max | 361 | * within policy->min and policy->max. If it is not, policy->max |
@@ -354,7 +375,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) | |||
354 | policy->max = tmp_freq; | 375 | policy->max = tmp_freq; |
355 | if (policy->max < policy->min) | 376 | if (policy->max < policy->min) |
356 | policy->max = policy->min; | 377 | policy->max = policy->min; |
357 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); | 378 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), |
379 | stock_freq); | ||
358 | 380 | ||
359 | return 0; | 381 | return 0; |
360 | } | 382 | } |
@@ -398,18 +420,18 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) | |||
398 | return -ENODEV; | 420 | return -ENODEV; |
399 | 421 | ||
400 | /* determine maximum frequency */ | 422 | /* determine maximum frequency */ |
401 | if (pci_busclk) { | 423 | if (pci_busclk) |
402 | maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; | 424 | maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; |
403 | } else if (cpu_khz) { | 425 | else if (cpu_khz) |
404 | maxfreq = cpu_khz; | 426 | maxfreq = cpu_khz; |
405 | } else { | 427 | else |
406 | maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; | 428 | maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; |
407 | } | 429 | |
408 | stock_freq = maxfreq; | 430 | stock_freq = maxfreq; |
409 | curfreq = gx_get_cpuspeed(0); | 431 | curfreq = gx_get_cpuspeed(0); |
410 | 432 | ||
411 | dprintk("cpu max frequency is %d.\n", maxfreq); | 433 | dprintk("cpu max frequency is %d.\n", maxfreq); |
412 | dprintk("cpu current frequency is %dkHz.\n",curfreq); | 434 | dprintk("cpu current frequency is %dkHz.\n", curfreq); |
413 | 435 | ||
414 | /* setup basic struct for cpufreq API */ | 436 | /* setup basic struct for cpufreq API */ |
415 | policy->cpu = 0; | 437 | policy->cpu = 0; |
@@ -447,7 +469,8 @@ static int __init cpufreq_gx_init(void) | |||
447 | struct pci_dev *gx_pci; | 469 | struct pci_dev *gx_pci; |
448 | 470 | ||
449 | /* Test if we have the right hardware */ | 471 | /* Test if we have the right hardware */ |
450 | if ((gx_pci = gx_detect_chipset()) == NULL) | 472 | gx_pci = gx_detect_chipset(); |
473 | if (gx_pci == NULL) | ||
451 | return -ENODEV; | 474 | return -ENODEV; |
452 | 475 | ||
453 | /* check whether module parameters are sane */ | 476 | /* check whether module parameters are sane */ |
@@ -468,9 +491,11 @@ static int __init cpufreq_gx_init(void) | |||
468 | pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); | 491 | pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); |
469 | pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); | 492 | pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); |
470 | pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); | 493 | pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); |
471 | pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); | 494 | pci_read_config_byte(params->cs55x0, PCI_MODOFF, |
495 | &(params->off_duration)); | ||
472 | 496 | ||
473 | if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { | 497 | ret = cpufreq_register_driver(&gx_suspmod_driver); |
498 | if (ret) { | ||
474 | kfree(params); | 499 | kfree(params); |
475 | return ret; /* register error! */ | 500 | return ret; /* register error! */ |
476 | } | 501 | } |
@@ -485,9 +510,9 @@ static void __exit cpufreq_gx_exit(void) | |||
485 | kfree(gx_params); | 510 | kfree(gx_params); |
486 | } | 511 | } |
487 | 512 | ||
488 | MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>"); | 513 | MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>"); |
489 | MODULE_DESCRIPTION ("Cpufreq driver for Cyrix MediaGX and NatSemi Geode"); | 514 | MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode"); |
490 | MODULE_LICENSE ("GPL"); | 515 | MODULE_LICENSE("GPL"); |
491 | 516 | ||
492 | module_init(cpufreq_gx_init); | 517 | module_init(cpufreq_gx_init); |
493 | module_exit(cpufreq_gx_exit); | 518 | module_exit(cpufreq_gx_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index a4cff5d6e380..ce2ed3e4aad9 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c | |||
@@ -30,12 +30,11 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/timex.h> | ||
34 | #include <linux/io.h> | ||
35 | #include <linux/acpi.h> | ||
33 | 36 | ||
34 | #include <asm/msr.h> | 37 | #include <asm/msr.h> |
35 | #include <asm/timex.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/acpi.h> | ||
38 | #include <linux/acpi.h> | ||
39 | #include <acpi/processor.h> | 38 | #include <acpi/processor.h> |
40 | 39 | ||
41 | #include "longhaul.h" | 40 | #include "longhaul.h" |
@@ -58,7 +57,7 @@ | |||
58 | #define USE_NORTHBRIDGE (1 << 2) | 57 | #define USE_NORTHBRIDGE (1 << 2) |
59 | 58 | ||
60 | static int cpu_model; | 59 | static int cpu_model; |
61 | static unsigned int numscales=16; | 60 | static unsigned int numscales = 16; |
62 | static unsigned int fsb; | 61 | static unsigned int fsb; |
63 | 62 | ||
64 | static const struct mV_pos *vrm_mV_table; | 63 | static const struct mV_pos *vrm_mV_table; |
@@ -67,8 +66,8 @@ static const unsigned char *mV_vrm_table; | |||
67 | static unsigned int highest_speed, lowest_speed; /* kHz */ | 66 | static unsigned int highest_speed, lowest_speed; /* kHz */ |
68 | static unsigned int minmult, maxmult; | 67 | static unsigned int minmult, maxmult; |
69 | static int can_scale_voltage; | 68 | static int can_scale_voltage; |
70 | static struct acpi_processor *pr = NULL; | 69 | static struct acpi_processor *pr; |
71 | static struct acpi_processor_cx *cx = NULL; | 70 | static struct acpi_processor_cx *cx; |
72 | static u32 acpi_regs_addr; | 71 | static u32 acpi_regs_addr; |
73 | static u8 longhaul_flags; | 72 | static u8 longhaul_flags; |
74 | static unsigned int longhaul_index; | 73 | static unsigned int longhaul_index; |
@@ -78,12 +77,13 @@ static int scale_voltage; | |||
78 | static int disable_acpi_c3; | 77 | static int disable_acpi_c3; |
79 | static int revid_errata; | 78 | static int revid_errata; |
80 | 79 | ||
81 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) | 80 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
81 | "longhaul", msg) | ||
82 | 82 | ||
83 | 83 | ||
84 | /* Clock ratios multiplied by 10 */ | 84 | /* Clock ratios multiplied by 10 */ |
85 | static int clock_ratio[32]; | 85 | static int mults[32]; |
86 | static int eblcr_table[32]; | 86 | static int eblcr[32]; |
87 | static int longhaul_version; | 87 | static int longhaul_version; |
88 | static struct cpufreq_frequency_table *longhaul_table; | 88 | static struct cpufreq_frequency_table *longhaul_table; |
89 | 89 | ||
@@ -93,7 +93,7 @@ static char speedbuffer[8]; | |||
93 | static char *print_speed(int speed) | 93 | static char *print_speed(int speed) |
94 | { | 94 | { |
95 | if (speed < 1000) { | 95 | if (speed < 1000) { |
96 | snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed); | 96 | snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed); |
97 | return speedbuffer; | 97 | return speedbuffer; |
98 | } | 98 | } |
99 | 99 | ||
@@ -122,27 +122,28 @@ static unsigned int calc_speed(int mult) | |||
122 | 122 | ||
123 | static int longhaul_get_cpu_mult(void) | 123 | static int longhaul_get_cpu_mult(void) |
124 | { | 124 | { |
125 | unsigned long invalue=0,lo, hi; | 125 | unsigned long invalue = 0, lo, hi; |
126 | 126 | ||
127 | rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); | 127 | rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi); |
128 | invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22; | 128 | invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22; |
129 | if (longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) { | 129 | if (longhaul_version == TYPE_LONGHAUL_V2 || |
130 | longhaul_version == TYPE_POWERSAVER) { | ||
130 | if (lo & (1<<27)) | 131 | if (lo & (1<<27)) |
131 | invalue+=16; | 132 | invalue += 16; |
132 | } | 133 | } |
133 | return eblcr_table[invalue]; | 134 | return eblcr[invalue]; |
134 | } | 135 | } |
135 | 136 | ||
136 | /* For processor with BCR2 MSR */ | 137 | /* For processor with BCR2 MSR */ |
137 | 138 | ||
138 | static void do_longhaul1(unsigned int clock_ratio_index) | 139 | static void do_longhaul1(unsigned int mults_index) |
139 | { | 140 | { |
140 | union msr_bcr2 bcr2; | 141 | union msr_bcr2 bcr2; |
141 | 142 | ||
142 | rdmsrl(MSR_VIA_BCR2, bcr2.val); | 143 | rdmsrl(MSR_VIA_BCR2, bcr2.val); |
143 | /* Enable software clock multiplier */ | 144 | /* Enable software clock multiplier */ |
144 | bcr2.bits.ESOFTBF = 1; | 145 | bcr2.bits.ESOFTBF = 1; |
145 | bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff; | 146 | bcr2.bits.CLOCKMUL = mults_index & 0xff; |
146 | 147 | ||
147 | /* Sync to timer tick */ | 148 | /* Sync to timer tick */ |
148 | safe_halt(); | 149 | safe_halt(); |
@@ -161,7 +162,7 @@ static void do_longhaul1(unsigned int clock_ratio_index) | |||
161 | 162 | ||
162 | /* For processor with Longhaul MSR */ | 163 | /* For processor with Longhaul MSR */ |
163 | 164 | ||
164 | static void do_powersaver(int cx_address, unsigned int clock_ratio_index, | 165 | static void do_powersaver(int cx_address, unsigned int mults_index, |
165 | unsigned int dir) | 166 | unsigned int dir) |
166 | { | 167 | { |
167 | union msr_longhaul longhaul; | 168 | union msr_longhaul longhaul; |
@@ -173,11 +174,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index, | |||
173 | longhaul.bits.RevisionKey = longhaul.bits.RevisionID; | 174 | longhaul.bits.RevisionKey = longhaul.bits.RevisionID; |
174 | else | 175 | else |
175 | longhaul.bits.RevisionKey = 0; | 176 | longhaul.bits.RevisionKey = 0; |
176 | longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; | 177 | longhaul.bits.SoftBusRatio = mults_index & 0xf; |
177 | longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; | 178 | longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4; |
178 | /* Setup new voltage */ | 179 | /* Setup new voltage */ |
179 | if (can_scale_voltage) | 180 | if (can_scale_voltage) |
180 | longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f; | 181 | longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f; |
181 | /* Sync to timer tick */ | 182 | /* Sync to timer tick */ |
182 | safe_halt(); | 183 | safe_halt(); |
183 | /* Raise voltage if necessary */ | 184 | /* Raise voltage if necessary */ |
@@ -240,14 +241,14 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index, | |||
240 | 241 | ||
241 | /** | 242 | /** |
242 | * longhaul_set_cpu_frequency() | 243 | * longhaul_set_cpu_frequency() |
243 | * @clock_ratio_index : bitpattern of the new multiplier. | 244 | * @mults_index : bitpattern of the new multiplier. |
244 | * | 245 | * |
245 | * Sets a new clock ratio. | 246 | * Sets a new clock ratio. |
246 | */ | 247 | */ |
247 | 248 | ||
248 | static void longhaul_setstate(unsigned int table_index) | 249 | static void longhaul_setstate(unsigned int table_index) |
249 | { | 250 | { |
250 | unsigned int clock_ratio_index; | 251 | unsigned int mults_index; |
251 | int speed, mult; | 252 | int speed, mult; |
252 | struct cpufreq_freqs freqs; | 253 | struct cpufreq_freqs freqs; |
253 | unsigned long flags; | 254 | unsigned long flags; |
@@ -256,9 +257,9 @@ static void longhaul_setstate(unsigned int table_index) | |||
256 | u32 bm_timeout = 1000; | 257 | u32 bm_timeout = 1000; |
257 | unsigned int dir = 0; | 258 | unsigned int dir = 0; |
258 | 259 | ||
259 | clock_ratio_index = longhaul_table[table_index].index; | 260 | mults_index = longhaul_table[table_index].index; |
260 | /* Safety precautions */ | 261 | /* Safety precautions */ |
261 | mult = clock_ratio[clock_ratio_index & 0x1f]; | 262 | mult = mults[mults_index & 0x1f]; |
262 | if (mult == -1) | 263 | if (mult == -1) |
263 | return; | 264 | return; |
264 | speed = calc_speed(mult); | 265 | speed = calc_speed(mult); |
@@ -274,7 +275,7 @@ static void longhaul_setstate(unsigned int table_index) | |||
274 | 275 | ||
275 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 276 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
276 | 277 | ||
277 | dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", | 278 | dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", |
278 | fsb, mult/10, mult%10, print_speed(speed/1000)); | 279 | fsb, mult/10, mult%10, print_speed(speed/1000)); |
279 | retry_loop: | 280 | retry_loop: |
280 | preempt_disable(); | 281 | preempt_disable(); |
@@ -282,8 +283,8 @@ retry_loop: | |||
282 | 283 | ||
283 | pic2_mask = inb(0xA1); | 284 | pic2_mask = inb(0xA1); |
284 | pic1_mask = inb(0x21); /* works on C3. save mask. */ | 285 | pic1_mask = inb(0x21); /* works on C3. save mask. */ |
285 | outb(0xFF,0xA1); /* Overkill */ | 286 | outb(0xFF, 0xA1); /* Overkill */ |
286 | outb(0xFE,0x21); /* TMR0 only */ | 287 | outb(0xFE, 0x21); /* TMR0 only */ |
287 | 288 | ||
288 | /* Wait while PCI bus is busy. */ | 289 | /* Wait while PCI bus is busy. */ |
289 | if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE | 290 | if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE |
@@ -303,7 +304,7 @@ retry_loop: | |||
303 | outb(3, 0x22); | 304 | outb(3, 0x22); |
304 | } else if ((pr != NULL) && pr->flags.bm_control) { | 305 | } else if ((pr != NULL) && pr->flags.bm_control) { |
305 | /* Disable bus master arbitration */ | 306 | /* Disable bus master arbitration */ |
306 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 307 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); |
307 | } | 308 | } |
308 | switch (longhaul_version) { | 309 | switch (longhaul_version) { |
309 | 310 | ||
@@ -312,7 +313,7 @@ retry_loop: | |||
312 | * Software controlled multipliers only. | 313 | * Software controlled multipliers only. |
313 | */ | 314 | */ |
314 | case TYPE_LONGHAUL_V1: | 315 | case TYPE_LONGHAUL_V1: |
315 | do_longhaul1(clock_ratio_index); | 316 | do_longhaul1(mults_index); |
316 | break; | 317 | break; |
317 | 318 | ||
318 | /* | 319 | /* |
@@ -326,10 +327,10 @@ retry_loop: | |||
326 | case TYPE_POWERSAVER: | 327 | case TYPE_POWERSAVER: |
327 | if (longhaul_flags & USE_ACPI_C3) { | 328 | if (longhaul_flags & USE_ACPI_C3) { |
328 | /* Don't allow wakeup */ | 329 | /* Don't allow wakeup */ |
329 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | 330 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0); |
330 | do_powersaver(cx->address, clock_ratio_index, dir); | 331 | do_powersaver(cx->address, mults_index, dir); |
331 | } else { | 332 | } else { |
332 | do_powersaver(0, clock_ratio_index, dir); | 333 | do_powersaver(0, mults_index, dir); |
333 | } | 334 | } |
334 | break; | 335 | break; |
335 | } | 336 | } |
@@ -339,10 +340,10 @@ retry_loop: | |||
339 | outb(0, 0x22); | 340 | outb(0, 0x22); |
340 | } else if ((pr != NULL) && pr->flags.bm_control) { | 341 | } else if ((pr != NULL) && pr->flags.bm_control) { |
341 | /* Enable bus master arbitration */ | 342 | /* Enable bus master arbitration */ |
342 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | 343 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); |
343 | } | 344 | } |
344 | outb(pic2_mask,0xA1); /* restore mask */ | 345 | outb(pic2_mask, 0xA1); /* restore mask */ |
345 | outb(pic1_mask,0x21); | 346 | outb(pic1_mask, 0x21); |
346 | 347 | ||
347 | local_irq_restore(flags); | 348 | local_irq_restore(flags); |
348 | preempt_enable(); | 349 | preempt_enable(); |
@@ -392,7 +393,8 @@ retry_loop: | |||
392 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 393 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
393 | 394 | ||
394 | if (!bm_timeout) | 395 | if (!bm_timeout) |
395 | printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n"); | 396 | printk(KERN_INFO PFX "Warning: Timeout while waiting for " |
397 | "idle PCI bus.\n"); | ||
396 | } | 398 | } |
397 | 399 | ||
398 | /* | 400 | /* |
@@ -458,31 +460,32 @@ static int __init longhaul_get_ranges(void) | |||
458 | break; | 460 | break; |
459 | } | 461 | } |
460 | 462 | ||
461 | dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n", | 463 | dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n", |
462 | minmult/10, minmult%10, maxmult/10, maxmult%10); | 464 | minmult/10, minmult%10, maxmult/10, maxmult%10); |
463 | 465 | ||
464 | highest_speed = calc_speed(maxmult); | 466 | highest_speed = calc_speed(maxmult); |
465 | lowest_speed = calc_speed(minmult); | 467 | lowest_speed = calc_speed(minmult); |
466 | dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, | 468 | dprintk("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, |
467 | print_speed(lowest_speed/1000), | 469 | print_speed(lowest_speed/1000), |
468 | print_speed(highest_speed/1000)); | 470 | print_speed(highest_speed/1000)); |
469 | 471 | ||
470 | if (lowest_speed == highest_speed) { | 472 | if (lowest_speed == highest_speed) { |
471 | printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n"); | 473 | printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n"); |
472 | return -EINVAL; | 474 | return -EINVAL; |
473 | } | 475 | } |
474 | if (lowest_speed > highest_speed) { | 476 | if (lowest_speed > highest_speed) { |
475 | printk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", | 477 | printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", |
476 | lowest_speed, highest_speed); | 478 | lowest_speed, highest_speed); |
477 | return -EINVAL; | 479 | return -EINVAL; |
478 | } | 480 | } |
479 | 481 | ||
480 | longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL); | 482 | longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table), |
481 | if(!longhaul_table) | 483 | GFP_KERNEL); |
484 | if (!longhaul_table) | ||
482 | return -ENOMEM; | 485 | return -ENOMEM; |
483 | 486 | ||
484 | for (j = 0; j < numscales; j++) { | 487 | for (j = 0; j < numscales; j++) { |
485 | ratio = clock_ratio[j]; | 488 | ratio = mults[j]; |
486 | if (ratio == -1) | 489 | if (ratio == -1) |
487 | continue; | 490 | continue; |
488 | if (ratio > maxmult || ratio < minmult) | 491 | if (ratio > maxmult || ratio < minmult) |
@@ -507,13 +510,10 @@ static int __init longhaul_get_ranges(void) | |||
507 | } | 510 | } |
508 | } | 511 | } |
509 | if (min_i != j) { | 512 | if (min_i != j) { |
510 | unsigned int temp; | 513 | swap(longhaul_table[j].frequency, |
511 | temp = longhaul_table[j].frequency; | 514 | longhaul_table[min_i].frequency); |
512 | longhaul_table[j].frequency = longhaul_table[min_i].frequency; | 515 | swap(longhaul_table[j].index, |
513 | longhaul_table[min_i].frequency = temp; | 516 | longhaul_table[min_i].index); |
514 | temp = longhaul_table[j].index; | ||
515 | longhaul_table[j].index = longhaul_table[min_i].index; | ||
516 | longhaul_table[min_i].index = temp; | ||
517 | } | 517 | } |
518 | } | 518 | } |
519 | 519 | ||
@@ -521,7 +521,7 @@ static int __init longhaul_get_ranges(void) | |||
521 | 521 | ||
522 | /* Find index we are running on */ | 522 | /* Find index we are running on */ |
523 | for (j = 0; j < k; j++) { | 523 | for (j = 0; j < k; j++) { |
524 | if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) { | 524 | if (mults[longhaul_table[j].index & 0x1f] == mult) { |
525 | longhaul_index = j; | 525 | longhaul_index = j; |
526 | break; | 526 | break; |
527 | } | 527 | } |
@@ -559,20 +559,22 @@ static void __init longhaul_setup_voltagescaling(void) | |||
559 | maxvid = vrm_mV_table[longhaul.bits.MaximumVID]; | 559 | maxvid = vrm_mV_table[longhaul.bits.MaximumVID]; |
560 | 560 | ||
561 | if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) { | 561 | if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) { |
562 | printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " | 562 | printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " |
563 | "Voltage scaling disabled.\n", | 563 | "Voltage scaling disabled.\n", |
564 | minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000); | 564 | minvid.mV/1000, minvid.mV%1000, |
565 | maxvid.mV/1000, maxvid.mV%1000); | ||
565 | return; | 566 | return; |
566 | } | 567 | } |
567 | 568 | ||
568 | if (minvid.mV == maxvid.mV) { | 569 | if (minvid.mV == maxvid.mV) { |
569 | printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are " | 570 | printk(KERN_INFO PFX "Claims to support voltage scaling but " |
570 | "both %d.%03d. Voltage scaling disabled\n", | 571 | "min & max are both %d.%03d. " |
572 | "Voltage scaling disabled\n", | ||
571 | maxvid.mV/1000, maxvid.mV%1000); | 573 | maxvid.mV/1000, maxvid.mV%1000); |
572 | return; | 574 | return; |
573 | } | 575 | } |
574 | 576 | ||
575 | /* How many voltage steps */ | 577 | /* How many voltage steps*/ |
576 | numvscales = maxvid.pos - minvid.pos + 1; | 578 | numvscales = maxvid.pos - minvid.pos + 1; |
577 | printk(KERN_INFO PFX | 579 | printk(KERN_INFO PFX |
578 | "Max VID=%d.%03d " | 580 | "Max VID=%d.%03d " |
@@ -586,7 +588,7 @@ static void __init longhaul_setup_voltagescaling(void) | |||
586 | j = longhaul.bits.MinMHzBR; | 588 | j = longhaul.bits.MinMHzBR; |
587 | if (longhaul.bits.MinMHzBR4) | 589 | if (longhaul.bits.MinMHzBR4) |
588 | j += 16; | 590 | j += 16; |
589 | min_vid_speed = eblcr_table[j]; | 591 | min_vid_speed = eblcr[j]; |
590 | if (min_vid_speed == -1) | 592 | if (min_vid_speed == -1) |
591 | return; | 593 | return; |
592 | switch (longhaul.bits.MinMHzFSB) { | 594 | switch (longhaul.bits.MinMHzFSB) { |
@@ -617,7 +619,8 @@ static void __init longhaul_setup_voltagescaling(void) | |||
617 | pos = minvid.pos; | 619 | pos = minvid.pos; |
618 | longhaul_table[j].index |= mV_vrm_table[pos] << 8; | 620 | longhaul_table[j].index |= mV_vrm_table[pos] << 8; |
619 | vid = vrm_mV_table[mV_vrm_table[pos]]; | 621 | vid = vrm_mV_table[mV_vrm_table[pos]]; |
620 | printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV); | 622 | printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", |
623 | speed, j, vid.mV); | ||
621 | j++; | 624 | j++; |
622 | } | 625 | } |
623 | 626 | ||
@@ -640,7 +643,8 @@ static int longhaul_target(struct cpufreq_policy *policy, | |||
640 | unsigned int dir = 0; | 643 | unsigned int dir = 0; |
641 | u8 vid, current_vid; | 644 | u8 vid, current_vid; |
642 | 645 | ||
643 | if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index)) | 646 | if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, |
647 | relation, &table_index)) | ||
644 | return -EINVAL; | 648 | return -EINVAL; |
645 | 649 | ||
646 | /* Don't set same frequency again */ | 650 | /* Don't set same frequency again */ |
@@ -656,7 +660,8 @@ static int longhaul_target(struct cpufreq_policy *policy, | |||
656 | * this in hardware, C3 is old and we need to do this | 660 | * this in hardware, C3 is old and we need to do this |
657 | * in software. */ | 661 | * in software. */ |
658 | i = longhaul_index; | 662 | i = longhaul_index; |
659 | current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f; | 663 | current_vid = (longhaul_table[longhaul_index].index >> 8); |
664 | current_vid &= 0x1f; | ||
660 | if (table_index > longhaul_index) | 665 | if (table_index > longhaul_index) |
661 | dir = 1; | 666 | dir = 1; |
662 | while (i != table_index) { | 667 | while (i != table_index) { |
@@ -691,9 +696,9 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle, | |||
691 | { | 696 | { |
692 | struct acpi_device *d; | 697 | struct acpi_device *d; |
693 | 698 | ||
694 | if ( acpi_bus_get_device(obj_handle, &d) ) { | 699 | if (acpi_bus_get_device(obj_handle, &d)) |
695 | return 0; | 700 | return 0; |
696 | } | 701 | |
697 | *return_value = acpi_driver_data(d); | 702 | *return_value = acpi_driver_data(d); |
698 | return 1; | 703 | return 1; |
699 | } | 704 | } |
@@ -750,7 +755,7 @@ static int longhaul_setup_southbridge(void) | |||
750 | /* Find VT8235 southbridge */ | 755 | /* Find VT8235 southbridge */ |
751 | dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); | 756 | dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); |
752 | if (dev == NULL) | 757 | if (dev == NULL) |
753 | /* Find VT8237 southbridge */ | 758 | /* Find VT8237 southbridge */ |
754 | dev = pci_get_device(PCI_VENDOR_ID_VIA, | 759 | dev = pci_get_device(PCI_VENDOR_ID_VIA, |
755 | PCI_DEVICE_ID_VIA_8237, NULL); | 760 | PCI_DEVICE_ID_VIA_8237, NULL); |
756 | if (dev != NULL) { | 761 | if (dev != NULL) { |
@@ -769,7 +774,8 @@ static int longhaul_setup_southbridge(void) | |||
769 | if (pci_cmd & 1 << 7) { | 774 | if (pci_cmd & 1 << 7) { |
770 | pci_read_config_dword(dev, 0x88, &acpi_regs_addr); | 775 | pci_read_config_dword(dev, 0x88, &acpi_regs_addr); |
771 | acpi_regs_addr &= 0xff00; | 776 | acpi_regs_addr &= 0xff00; |
772 | printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr); | 777 | printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", |
778 | acpi_regs_addr); | ||
773 | } | 779 | } |
774 | 780 | ||
775 | pci_dev_put(dev); | 781 | pci_dev_put(dev); |
@@ -781,7 +787,7 @@ static int longhaul_setup_southbridge(void) | |||
781 | static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | 787 | static int __init longhaul_cpu_init(struct cpufreq_policy *policy) |
782 | { | 788 | { |
783 | struct cpuinfo_x86 *c = &cpu_data(0); | 789 | struct cpuinfo_x86 *c = &cpu_data(0); |
784 | char *cpuname=NULL; | 790 | char *cpuname = NULL; |
785 | int ret; | 791 | int ret; |
786 | u32 lo, hi; | 792 | u32 lo, hi; |
787 | 793 | ||
@@ -791,8 +797,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
791 | cpu_model = CPU_SAMUEL; | 797 | cpu_model = CPU_SAMUEL; |
792 | cpuname = "C3 'Samuel' [C5A]"; | 798 | cpuname = "C3 'Samuel' [C5A]"; |
793 | longhaul_version = TYPE_LONGHAUL_V1; | 799 | longhaul_version = TYPE_LONGHAUL_V1; |
794 | memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio)); | 800 | memcpy(mults, samuel1_mults, sizeof(samuel1_mults)); |
795 | memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr)); | 801 | memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr)); |
796 | break; | 802 | break; |
797 | 803 | ||
798 | case 7: | 804 | case 7: |
@@ -803,10 +809,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
803 | cpuname = "C3 'Samuel 2' [C5B]"; | 809 | cpuname = "C3 'Samuel 2' [C5B]"; |
804 | /* Note, this is not a typo, early Samuel2's had | 810 | /* Note, this is not a typo, early Samuel2's had |
805 | * Samuel1 ratios. */ | 811 | * Samuel1 ratios. */ |
806 | memcpy(clock_ratio, samuel1_clock_ratio, | 812 | memcpy(mults, samuel1_mults, sizeof(samuel1_mults)); |
807 | sizeof(samuel1_clock_ratio)); | 813 | memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); |
808 | memcpy(eblcr_table, samuel2_eblcr, | ||
809 | sizeof(samuel2_eblcr)); | ||
810 | break; | 814 | break; |
811 | case 1 ... 15: | 815 | case 1 ... 15: |
812 | longhaul_version = TYPE_LONGHAUL_V1; | 816 | longhaul_version = TYPE_LONGHAUL_V1; |
@@ -817,10 +821,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
817 | cpu_model = CPU_EZRA; | 821 | cpu_model = CPU_EZRA; |
818 | cpuname = "C3 'Ezra' [C5C]"; | 822 | cpuname = "C3 'Ezra' [C5C]"; |
819 | } | 823 | } |
820 | memcpy(clock_ratio, ezra_clock_ratio, | 824 | memcpy(mults, ezra_mults, sizeof(ezra_mults)); |
821 | sizeof(ezra_clock_ratio)); | 825 | memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr)); |
822 | memcpy(eblcr_table, ezra_eblcr, | ||
823 | sizeof(ezra_eblcr)); | ||
824 | break; | 826 | break; |
825 | } | 827 | } |
826 | break; | 828 | break; |
@@ -829,18 +831,16 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
829 | cpu_model = CPU_EZRA_T; | 831 | cpu_model = CPU_EZRA_T; |
830 | cpuname = "C3 'Ezra-T' [C5M]"; | 832 | cpuname = "C3 'Ezra-T' [C5M]"; |
831 | longhaul_version = TYPE_POWERSAVER; | 833 | longhaul_version = TYPE_POWERSAVER; |
832 | numscales=32; | 834 | numscales = 32; |
833 | memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio)); | 835 | memcpy(mults, ezrat_mults, sizeof(ezrat_mults)); |
834 | memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr)); | 836 | memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr)); |
835 | break; | 837 | break; |
836 | 838 | ||
837 | case 9: | 839 | case 9: |
838 | longhaul_version = TYPE_POWERSAVER; | 840 | longhaul_version = TYPE_POWERSAVER; |
839 | numscales = 32; | 841 | numscales = 32; |
840 | memcpy(clock_ratio, | 842 | memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults)); |
841 | nehemiah_clock_ratio, | 843 | memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr)); |
842 | sizeof(nehemiah_clock_ratio)); | ||
843 | memcpy(eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr)); | ||
844 | switch (c->x86_mask) { | 844 | switch (c->x86_mask) { |
845 | case 0 ... 1: | 845 | case 0 ... 1: |
846 | cpu_model = CPU_NEHEMIAH; | 846 | cpu_model = CPU_NEHEMIAH; |
@@ -869,14 +869,14 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
869 | longhaul_version = TYPE_LONGHAUL_V1; | 869 | longhaul_version = TYPE_LONGHAUL_V1; |
870 | } | 870 | } |
871 | 871 | ||
872 | printk (KERN_INFO PFX "VIA %s CPU detected. ", cpuname); | 872 | printk(KERN_INFO PFX "VIA %s CPU detected. ", cpuname); |
873 | switch (longhaul_version) { | 873 | switch (longhaul_version) { |
874 | case TYPE_LONGHAUL_V1: | 874 | case TYPE_LONGHAUL_V1: |
875 | case TYPE_LONGHAUL_V2: | 875 | case TYPE_LONGHAUL_V2: |
876 | printk ("Longhaul v%d supported.\n", longhaul_version); | 876 | printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version); |
877 | break; | 877 | break; |
878 | case TYPE_POWERSAVER: | 878 | case TYPE_POWERSAVER: |
879 | printk ("Powersaver supported.\n"); | 879 | printk(KERN_CONT "Powersaver supported.\n"); |
880 | break; | 880 | break; |
881 | }; | 881 | }; |
882 | 882 | ||
@@ -940,7 +940,7 @@ static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy) | |||
940 | return 0; | 940 | return 0; |
941 | } | 941 | } |
942 | 942 | ||
943 | static struct freq_attr* longhaul_attr[] = { | 943 | static struct freq_attr *longhaul_attr[] = { |
944 | &cpufreq_freq_attr_scaling_available_freqs, | 944 | &cpufreq_freq_attr_scaling_available_freqs, |
945 | NULL, | 945 | NULL, |
946 | }; | 946 | }; |
@@ -966,13 +966,15 @@ static int __init longhaul_init(void) | |||
966 | 966 | ||
967 | #ifdef CONFIG_SMP | 967 | #ifdef CONFIG_SMP |
968 | if (num_online_cpus() > 1) { | 968 | if (num_online_cpus() > 1) { |
969 | printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n"); | 969 | printk(KERN_ERR PFX "More than 1 CPU detected, " |
970 | "longhaul disabled.\n"); | ||
970 | return -ENODEV; | 971 | return -ENODEV; |
971 | } | 972 | } |
972 | #endif | 973 | #endif |
973 | #ifdef CONFIG_X86_IO_APIC | 974 | #ifdef CONFIG_X86_IO_APIC |
974 | if (cpu_has_apic) { | 975 | if (cpu_has_apic) { |
975 | printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n"); | 976 | printk(KERN_ERR PFX "APIC detected. Longhaul is currently " |
977 | "broken in this configuration.\n"); | ||
976 | return -ENODEV; | 978 | return -ENODEV; |
977 | } | 979 | } |
978 | #endif | 980 | #endif |
@@ -993,8 +995,8 @@ static void __exit longhaul_exit(void) | |||
993 | { | 995 | { |
994 | int i; | 996 | int i; |
995 | 997 | ||
996 | for (i=0; i < numscales; i++) { | 998 | for (i = 0; i < numscales; i++) { |
997 | if (clock_ratio[i] == maxmult) { | 999 | if (mults[i] == maxmult) { |
998 | longhaul_setstate(i); | 1000 | longhaul_setstate(i); |
999 | break; | 1001 | break; |
1000 | } | 1002 | } |
@@ -1007,11 +1009,11 @@ static void __exit longhaul_exit(void) | |||
1007 | /* Even if BIOS is exporting ACPI C3 state, and it is used | 1009 | /* Even if BIOS is exporting ACPI C3 state, and it is used |
1008 | * with success when CPU is idle, this state doesn't | 1010 | * with success when CPU is idle, this state doesn't |
1009 | * trigger frequency transition in some cases. */ | 1011 | * trigger frequency transition in some cases. */ |
1010 | module_param (disable_acpi_c3, int, 0644); | 1012 | module_param(disable_acpi_c3, int, 0644); |
1011 | MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); | 1013 | MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); |
1012 | /* Change CPU voltage with frequency. Very usefull to save | 1014 | /* Change CPU voltage with frequency. Very usefull to save |
1013 | * power, but most VIA C3 processors aren't supporting it. */ | 1015 | * power, but most VIA C3 processors aren't supporting it. */ |
1014 | module_param (scale_voltage, int, 0644); | 1016 | module_param(scale_voltage, int, 0644); |
1015 | MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); | 1017 | MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); |
1016 | /* Force revision key to 0 for processors which doesn't | 1018 | /* Force revision key to 0 for processors which doesn't |
1017 | * support voltage scaling, but are introducing itself as | 1019 | * support voltage scaling, but are introducing itself as |
@@ -1019,9 +1021,9 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); | |||
1019 | module_param(revid_errata, int, 0644); | 1021 | module_param(revid_errata, int, 0644); |
1020 | MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); | 1022 | MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); |
1021 | 1023 | ||
1022 | MODULE_AUTHOR ("Dave Jones <davej@redhat.com>"); | 1024 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
1023 | MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); | 1025 | MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); |
1024 | MODULE_LICENSE ("GPL"); | 1026 | MODULE_LICENSE("GPL"); |
1025 | 1027 | ||
1026 | late_initcall(longhaul_init); | 1028 | late_initcall(longhaul_init); |
1027 | module_exit(longhaul_exit); | 1029 | module_exit(longhaul_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.h b/arch/x86/kernel/cpu/cpufreq/longhaul.h index 4fcc320997df..e2360a469f79 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.h +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.h | |||
@@ -49,14 +49,14 @@ union msr_longhaul { | |||
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Clock ratio tables. Div/Mod by 10 to get ratio. | 51 | * Clock ratio tables. Div/Mod by 10 to get ratio. |
52 | * The eblcr ones specify the ratio read from the CPU. | 52 | * The eblcr values specify the ratio read from the CPU. |
53 | * The clock_ratio ones specify what to write to the CPU. | 53 | * The mults values specify what to write to the CPU. |
54 | */ | 54 | */ |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * VIA C3 Samuel 1 & Samuel 2 (stepping 0) | 57 | * VIA C3 Samuel 1 & Samuel 2 (stepping 0) |
58 | */ | 58 | */ |
59 | static const int __initdata samuel1_clock_ratio[16] = { | 59 | static const int __initdata samuel1_mults[16] = { |
60 | -1, /* 0000 -> RESERVED */ | 60 | -1, /* 0000 -> RESERVED */ |
61 | 30, /* 0001 -> 3.0x */ | 61 | 30, /* 0001 -> 3.0x */ |
62 | 40, /* 0010 -> 4.0x */ | 62 | 40, /* 0010 -> 4.0x */ |
@@ -119,7 +119,7 @@ static const int __initdata samuel2_eblcr[16] = { | |||
119 | /* | 119 | /* |
120 | * VIA C3 Ezra | 120 | * VIA C3 Ezra |
121 | */ | 121 | */ |
122 | static const int __initdata ezra_clock_ratio[16] = { | 122 | static const int __initdata ezra_mults[16] = { |
123 | 100, /* 0000 -> 10.0x */ | 123 | 100, /* 0000 -> 10.0x */ |
124 | 30, /* 0001 -> 3.0x */ | 124 | 30, /* 0001 -> 3.0x */ |
125 | 40, /* 0010 -> 4.0x */ | 125 | 40, /* 0010 -> 4.0x */ |
@@ -160,7 +160,7 @@ static const int __initdata ezra_eblcr[16] = { | |||
160 | /* | 160 | /* |
161 | * VIA C3 (Ezra-T) [C5M]. | 161 | * VIA C3 (Ezra-T) [C5M]. |
162 | */ | 162 | */ |
163 | static const int __initdata ezrat_clock_ratio[32] = { | 163 | static const int __initdata ezrat_mults[32] = { |
164 | 100, /* 0000 -> 10.0x */ | 164 | 100, /* 0000 -> 10.0x */ |
165 | 30, /* 0001 -> 3.0x */ | 165 | 30, /* 0001 -> 3.0x */ |
166 | 40, /* 0010 -> 4.0x */ | 166 | 40, /* 0010 -> 4.0x */ |
@@ -235,7 +235,7 @@ static const int __initdata ezrat_eblcr[32] = { | |||
235 | /* | 235 | /* |
236 | * VIA C3 Nehemiah */ | 236 | * VIA C3 Nehemiah */ |
237 | 237 | ||
238 | static const int __initdata nehemiah_clock_ratio[32] = { | 238 | static const int __initdata nehemiah_mults[32] = { |
239 | 100, /* 0000 -> 10.0x */ | 239 | 100, /* 0000 -> 10.0x */ |
240 | -1, /* 0001 -> 16.0x */ | 240 | -1, /* 0001 -> 16.0x */ |
241 | 40, /* 0010 -> 4.0x */ | 241 | 40, /* 0010 -> 4.0x */ |
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c index 777a7ff075de..da5f70fcb766 100644 --- a/arch/x86/kernel/cpu/cpufreq/longrun.c +++ b/arch/x86/kernel/cpu/cpufreq/longrun.c | |||
@@ -11,12 +11,13 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/cpufreq.h> | 13 | #include <linux/cpufreq.h> |
14 | #include <linux/timex.h> | ||
14 | 15 | ||
15 | #include <asm/msr.h> | 16 | #include <asm/msr.h> |
16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
17 | #include <asm/timex.h> | ||
18 | 18 | ||
19 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longrun", msg) | 19 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
20 | "longrun", msg) | ||
20 | 21 | ||
21 | static struct cpufreq_driver longrun_driver; | 22 | static struct cpufreq_driver longrun_driver; |
22 | 23 | ||
@@ -51,7 +52,7 @@ static void __init longrun_get_policy(struct cpufreq_policy *policy) | |||
51 | msr_lo &= 0x0000007F; | 52 | msr_lo &= 0x0000007F; |
52 | msr_hi &= 0x0000007F; | 53 | msr_hi &= 0x0000007F; |
53 | 54 | ||
54 | if ( longrun_high_freq <= longrun_low_freq ) { | 55 | if (longrun_high_freq <= longrun_low_freq) { |
55 | /* Assume degenerate Longrun table */ | 56 | /* Assume degenerate Longrun table */ |
56 | policy->min = policy->max = longrun_high_freq; | 57 | policy->min = policy->max = longrun_high_freq; |
57 | } else { | 58 | } else { |
@@ -79,7 +80,7 @@ static int longrun_set_policy(struct cpufreq_policy *policy) | |||
79 | if (!policy) | 80 | if (!policy) |
80 | return -EINVAL; | 81 | return -EINVAL; |
81 | 82 | ||
82 | if ( longrun_high_freq <= longrun_low_freq ) { | 83 | if (longrun_high_freq <= longrun_low_freq) { |
83 | /* Assume degenerate Longrun table */ | 84 | /* Assume degenerate Longrun table */ |
84 | pctg_lo = pctg_hi = 100; | 85 | pctg_lo = pctg_hi = 100; |
85 | } else { | 86 | } else { |
@@ -152,7 +153,7 @@ static unsigned int longrun_get(unsigned int cpu) | |||
152 | cpuid(0x80860007, &eax, &ebx, &ecx, &edx); | 153 | cpuid(0x80860007, &eax, &ebx, &ecx, &edx); |
153 | dprintk("cpuid eax is %u\n", eax); | 154 | dprintk("cpuid eax is %u\n", eax); |
154 | 155 | ||
155 | return (eax * 1000); | 156 | return eax * 1000; |
156 | } | 157 | } |
157 | 158 | ||
158 | /** | 159 | /** |
@@ -196,7 +197,8 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, | |||
196 | rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); | 197 | rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); |
197 | *high_freq = msr_lo * 1000; /* to kHz */ | 198 | *high_freq = msr_lo * 1000; /* to kHz */ |
198 | 199 | ||
199 | dprintk("longrun table interface told %u - %u kHz\n", *low_freq, *high_freq); | 200 | dprintk("longrun table interface told %u - %u kHz\n", |
201 | *low_freq, *high_freq); | ||
200 | 202 | ||
201 | if (*low_freq > *high_freq) | 203 | if (*low_freq > *high_freq) |
202 | *low_freq = *high_freq; | 204 | *low_freq = *high_freq; |
@@ -219,7 +221,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, | |||
219 | cpuid(0x80860007, &eax, &ebx, &ecx, &edx); | 221 | cpuid(0x80860007, &eax, &ebx, &ecx, &edx); |
220 | /* try decreasing in 10% steps, some processors react only | 222 | /* try decreasing in 10% steps, some processors react only |
221 | * on some barrier values */ | 223 | * on some barrier values */ |
222 | for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -=10) { | 224 | for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) { |
223 | /* set to 0 to try_hi perf_pctg */ | 225 | /* set to 0 to try_hi perf_pctg */ |
224 | msr_lo &= 0xFFFFFF80; | 226 | msr_lo &= 0xFFFFFF80; |
225 | msr_hi &= 0xFFFFFF80; | 227 | msr_hi &= 0xFFFFFF80; |
@@ -236,7 +238,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, | |||
236 | 238 | ||
237 | /* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) | 239 | /* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) |
238 | * eqals | 240 | * eqals |
239 | * low_freq * ( 1 - perf_pctg) = (cur_freq - high_freq * perf_pctg) | 241 | * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg) |
240 | * | 242 | * |
241 | * high_freq * perf_pctg is stored tempoarily into "ebx". | 243 | * high_freq * perf_pctg is stored tempoarily into "ebx". |
242 | */ | 244 | */ |
@@ -317,9 +319,10 @@ static void __exit longrun_exit(void) | |||
317 | } | 319 | } |
318 | 320 | ||
319 | 321 | ||
320 | MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>"); | 322 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); |
321 | MODULE_DESCRIPTION ("LongRun driver for Transmeta Crusoe and Efficeon processors."); | 323 | MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and " |
322 | MODULE_LICENSE ("GPL"); | 324 | "Efficeon processors."); |
325 | MODULE_LICENSE("GPL"); | ||
323 | 326 | ||
324 | module_init(longrun_init); | 327 | module_init(longrun_init); |
325 | module_exit(longrun_exit); | 328 | module_exit(longrun_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 3178c3acd97e..6ac55bd341ae 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -27,15 +27,17 @@ | |||
27 | #include <linux/cpufreq.h> | 27 | #include <linux/cpufreq.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/cpumask.h> | 29 | #include <linux/cpumask.h> |
30 | #include <linux/timex.h> | ||
30 | 31 | ||
31 | #include <asm/processor.h> | 32 | #include <asm/processor.h> |
32 | #include <asm/msr.h> | 33 | #include <asm/msr.h> |
33 | #include <asm/timex.h> | 34 | #include <asm/timer.h> |
34 | 35 | ||
35 | #include "speedstep-lib.h" | 36 | #include "speedstep-lib.h" |
36 | 37 | ||
37 | #define PFX "p4-clockmod: " | 38 | #define PFX "p4-clockmod: " |
38 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "p4-clockmod", msg) | 39 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
40 | "p4-clockmod", msg) | ||
39 | 41 | ||
40 | /* | 42 | /* |
41 | * Duty Cycle (3bits), note DC_DISABLE is not specified in | 43 | * Duty Cycle (3bits), note DC_DISABLE is not specified in |
@@ -58,7 +60,8 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) | |||
58 | { | 60 | { |
59 | u32 l, h; | 61 | u32 l, h; |
60 | 62 | ||
61 | if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV)) | 63 | if (!cpu_online(cpu) || |
64 | (newstate > DC_DISABLE) || (newstate == DC_RESV)) | ||
62 | return -EINVAL; | 65 | return -EINVAL; |
63 | 66 | ||
64 | rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); | 67 | rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); |
@@ -66,7 +69,8 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) | |||
66 | if (l & 0x01) | 69 | if (l & 0x01) |
67 | dprintk("CPU#%d currently thermal throttled\n", cpu); | 70 | dprintk("CPU#%d currently thermal throttled\n", cpu); |
68 | 71 | ||
69 | if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) | 72 | if (has_N44_O17_errata[cpu] && |
73 | (newstate == DC_25PT || newstate == DC_DFLT)) | ||
70 | newstate = DC_38PT; | 74 | newstate = DC_38PT; |
71 | 75 | ||
72 | rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); | 76 | rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); |
@@ -112,7 +116,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, | |||
112 | struct cpufreq_freqs freqs; | 116 | struct cpufreq_freqs freqs; |
113 | int i; | 117 | int i; |
114 | 118 | ||
115 | if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate)) | 119 | if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], |
120 | target_freq, relation, &newstate)) | ||
116 | return -EINVAL; | 121 | return -EINVAL; |
117 | 122 | ||
118 | freqs.old = cpufreq_p4_get(policy->cpu); | 123 | freqs.old = cpufreq_p4_get(policy->cpu); |
@@ -127,7 +132,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, | |||
127 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 132 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
128 | } | 133 | } |
129 | 134 | ||
130 | /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software | 135 | /* run on each logical CPU, |
136 | * see section 13.15.3 of IA32 Intel Architecture Software | ||
131 | * Developer's Manual, Volume 3 | 137 | * Developer's Manual, Volume 3 |
132 | */ | 138 | */ |
133 | for_each_cpu(i, policy->cpus) | 139 | for_each_cpu(i, policy->cpus) |
@@ -153,28 +159,30 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) | |||
153 | { | 159 | { |
154 | if (c->x86 == 0x06) { | 160 | if (c->x86 == 0x06) { |
155 | if (cpu_has(c, X86_FEATURE_EST)) | 161 | if (cpu_has(c, X86_FEATURE_EST)) |
156 | printk(KERN_WARNING PFX "Warning: EST-capable CPU detected. " | 162 | printk(KERN_WARNING PFX "Warning: EST-capable CPU " |
157 | "The acpi-cpufreq module offers voltage scaling" | 163 | "detected. The acpi-cpufreq module offers " |
158 | " in addition of frequency scaling. You should use " | 164 | "voltage scaling in addition of frequency " |
159 | "that instead of p4-clockmod, if possible.\n"); | 165 | "scaling. You should use that instead of " |
166 | "p4-clockmod, if possible.\n"); | ||
160 | switch (c->x86_model) { | 167 | switch (c->x86_model) { |
161 | case 0x0E: /* Core */ | 168 | case 0x0E: /* Core */ |
162 | case 0x0F: /* Core Duo */ | 169 | case 0x0F: /* Core Duo */ |
163 | case 0x16: /* Celeron Core */ | 170 | case 0x16: /* Celeron Core */ |
164 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; | 171 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
165 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PCORE); | 172 | return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE); |
166 | case 0x0D: /* Pentium M (Dothan) */ | 173 | case 0x0D: /* Pentium M (Dothan) */ |
167 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; | 174 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
168 | /* fall through */ | 175 | /* fall through */ |
169 | case 0x09: /* Pentium M (Banias) */ | 176 | case 0x09: /* Pentium M (Banias) */ |
170 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM); | 177 | return speedstep_get_frequency(SPEEDSTEP_CPU_PM); |
171 | } | 178 | } |
172 | } | 179 | } |
173 | 180 | ||
174 | if (c->x86 != 0xF) { | 181 | if (c->x86 != 0xF) { |
175 | if (!cpu_has(c, X86_FEATURE_EST)) | 182 | if (!cpu_has(c, X86_FEATURE_EST)) |
176 | printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. " | 183 | printk(KERN_WARNING PFX "Unknown CPU. " |
177 | "Please send an e-mail to <cpufreq@vger.kernel.org>\n"); | 184 | "Please send an e-mail to " |
185 | "<cpufreq@vger.kernel.org>\n"); | ||
178 | return 0; | 186 | return 0; |
179 | } | 187 | } |
180 | 188 | ||
@@ -182,16 +190,16 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) | |||
182 | * throttling is active or not. */ | 190 | * throttling is active or not. */ |
183 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; | 191 | p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
184 | 192 | ||
185 | if (speedstep_detect_processor() == SPEEDSTEP_PROCESSOR_P4M) { | 193 | if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) { |
186 | printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. " | 194 | printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. " |
187 | "The speedstep-ich or acpi cpufreq modules offer " | 195 | "The speedstep-ich or acpi cpufreq modules offer " |
188 | "voltage scaling in addition of frequency scaling. " | 196 | "voltage scaling in addition of frequency scaling. " |
189 | "You should use either one instead of p4-clockmod, " | 197 | "You should use either one instead of p4-clockmod, " |
190 | "if possible.\n"); | 198 | "if possible.\n"); |
191 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4M); | 199 | return speedstep_get_frequency(SPEEDSTEP_CPU_P4M); |
192 | } | 200 | } |
193 | 201 | ||
194 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D); | 202 | return speedstep_get_frequency(SPEEDSTEP_CPU_P4D); |
195 | } | 203 | } |
196 | 204 | ||
197 | 205 | ||
@@ -203,7 +211,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
203 | unsigned int i; | 211 | unsigned int i; |
204 | 212 | ||
205 | #ifdef CONFIG_SMP | 213 | #ifdef CONFIG_SMP |
206 | cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu)); | 214 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); |
207 | #endif | 215 | #endif |
208 | 216 | ||
209 | /* Errata workaround */ | 217 | /* Errata workaround */ |
@@ -217,14 +225,20 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
217 | dprintk("has errata -- disabling low frequencies\n"); | 225 | dprintk("has errata -- disabling low frequencies\n"); |
218 | } | 226 | } |
219 | 227 | ||
228 | if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D && | ||
229 | c->x86_model < 2) { | ||
230 | /* switch to maximum frequency and measure result */ | ||
231 | cpufreq_p4_setdc(policy->cpu, DC_DISABLE); | ||
232 | recalibrate_cpu_khz(); | ||
233 | } | ||
220 | /* get max frequency */ | 234 | /* get max frequency */ |
221 | stock_freq = cpufreq_p4_get_frequency(c); | 235 | stock_freq = cpufreq_p4_get_frequency(c); |
222 | if (!stock_freq) | 236 | if (!stock_freq) |
223 | return -EINVAL; | 237 | return -EINVAL; |
224 | 238 | ||
225 | /* table init */ | 239 | /* table init */ |
226 | for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 240 | for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { |
227 | if ((i<2) && (has_N44_O17_errata[policy->cpu])) | 241 | if ((i < 2) && (has_N44_O17_errata[policy->cpu])) |
228 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 242 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
229 | else | 243 | else |
230 | p4clockmod_table[i].frequency = (stock_freq * i)/8; | 244 | p4clockmod_table[i].frequency = (stock_freq * i)/8; |
@@ -232,7 +246,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
232 | cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); | 246 | cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); |
233 | 247 | ||
234 | /* cpuinfo and default policy values */ | 248 | /* cpuinfo and default policy values */ |
235 | policy->cpuinfo.transition_latency = 1000000; /* assumed */ | 249 | |
250 | /* the transition latency is set to be 1 higher than the maximum | ||
251 | * transition latency of the ondemand governor */ | ||
252 | policy->cpuinfo.transition_latency = 10000001; | ||
236 | policy->cur = stock_freq; | 253 | policy->cur = stock_freq; |
237 | 254 | ||
238 | return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]); | 255 | return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]); |
@@ -258,12 +275,12 @@ static unsigned int cpufreq_p4_get(unsigned int cpu) | |||
258 | l = DC_DISABLE; | 275 | l = DC_DISABLE; |
259 | 276 | ||
260 | if (l != DC_DISABLE) | 277 | if (l != DC_DISABLE) |
261 | return (stock_freq * l / 8); | 278 | return stock_freq * l / 8; |
262 | 279 | ||
263 | return stock_freq; | 280 | return stock_freq; |
264 | } | 281 | } |
265 | 282 | ||
266 | static struct freq_attr* p4clockmod_attr[] = { | 283 | static struct freq_attr *p4clockmod_attr[] = { |
267 | &cpufreq_freq_attr_scaling_available_freqs, | 284 | &cpufreq_freq_attr_scaling_available_freqs, |
268 | NULL, | 285 | NULL, |
269 | }; | 286 | }; |
@@ -298,9 +315,10 @@ static int __init cpufreq_p4_init(void) | |||
298 | 315 | ||
299 | ret = cpufreq_register_driver(&p4clockmod_driver); | 316 | ret = cpufreq_register_driver(&p4clockmod_driver); |
300 | if (!ret) | 317 | if (!ret) |
301 | printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); | 318 | printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock " |
319 | "Modulation available\n"); | ||
302 | 320 | ||
303 | return (ret); | 321 | return ret; |
304 | } | 322 | } |
305 | 323 | ||
306 | 324 | ||
@@ -310,9 +328,9 @@ static void __exit cpufreq_p4_exit(void) | |||
310 | } | 328 | } |
311 | 329 | ||
312 | 330 | ||
313 | MODULE_AUTHOR ("Zwane Mwaikambo <zwane@commfireservices.com>"); | 331 | MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>"); |
314 | MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)"); | 332 | MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)"); |
315 | MODULE_LICENSE ("GPL"); | 333 | MODULE_LICENSE("GPL"); |
316 | 334 | ||
317 | late_initcall(cpufreq_p4_init); | 335 | late_initcall(cpufreq_p4_init); |
318 | module_exit(cpufreq_p4_exit); | 336 | module_exit(cpufreq_p4_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index c1ac5790c63e..f10dea409f40 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * This file was based upon code in Powertweak Linux (http://powertweak.sf.net) | 2 | * This file was based upon code in Powertweak Linux (http://powertweak.sf.net) |
3 | * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski. | 3 | * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä, |
4 | * Dominik Brodowski. | ||
4 | * | 5 | * |
5 | * Licensed under the terms of the GNU GPL License version 2. | 6 | * Licensed under the terms of the GNU GPL License version 2. |
6 | * | 7 | * |
@@ -13,14 +14,15 @@ | |||
13 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
14 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | |||
17 | #include <asm/msr.h> | ||
18 | #include <linux/timex.h> | 17 | #include <linux/timex.h> |
19 | #include <linux/io.h> | 18 | #include <linux/io.h> |
20 | 19 | ||
20 | #include <asm/msr.h> | ||
21 | |||
21 | #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long | 22 | #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long |
22 | as it is unused */ | 23 | as it is unused */ |
23 | 24 | ||
25 | #define PFX "powernow-k6: " | ||
24 | static unsigned int busfreq; /* FSB, in 10 kHz */ | 26 | static unsigned int busfreq; /* FSB, in 10 kHz */ |
25 | static unsigned int max_multiplier; | 27 | static unsigned int max_multiplier; |
26 | 28 | ||
@@ -47,8 +49,8 @@ static struct cpufreq_frequency_table clock_ratio[] = { | |||
47 | */ | 49 | */ |
48 | static int powernow_k6_get_cpu_multiplier(void) | 50 | static int powernow_k6_get_cpu_multiplier(void) |
49 | { | 51 | { |
50 | u64 invalue = 0; | 52 | u64 invalue = 0; |
51 | u32 msrval; | 53 | u32 msrval; |
52 | 54 | ||
53 | msrval = POWERNOW_IOPORT + 0x1; | 55 | msrval = POWERNOW_IOPORT + 0x1; |
54 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | 56 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ |
@@ -68,12 +70,12 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
68 | */ | 70 | */ |
69 | static void powernow_k6_set_state(unsigned int best_i) | 71 | static void powernow_k6_set_state(unsigned int best_i) |
70 | { | 72 | { |
71 | unsigned long outvalue = 0, invalue = 0; | 73 | unsigned long outvalue = 0, invalue = 0; |
72 | unsigned long msrval; | 74 | unsigned long msrval; |
73 | struct cpufreq_freqs freqs; | 75 | struct cpufreq_freqs freqs; |
74 | 76 | ||
75 | if (clock_ratio[best_i].index > max_multiplier) { | 77 | if (clock_ratio[best_i].index > max_multiplier) { |
76 | printk(KERN_ERR "cpufreq: invalid target frequency\n"); | 78 | printk(KERN_ERR PFX "invalid target frequency\n"); |
77 | return; | 79 | return; |
78 | } | 80 | } |
79 | 81 | ||
@@ -119,7 +121,8 @@ static int powernow_k6_verify(struct cpufreq_policy *policy) | |||
119 | * powernow_k6_setpolicy - sets a new CPUFreq policy | 121 | * powernow_k6_setpolicy - sets a new CPUFreq policy |
120 | * @policy: new policy | 122 | * @policy: new policy |
121 | * @target_freq: the target frequency | 123 | * @target_freq: the target frequency |
122 | * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | 124 | * @relation: how that frequency relates to achieved frequency |
125 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
123 | * | 126 | * |
124 | * sets a new CPUFreq policy | 127 | * sets a new CPUFreq policy |
125 | */ | 128 | */ |
@@ -127,9 +130,10 @@ static int powernow_k6_target(struct cpufreq_policy *policy, | |||
127 | unsigned int target_freq, | 130 | unsigned int target_freq, |
128 | unsigned int relation) | 131 | unsigned int relation) |
129 | { | 132 | { |
130 | unsigned int newstate = 0; | 133 | unsigned int newstate = 0; |
131 | 134 | ||
132 | if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate)) | 135 | if (cpufreq_frequency_table_target(policy, &clock_ratio[0], |
136 | target_freq, relation, &newstate)) | ||
133 | return -EINVAL; | 137 | return -EINVAL; |
134 | 138 | ||
135 | powernow_k6_set_state(newstate); | 139 | powernow_k6_set_state(newstate); |
@@ -140,7 +144,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy, | |||
140 | 144 | ||
141 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | 145 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) |
142 | { | 146 | { |
143 | unsigned int i; | 147 | unsigned int i, f; |
144 | int result; | 148 | int result; |
145 | 149 | ||
146 | if (policy->cpu != 0) | 150 | if (policy->cpu != 0) |
@@ -152,10 +156,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
152 | 156 | ||
153 | /* table init */ | 157 | /* table init */ |
154 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 158 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { |
155 | if (clock_ratio[i].index > max_multiplier) | 159 | f = clock_ratio[i].index; |
160 | if (f > max_multiplier) | ||
156 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; | 161 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; |
157 | else | 162 | else |
158 | clock_ratio[i].frequency = busfreq * clock_ratio[i].index; | 163 | clock_ratio[i].frequency = busfreq * f; |
159 | } | 164 | } |
160 | 165 | ||
161 | /* cpuinfo and default policy values */ | 166 | /* cpuinfo and default policy values */ |
@@ -185,7 +190,9 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) | |||
185 | 190 | ||
186 | static unsigned int powernow_k6_get(unsigned int cpu) | 191 | static unsigned int powernow_k6_get(unsigned int cpu) |
187 | { | 192 | { |
188 | return busfreq * powernow_k6_get_cpu_multiplier(); | 193 | unsigned int ret; |
194 | ret = (busfreq * powernow_k6_get_cpu_multiplier()); | ||
195 | return ret; | ||
189 | } | 196 | } |
190 | 197 | ||
191 | static struct freq_attr *powernow_k6_attr[] = { | 198 | static struct freq_attr *powernow_k6_attr[] = { |
@@ -221,7 +228,7 @@ static int __init powernow_k6_init(void) | |||
221 | return -ENODEV; | 228 | return -ENODEV; |
222 | 229 | ||
223 | if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { | 230 | if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { |
224 | printk("cpufreq: PowerNow IOPORT region already used.\n"); | 231 | printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n"); |
225 | return -EIO; | 232 | return -EIO; |
226 | } | 233 | } |
227 | 234 | ||
@@ -246,7 +253,8 @@ static void __exit powernow_k6_exit(void) | |||
246 | } | 253 | } |
247 | 254 | ||
248 | 255 | ||
249 | MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>"); | 256 | MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, " |
257 | "Dominik Brodowski <linux@brodo.de>"); | ||
250 | MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); | 258 | MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); |
251 | MODULE_LICENSE("GPL"); | 259 | MODULE_LICENSE("GPL"); |
252 | 260 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index 1b446d79a8fd..3c28ccd49742 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -6,10 +6,12 @@ | |||
6 | * Licensed under the terms of the GNU GPL License version 2. | 6 | * Licensed under the terms of the GNU GPL License version 2. |
7 | * Based upon datasheets & sample CPUs kindly provided by AMD. | 7 | * Based upon datasheets & sample CPUs kindly provided by AMD. |
8 | * | 8 | * |
9 | * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt. | 9 | * Errata 5: |
10 | * - We cli/sti on stepping A0 CPUs around the FID/VID transition. | 10 | * CPU may fail to execute a FID/VID change in presence of interrupt. |
11 | * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect. | 11 | * - We cli/sti on stepping A0 CPUs around the FID/VID transition. |
12 | * - We disable half multipliers if ACPI is used on A0 stepping CPUs. | 12 | * Errata 15: |
13 | * CPU with half frequency multipliers may hang upon wakeup from disconnect. | ||
14 | * - We disable half multipliers if ACPI is used on A0 stepping CPUs. | ||
13 | */ | 15 | */ |
14 | 16 | ||
15 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
@@ -20,11 +22,11 @@ | |||
20 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
21 | #include <linux/string.h> | 23 | #include <linux/string.h> |
22 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/timex.h> | ||
26 | #include <linux/io.h> | ||
23 | 27 | ||
28 | #include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */ | ||
24 | #include <asm/msr.h> | 29 | #include <asm/msr.h> |
25 | #include <asm/timer.h> | ||
26 | #include <asm/timex.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/system.h> | 30 | #include <asm/system.h> |
29 | 31 | ||
30 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 32 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
@@ -58,9 +60,9 @@ struct pst_s { | |||
58 | union powernow_acpi_control_t { | 60 | union powernow_acpi_control_t { |
59 | struct { | 61 | struct { |
60 | unsigned long fid:5, | 62 | unsigned long fid:5, |
61 | vid:5, | 63 | vid:5, |
62 | sgtc:20, | 64 | sgtc:20, |
63 | res1:2; | 65 | res1:2; |
64 | } bits; | 66 | } bits; |
65 | unsigned long val; | 67 | unsigned long val; |
66 | }; | 68 | }; |
@@ -94,14 +96,15 @@ static struct cpufreq_frequency_table *powernow_table; | |||
94 | 96 | ||
95 | static unsigned int can_scale_bus; | 97 | static unsigned int can_scale_bus; |
96 | static unsigned int can_scale_vid; | 98 | static unsigned int can_scale_vid; |
97 | static unsigned int minimum_speed=-1; | 99 | static unsigned int minimum_speed = -1; |
98 | static unsigned int maximum_speed; | 100 | static unsigned int maximum_speed; |
99 | static unsigned int number_scales; | 101 | static unsigned int number_scales; |
100 | static unsigned int fsb; | 102 | static unsigned int fsb; |
101 | static unsigned int latency; | 103 | static unsigned int latency; |
102 | static char have_a0; | 104 | static char have_a0; |
103 | 105 | ||
104 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg) | 106 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
107 | "powernow-k7", msg) | ||
105 | 108 | ||
106 | static int check_fsb(unsigned int fsbspeed) | 109 | static int check_fsb(unsigned int fsbspeed) |
107 | { | 110 | { |
@@ -109,7 +112,7 @@ static int check_fsb(unsigned int fsbspeed) | |||
109 | unsigned int f = fsb / 1000; | 112 | unsigned int f = fsb / 1000; |
110 | 113 | ||
111 | delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed; | 114 | delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed; |
112 | return (delta < 5); | 115 | return delta < 5; |
113 | } | 116 | } |
114 | 117 | ||
115 | static int check_powernow(void) | 118 | static int check_powernow(void) |
@@ -117,24 +120,26 @@ static int check_powernow(void) | |||
117 | struct cpuinfo_x86 *c = &cpu_data(0); | 120 | struct cpuinfo_x86 *c = &cpu_data(0); |
118 | unsigned int maxei, eax, ebx, ecx, edx; | 121 | unsigned int maxei, eax, ebx, ecx, edx; |
119 | 122 | ||
120 | if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) { | 123 | if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) { |
121 | #ifdef MODULE | 124 | #ifdef MODULE |
122 | printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n"); | 125 | printk(KERN_INFO PFX "This module only works with " |
126 | "AMD K7 CPUs\n"); | ||
123 | #endif | 127 | #endif |
124 | return 0; | 128 | return 0; |
125 | } | 129 | } |
126 | 130 | ||
127 | /* Get maximum capabilities */ | 131 | /* Get maximum capabilities */ |
128 | maxei = cpuid_eax (0x80000000); | 132 | maxei = cpuid_eax(0x80000000); |
129 | if (maxei < 0x80000007) { /* Any powernow info ? */ | 133 | if (maxei < 0x80000007) { /* Any powernow info ? */ |
130 | #ifdef MODULE | 134 | #ifdef MODULE |
131 | printk (KERN_INFO PFX "No powernow capabilities detected\n"); | 135 | printk(KERN_INFO PFX "No powernow capabilities detected\n"); |
132 | #endif | 136 | #endif |
133 | return 0; | 137 | return 0; |
134 | } | 138 | } |
135 | 139 | ||
136 | if ((c->x86_model == 6) && (c->x86_mask == 0)) { | 140 | if ((c->x86_model == 6) && (c->x86_mask == 0)) { |
137 | printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n"); | 141 | printk(KERN_INFO PFX "K7 660[A0] core detected, " |
142 | "enabling errata workarounds\n"); | ||
138 | have_a0 = 1; | 143 | have_a0 = 1; |
139 | } | 144 | } |
140 | 145 | ||
@@ -144,37 +149,42 @@ static int check_powernow(void) | |||
144 | if (!(edx & (1 << 1 | 1 << 2))) | 149 | if (!(edx & (1 << 1 | 1 << 2))) |
145 | return 0; | 150 | return 0; |
146 | 151 | ||
147 | printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); | 152 | printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); |
148 | 153 | ||
149 | if (edx & 1 << 1) { | 154 | if (edx & 1 << 1) { |
150 | printk ("frequency"); | 155 | printk("frequency"); |
151 | can_scale_bus=1; | 156 | can_scale_bus = 1; |
152 | } | 157 | } |
153 | 158 | ||
154 | if ((edx & (1 << 1 | 1 << 2)) == 0x6) | 159 | if ((edx & (1 << 1 | 1 << 2)) == 0x6) |
155 | printk (" and "); | 160 | printk(" and "); |
156 | 161 | ||
157 | if (edx & 1 << 2) { | 162 | if (edx & 1 << 2) { |
158 | printk ("voltage"); | 163 | printk("voltage"); |
159 | can_scale_vid=1; | 164 | can_scale_vid = 1; |
160 | } | 165 | } |
161 | 166 | ||
162 | printk (".\n"); | 167 | printk(".\n"); |
163 | return 1; | 168 | return 1; |
164 | } | 169 | } |
165 | 170 | ||
171 | static void invalidate_entry(unsigned int entry) | ||
172 | { | ||
173 | powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID; | ||
174 | } | ||
166 | 175 | ||
167 | static int get_ranges (unsigned char *pst) | 176 | static int get_ranges(unsigned char *pst) |
168 | { | 177 | { |
169 | unsigned int j; | 178 | unsigned int j; |
170 | unsigned int speed; | 179 | unsigned int speed; |
171 | u8 fid, vid; | 180 | u8 fid, vid; |
172 | 181 | ||
173 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); | 182 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * |
183 | (number_scales + 1)), GFP_KERNEL); | ||
174 | if (!powernow_table) | 184 | if (!powernow_table) |
175 | return -ENOMEM; | 185 | return -ENOMEM; |
176 | 186 | ||
177 | for (j=0 ; j < number_scales; j++) { | 187 | for (j = 0 ; j < number_scales; j++) { |
178 | fid = *pst++; | 188 | fid = *pst++; |
179 | 189 | ||
180 | powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10; | 190 | powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10; |
@@ -182,10 +192,10 @@ static int get_ranges (unsigned char *pst) | |||
182 | 192 | ||
183 | speed = powernow_table[j].frequency; | 193 | speed = powernow_table[j].frequency; |
184 | 194 | ||
185 | if ((fid_codes[fid] % 10)==5) { | 195 | if ((fid_codes[fid] % 10) == 5) { |
186 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 196 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
187 | if (have_a0 == 1) | 197 | if (have_a0 == 1) |
188 | powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID; | 198 | invalidate_entry(j); |
189 | #endif | 199 | #endif |
190 | } | 200 | } |
191 | 201 | ||
@@ -197,7 +207,7 @@ static int get_ranges (unsigned char *pst) | |||
197 | vid = *pst++; | 207 | vid = *pst++; |
198 | powernow_table[j].index |= (vid << 8); /* upper 8 bits */ | 208 | powernow_table[j].index |= (vid << 8); /* upper 8 bits */ |
199 | 209 | ||
200 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " | 210 | dprintk(" FID: 0x%x (%d.%dx [%dMHz]) " |
201 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, | 211 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, |
202 | fid_codes[fid] % 10, speed/1000, vid, | 212 | fid_codes[fid] % 10, speed/1000, vid, |
203 | mobile_vid_table[vid]/1000, | 213 | mobile_vid_table[vid]/1000, |
@@ -214,13 +224,13 @@ static void change_FID(int fid) | |||
214 | { | 224 | { |
215 | union msr_fidvidctl fidvidctl; | 225 | union msr_fidvidctl fidvidctl; |
216 | 226 | ||
217 | rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); | 227 | rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); |
218 | if (fidvidctl.bits.FID != fid) { | 228 | if (fidvidctl.bits.FID != fid) { |
219 | fidvidctl.bits.SGTC = latency; | 229 | fidvidctl.bits.SGTC = latency; |
220 | fidvidctl.bits.FID = fid; | 230 | fidvidctl.bits.FID = fid; |
221 | fidvidctl.bits.VIDC = 0; | 231 | fidvidctl.bits.VIDC = 0; |
222 | fidvidctl.bits.FIDC = 1; | 232 | fidvidctl.bits.FIDC = 1; |
223 | wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); | 233 | wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); |
224 | } | 234 | } |
225 | } | 235 | } |
226 | 236 | ||
@@ -229,18 +239,18 @@ static void change_VID(int vid) | |||
229 | { | 239 | { |
230 | union msr_fidvidctl fidvidctl; | 240 | union msr_fidvidctl fidvidctl; |
231 | 241 | ||
232 | rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); | 242 | rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); |
233 | if (fidvidctl.bits.VID != vid) { | 243 | if (fidvidctl.bits.VID != vid) { |
234 | fidvidctl.bits.SGTC = latency; | 244 | fidvidctl.bits.SGTC = latency; |
235 | fidvidctl.bits.VID = vid; | 245 | fidvidctl.bits.VID = vid; |
236 | fidvidctl.bits.FIDC = 0; | 246 | fidvidctl.bits.FIDC = 0; |
237 | fidvidctl.bits.VIDC = 1; | 247 | fidvidctl.bits.VIDC = 1; |
238 | wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); | 248 | wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); |
239 | } | 249 | } |
240 | } | 250 | } |
241 | 251 | ||
242 | 252 | ||
243 | static void change_speed (unsigned int index) | 253 | static void change_speed(unsigned int index) |
244 | { | 254 | { |
245 | u8 fid, vid; | 255 | u8 fid, vid; |
246 | struct cpufreq_freqs freqs; | 256 | struct cpufreq_freqs freqs; |
@@ -257,7 +267,7 @@ static void change_speed (unsigned int index) | |||
257 | 267 | ||
258 | freqs.cpu = 0; | 268 | freqs.cpu = 0; |
259 | 269 | ||
260 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 270 | rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
261 | cfid = fidvidstatus.bits.CFID; | 271 | cfid = fidvidstatus.bits.CFID; |
262 | freqs.old = fsb * fid_codes[cfid] / 10; | 272 | freqs.old = fsb * fid_codes[cfid] / 10; |
263 | 273 | ||
@@ -321,12 +331,14 @@ static int powernow_acpi_init(void) | |||
321 | goto err1; | 331 | goto err1; |
322 | } | 332 | } |
323 | 333 | ||
324 | if (acpi_processor_perf->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) { | 334 | if (acpi_processor_perf->control_register.space_id != |
335 | ACPI_ADR_SPACE_FIXED_HARDWARE) { | ||
325 | retval = -ENODEV; | 336 | retval = -ENODEV; |
326 | goto err2; | 337 | goto err2; |
327 | } | 338 | } |
328 | 339 | ||
329 | if (acpi_processor_perf->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) { | 340 | if (acpi_processor_perf->status_register.space_id != |
341 | ACPI_ADR_SPACE_FIXED_HARDWARE) { | ||
330 | retval = -ENODEV; | 342 | retval = -ENODEV; |
331 | goto err2; | 343 | goto err2; |
332 | } | 344 | } |
@@ -338,7 +350,8 @@ static int powernow_acpi_init(void) | |||
338 | goto err2; | 350 | goto err2; |
339 | } | 351 | } |
340 | 352 | ||
341 | powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); | 353 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * |
354 | (number_scales + 1)), GFP_KERNEL); | ||
342 | if (!powernow_table) { | 355 | if (!powernow_table) { |
343 | retval = -ENOMEM; | 356 | retval = -ENOMEM; |
344 | goto err2; | 357 | goto err2; |
@@ -352,7 +365,7 @@ static int powernow_acpi_init(void) | |||
352 | unsigned int speed, speed_mhz; | 365 | unsigned int speed, speed_mhz; |
353 | 366 | ||
354 | pc.val = (unsigned long) state->control; | 367 | pc.val = (unsigned long) state->control; |
355 | dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", | 368 | dprintk("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", |
356 | i, | 369 | i, |
357 | (u32) state->core_frequency, | 370 | (u32) state->core_frequency, |
358 | (u32) state->power, | 371 | (u32) state->power, |
@@ -381,12 +394,12 @@ static int powernow_acpi_init(void) | |||
381 | if (speed % 1000 > 0) | 394 | if (speed % 1000 > 0) |
382 | speed_mhz++; | 395 | speed_mhz++; |
383 | 396 | ||
384 | if ((fid_codes[fid] % 10)==5) { | 397 | if ((fid_codes[fid] % 10) == 5) { |
385 | if (have_a0 == 1) | 398 | if (have_a0 == 1) |
386 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 399 | invalidate_entry(i); |
387 | } | 400 | } |
388 | 401 | ||
389 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " | 402 | dprintk(" FID: 0x%x (%d.%dx [%dMHz]) " |
390 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, | 403 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, |
391 | fid_codes[fid] % 10, speed_mhz, vid, | 404 | fid_codes[fid] % 10, speed_mhz, vid, |
392 | mobile_vid_table[vid]/1000, | 405 | mobile_vid_table[vid]/1000, |
@@ -422,7 +435,8 @@ err1: | |||
422 | err05: | 435 | err05: |
423 | kfree(acpi_processor_perf); | 436 | kfree(acpi_processor_perf); |
424 | err0: | 437 | err0: |
425 | printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n"); | 438 | printk(KERN_WARNING PFX "ACPI perflib can not be used on " |
439 | "this platform\n"); | ||
426 | acpi_processor_perf = NULL; | 440 | acpi_processor_perf = NULL; |
427 | return retval; | 441 | return retval; |
428 | } | 442 | } |
@@ -435,7 +449,14 @@ static int powernow_acpi_init(void) | |||
435 | } | 449 | } |
436 | #endif | 450 | #endif |
437 | 451 | ||
438 | static int powernow_decode_bios (int maxfid, int startvid) | 452 | static void print_pst_entry(struct pst_s *pst, unsigned int j) |
453 | { | ||
454 | dprintk("PST:%d (@%p)\n", j, pst); | ||
455 | dprintk(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", | ||
456 | pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); | ||
457 | } | ||
458 | |||
459 | static int powernow_decode_bios(int maxfid, int startvid) | ||
439 | { | 460 | { |
440 | struct psb_s *psb; | 461 | struct psb_s *psb; |
441 | struct pst_s *pst; | 462 | struct pst_s *pst; |
@@ -446,61 +467,67 @@ static int powernow_decode_bios (int maxfid, int startvid) | |||
446 | 467 | ||
447 | etuple = cpuid_eax(0x80000001); | 468 | etuple = cpuid_eax(0x80000001); |
448 | 469 | ||
449 | for (i=0xC0000; i < 0xffff0 ; i+=16) { | 470 | for (i = 0xC0000; i < 0xffff0 ; i += 16) { |
450 | 471 | ||
451 | p = phys_to_virt(i); | 472 | p = phys_to_virt(i); |
452 | 473 | ||
453 | if (memcmp(p, "AMDK7PNOW!", 10) == 0){ | 474 | if (memcmp(p, "AMDK7PNOW!", 10) == 0) { |
454 | dprintk ("Found PSB header at %p\n", p); | 475 | dprintk("Found PSB header at %p\n", p); |
455 | psb = (struct psb_s *) p; | 476 | psb = (struct psb_s *) p; |
456 | dprintk ("Table version: 0x%x\n", psb->tableversion); | 477 | dprintk("Table version: 0x%x\n", psb->tableversion); |
457 | if (psb->tableversion != 0x12) { | 478 | if (psb->tableversion != 0x12) { |
458 | printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n"); | 479 | printk(KERN_INFO PFX "Sorry, only v1.2 tables" |
480 | " supported right now\n"); | ||
459 | return -ENODEV; | 481 | return -ENODEV; |
460 | } | 482 | } |
461 | 483 | ||
462 | dprintk ("Flags: 0x%x\n", psb->flags); | 484 | dprintk("Flags: 0x%x\n", psb->flags); |
463 | if ((psb->flags & 1)==0) { | 485 | if ((psb->flags & 1) == 0) |
464 | dprintk ("Mobile voltage regulator\n"); | 486 | dprintk("Mobile voltage regulator\n"); |
465 | } else { | 487 | else |
466 | dprintk ("Desktop voltage regulator\n"); | 488 | dprintk("Desktop voltage regulator\n"); |
467 | } | ||
468 | 489 | ||
469 | latency = psb->settlingtime; | 490 | latency = psb->settlingtime; |
470 | if (latency < 100) { | 491 | if (latency < 100) { |
471 | printk(KERN_INFO PFX "BIOS set settling time to %d microseconds. " | 492 | printk(KERN_INFO PFX "BIOS set settling time " |
472 | "Should be at least 100. Correcting.\n", latency); | 493 | "to %d microseconds. " |
494 | "Should be at least 100. " | ||
495 | "Correcting.\n", latency); | ||
473 | latency = 100; | 496 | latency = 100; |
474 | } | 497 | } |
475 | dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime); | 498 | dprintk("Settling Time: %d microseconds.\n", |
476 | dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst); | 499 | psb->settlingtime); |
500 | dprintk("Has %d PST tables. (Only dumping ones " | ||
501 | "relevant to this CPU).\n", | ||
502 | psb->numpst); | ||
477 | 503 | ||
478 | p += sizeof (struct psb_s); | 504 | p += sizeof(struct psb_s); |
479 | 505 | ||
480 | pst = (struct pst_s *) p; | 506 | pst = (struct pst_s *) p; |
481 | 507 | ||
482 | for (j=0; j<psb->numpst; j++) { | 508 | for (j = 0; j < psb->numpst; j++) { |
483 | pst = (struct pst_s *) p; | 509 | pst = (struct pst_s *) p; |
484 | number_scales = pst->numpstates; | 510 | number_scales = pst->numpstates; |
485 | 511 | ||
486 | if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) && | 512 | if ((etuple == pst->cpuid) && |
487 | (maxfid==pst->maxfid) && (startvid==pst->startvid)) | 513 | check_fsb(pst->fsbspeed) && |
488 | { | 514 | (maxfid == pst->maxfid) && |
489 | dprintk ("PST:%d (@%p)\n", j, pst); | 515 | (startvid == pst->startvid)) { |
490 | dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", | 516 | print_pst_entry(pst, j); |
491 | pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); | 517 | p = (char *)pst + sizeof(struct pst_s); |
492 | 518 | ret = get_ranges(p); | |
493 | ret = get_ranges ((char *) pst + sizeof (struct pst_s)); | ||
494 | return ret; | 519 | return ret; |
495 | } else { | 520 | } else { |
496 | unsigned int k; | 521 | unsigned int k; |
497 | p = (char *) pst + sizeof (struct pst_s); | 522 | p = (char *)pst + sizeof(struct pst_s); |
498 | for (k=0; k<number_scales; k++) | 523 | for (k = 0; k < number_scales; k++) |
499 | p+=2; | 524 | p += 2; |
500 | } | 525 | } |
501 | } | 526 | } |
502 | printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple); | 527 | printk(KERN_INFO PFX "No PST tables match this cpuid " |
503 | printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n"); | 528 | "(0x%x)\n", etuple); |
529 | printk(KERN_INFO PFX "This is indicative of a broken " | ||
530 | "BIOS.\n"); | ||
504 | 531 | ||
505 | return -EINVAL; | 532 | return -EINVAL; |
506 | } | 533 | } |
@@ -511,13 +538,14 @@ static int powernow_decode_bios (int maxfid, int startvid) | |||
511 | } | 538 | } |
512 | 539 | ||
513 | 540 | ||
514 | static int powernow_target (struct cpufreq_policy *policy, | 541 | static int powernow_target(struct cpufreq_policy *policy, |
515 | unsigned int target_freq, | 542 | unsigned int target_freq, |
516 | unsigned int relation) | 543 | unsigned int relation) |
517 | { | 544 | { |
518 | unsigned int newstate; | 545 | unsigned int newstate; |
519 | 546 | ||
520 | if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate)) | 547 | if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, |
548 | relation, &newstate)) | ||
521 | return -EINVAL; | 549 | return -EINVAL; |
522 | 550 | ||
523 | change_speed(newstate); | 551 | change_speed(newstate); |
@@ -526,7 +554,7 @@ static int powernow_target (struct cpufreq_policy *policy, | |||
526 | } | 554 | } |
527 | 555 | ||
528 | 556 | ||
529 | static int powernow_verify (struct cpufreq_policy *policy) | 557 | static int powernow_verify(struct cpufreq_policy *policy) |
530 | { | 558 | { |
531 | return cpufreq_frequency_table_verify(policy, powernow_table); | 559 | return cpufreq_frequency_table_verify(policy, powernow_table); |
532 | } | 560 | } |
@@ -566,18 +594,23 @@ static unsigned int powernow_get(unsigned int cpu) | |||
566 | 594 | ||
567 | if (cpu) | 595 | if (cpu) |
568 | return 0; | 596 | return 0; |
569 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 597 | rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
570 | cfid = fidvidstatus.bits.CFID; | 598 | cfid = fidvidstatus.bits.CFID; |
571 | 599 | ||
572 | return (fsb * fid_codes[cfid] / 10); | 600 | return fsb * fid_codes[cfid] / 10; |
573 | } | 601 | } |
574 | 602 | ||
575 | 603 | ||
576 | static int __init acer_cpufreq_pst(const struct dmi_system_id *d) | 604 | static int __init acer_cpufreq_pst(const struct dmi_system_id *d) |
577 | { | 605 | { |
578 | printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident); | 606 | printk(KERN_WARNING PFX |
579 | printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n"); | 607 | "%s laptop with broken PST tables in BIOS detected.\n", |
580 | printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n"); | 608 | d->ident); |
609 | printk(KERN_WARNING PFX | ||
610 | "You need to downgrade to 3A21 (09/09/2002), or try a newer " | ||
611 | "BIOS than 3A71 (01/20/2003)\n"); | ||
612 | printk(KERN_WARNING PFX | ||
613 | "cpufreq scaling has been disabled as a result of this.\n"); | ||
581 | return 0; | 614 | return 0; |
582 | } | 615 | } |
583 | 616 | ||
@@ -598,7 +631,7 @@ static struct dmi_system_id __initdata powernow_dmi_table[] = { | |||
598 | { } | 631 | { } |
599 | }; | 632 | }; |
600 | 633 | ||
601 | static int __init powernow_cpu_init (struct cpufreq_policy *policy) | 634 | static int __init powernow_cpu_init(struct cpufreq_policy *policy) |
602 | { | 635 | { |
603 | union msr_fidvidstatus fidvidstatus; | 636 | union msr_fidvidstatus fidvidstatus; |
604 | int result; | 637 | int result; |
@@ -606,7 +639,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
606 | if (policy->cpu != 0) | 639 | if (policy->cpu != 0) |
607 | return -ENODEV; | 640 | return -ENODEV; |
608 | 641 | ||
609 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 642 | rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
610 | 643 | ||
611 | recalibrate_cpu_khz(); | 644 | recalibrate_cpu_khz(); |
612 | 645 | ||
@@ -618,19 +651,21 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
618 | dprintk("FSB: %3dMHz\n", fsb/1000); | 651 | dprintk("FSB: %3dMHz\n", fsb/1000); |
619 | 652 | ||
620 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { | 653 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { |
621 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); | 654 | printk(KERN_INFO PFX "PSB/PST known to be broken. " |
655 | "Trying ACPI instead\n"); | ||
622 | result = powernow_acpi_init(); | 656 | result = powernow_acpi_init(); |
623 | } else { | 657 | } else { |
624 | result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID); | 658 | result = powernow_decode_bios(fidvidstatus.bits.MFID, |
659 | fidvidstatus.bits.SVID); | ||
625 | if (result) { | 660 | if (result) { |
626 | printk (KERN_INFO PFX "Trying ACPI perflib\n"); | 661 | printk(KERN_INFO PFX "Trying ACPI perflib\n"); |
627 | maximum_speed = 0; | 662 | maximum_speed = 0; |
628 | minimum_speed = -1; | 663 | minimum_speed = -1; |
629 | latency = 0; | 664 | latency = 0; |
630 | result = powernow_acpi_init(); | 665 | result = powernow_acpi_init(); |
631 | if (result) { | 666 | if (result) { |
632 | printk (KERN_INFO PFX "ACPI and legacy methods failed\n"); | 667 | printk(KERN_INFO PFX |
633 | printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n"); | 668 | "ACPI and legacy methods failed\n"); |
634 | } | 669 | } |
635 | } else { | 670 | } else { |
636 | /* SGTC use the bus clock as timer */ | 671 | /* SGTC use the bus clock as timer */ |
@@ -642,10 +677,11 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
642 | if (result) | 677 | if (result) |
643 | return result; | 678 | return result; |
644 | 679 | ||
645 | printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", | 680 | printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", |
646 | minimum_speed/1000, maximum_speed/1000); | 681 | minimum_speed/1000, maximum_speed/1000); |
647 | 682 | ||
648 | policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); | 683 | policy->cpuinfo.transition_latency = |
684 | cpufreq_scale(2000000UL, fsb, latency); | ||
649 | 685 | ||
650 | policy->cur = powernow_get(0); | 686 | policy->cur = powernow_get(0); |
651 | 687 | ||
@@ -654,7 +690,8 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
654 | return cpufreq_frequency_table_cpuinfo(policy, powernow_table); | 690 | return cpufreq_frequency_table_cpuinfo(policy, powernow_table); |
655 | } | 691 | } |
656 | 692 | ||
657 | static int powernow_cpu_exit (struct cpufreq_policy *policy) { | 693 | static int powernow_cpu_exit(struct cpufreq_policy *policy) |
694 | { | ||
658 | cpufreq_frequency_table_put_attr(policy->cpu); | 695 | cpufreq_frequency_table_put_attr(policy->cpu); |
659 | 696 | ||
660 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 697 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
@@ -669,7 +706,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) { | |||
669 | return 0; | 706 | return 0; |
670 | } | 707 | } |
671 | 708 | ||
672 | static struct freq_attr* powernow_table_attr[] = { | 709 | static struct freq_attr *powernow_table_attr[] = { |
673 | &cpufreq_freq_attr_scaling_available_freqs, | 710 | &cpufreq_freq_attr_scaling_available_freqs, |
674 | NULL, | 711 | NULL, |
675 | }; | 712 | }; |
@@ -685,15 +722,15 @@ static struct cpufreq_driver powernow_driver = { | |||
685 | .attr = powernow_table_attr, | 722 | .attr = powernow_table_attr, |
686 | }; | 723 | }; |
687 | 724 | ||
688 | static int __init powernow_init (void) | 725 | static int __init powernow_init(void) |
689 | { | 726 | { |
690 | if (check_powernow()==0) | 727 | if (check_powernow() == 0) |
691 | return -ENODEV; | 728 | return -ENODEV; |
692 | return cpufreq_register_driver(&powernow_driver); | 729 | return cpufreq_register_driver(&powernow_driver); |
693 | } | 730 | } |
694 | 731 | ||
695 | 732 | ||
696 | static void __exit powernow_exit (void) | 733 | static void __exit powernow_exit(void) |
697 | { | 734 | { |
698 | cpufreq_unregister_driver(&powernow_driver); | 735 | cpufreq_unregister_driver(&powernow_driver); |
699 | } | 736 | } |
@@ -701,9 +738,9 @@ static void __exit powernow_exit (void) | |||
701 | module_param(acpi_force, int, 0444); | 738 | module_param(acpi_force, int, 0444); |
702 | MODULE_PARM_DESC(acpi_force, "Force ACPI to be used."); | 739 | MODULE_PARM_DESC(acpi_force, "Force ACPI to be used."); |
703 | 740 | ||
704 | MODULE_AUTHOR ("Dave Jones <davej@redhat.com>"); | 741 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
705 | MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors."); | 742 | MODULE_DESCRIPTION("Powernow driver for AMD K7 processors."); |
706 | MODULE_LICENSE ("GPL"); | 743 | MODULE_LICENSE("GPL"); |
707 | 744 | ||
708 | late_initcall(powernow_init); | 745 | late_initcall(powernow_init); |
709 | module_exit(powernow_exit); | 746 | module_exit(powernow_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6428aa17b40e..4709ead2db52 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -33,16 +33,14 @@ | |||
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/cpumask.h> | 34 | #include <linux/cpumask.h> |
35 | #include <linux/sched.h> /* for current / set_cpus_allowed() */ | 35 | #include <linux/sched.h> /* for current / set_cpus_allowed() */ |
36 | #include <linux/io.h> | ||
37 | #include <linux/delay.h> | ||
36 | 38 | ||
37 | #include <asm/msr.h> | 39 | #include <asm/msr.h> |
38 | #include <asm/io.h> | ||
39 | #include <asm/delay.h> | ||
40 | 40 | ||
41 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | ||
42 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
43 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
44 | #include <acpi/processor.h> | 43 | #include <acpi/processor.h> |
45 | #endif | ||
46 | 44 | ||
47 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
48 | #define VERSION "version 2.20.00" | 46 | #define VERSION "version 2.20.00" |
@@ -56,7 +54,10 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data); | |||
56 | static int cpu_family = CPU_OPTERON; | 54 | static int cpu_family = CPU_OPTERON; |
57 | 55 | ||
58 | #ifndef CONFIG_SMP | 56 | #ifndef CONFIG_SMP |
59 | DEFINE_PER_CPU(cpumask_t, cpu_core_map); | 57 | static inline const struct cpumask *cpu_core_mask(int cpu) |
58 | { | ||
59 | return cpumask_of(0); | ||
60 | } | ||
60 | #endif | 61 | #endif |
61 | 62 | ||
62 | /* Return a frequency in MHz, given an input fid */ | 63 | /* Return a frequency in MHz, given an input fid */ |
@@ -71,7 +72,8 @@ static u32 find_khz_freq_from_fid(u32 fid) | |||
71 | return 1000 * find_freq_from_fid(fid); | 72 | return 1000 * find_freq_from_fid(fid); |
72 | } | 73 | } |
73 | 74 | ||
74 | static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate) | 75 | static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, |
76 | u32 pstate) | ||
75 | { | 77 | { |
76 | return data[pstate].frequency; | 78 | return data[pstate].frequency; |
77 | } | 79 | } |
@@ -186,7 +188,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
186 | return 1; | 188 | return 1; |
187 | } | 189 | } |
188 | 190 | ||
189 | lo = fid | (data->currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID; | 191 | lo = fid; |
192 | lo |= (data->currvid << MSR_C_LO_VID_SHIFT); | ||
193 | lo |= MSR_C_LO_INIT_FID_VID; | ||
190 | 194 | ||
191 | dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n", | 195 | dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n", |
192 | fid, lo, data->plllock * PLL_LOCK_CONVERSION); | 196 | fid, lo, data->plllock * PLL_LOCK_CONVERSION); |
@@ -194,7 +198,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
194 | do { | 198 | do { |
195 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); | 199 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); |
196 | if (i++ > 100) { | 200 | if (i++ > 100) { |
197 | printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n"); | 201 | printk(KERN_ERR PFX |
202 | "Hardware error - pending bit very stuck - " | ||
203 | "no further pstate changes possible\n"); | ||
198 | return 1; | 204 | return 1; |
199 | } | 205 | } |
200 | } while (query_current_values_with_pending_wait(data)); | 206 | } while (query_current_values_with_pending_wait(data)); |
@@ -202,14 +208,16 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
202 | count_off_irt(data); | 208 | count_off_irt(data); |
203 | 209 | ||
204 | if (savevid != data->currvid) { | 210 | if (savevid != data->currvid) { |
205 | printk(KERN_ERR PFX "vid change on fid trans, old 0x%x, new 0x%x\n", | 211 | printk(KERN_ERR PFX |
206 | savevid, data->currvid); | 212 | "vid change on fid trans, old 0x%x, new 0x%x\n", |
213 | savevid, data->currvid); | ||
207 | return 1; | 214 | return 1; |
208 | } | 215 | } |
209 | 216 | ||
210 | if (fid != data->currfid) { | 217 | if (fid != data->currfid) { |
211 | printk(KERN_ERR PFX "fid trans failed, fid 0x%x, curr 0x%x\n", fid, | 218 | printk(KERN_ERR PFX |
212 | data->currfid); | 219 | "fid trans failed, fid 0x%x, curr 0x%x\n", fid, |
220 | data->currfid); | ||
213 | return 1; | 221 | return 1; |
214 | } | 222 | } |
215 | 223 | ||
@@ -228,7 +236,9 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
228 | return 1; | 236 | return 1; |
229 | } | 237 | } |
230 | 238 | ||
231 | lo = data->currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID; | 239 | lo = data->currfid; |
240 | lo |= (vid << MSR_C_LO_VID_SHIFT); | ||
241 | lo |= MSR_C_LO_INIT_FID_VID; | ||
232 | 242 | ||
233 | dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n", | 243 | dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n", |
234 | vid, lo, STOP_GRANT_5NS); | 244 | vid, lo, STOP_GRANT_5NS); |
@@ -236,20 +246,24 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
236 | do { | 246 | do { |
237 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); | 247 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); |
238 | if (i++ > 100) { | 248 | if (i++ > 100) { |
239 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); | 249 | printk(KERN_ERR PFX "internal error - pending bit " |
250 | "very stuck - no further pstate " | ||
251 | "changes possible\n"); | ||
240 | return 1; | 252 | return 1; |
241 | } | 253 | } |
242 | } while (query_current_values_with_pending_wait(data)); | 254 | } while (query_current_values_with_pending_wait(data)); |
243 | 255 | ||
244 | if (savefid != data->currfid) { | 256 | if (savefid != data->currfid) { |
245 | printk(KERN_ERR PFX "fid changed on vid trans, old 0x%x new 0x%x\n", | 257 | printk(KERN_ERR PFX "fid changed on vid trans, old " |
258 | "0x%x new 0x%x\n", | ||
246 | savefid, data->currfid); | 259 | savefid, data->currfid); |
247 | return 1; | 260 | return 1; |
248 | } | 261 | } |
249 | 262 | ||
250 | if (vid != data->currvid) { | 263 | if (vid != data->currvid) { |
251 | printk(KERN_ERR PFX "vid trans failed, vid 0x%x, curr 0x%x\n", vid, | 264 | printk(KERN_ERR PFX "vid trans failed, vid 0x%x, " |
252 | data->currvid); | 265 | "curr 0x%x\n", |
266 | vid, data->currvid); | ||
253 | return 1; | 267 | return 1; |
254 | } | 268 | } |
255 | 269 | ||
@@ -261,7 +275,8 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
261 | * Decreasing vid codes represent increasing voltages: | 275 | * Decreasing vid codes represent increasing voltages: |
262 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. | 276 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. |
263 | */ | 277 | */ |
264 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step) | 278 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, |
279 | u32 reqvid, u32 step) | ||
265 | { | 280 | { |
266 | if ((data->currvid - reqvid) > step) | 281 | if ((data->currvid - reqvid) > step) |
267 | reqvid = data->currvid - step; | 282 | reqvid = data->currvid - step; |
@@ -283,7 +298,8 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate) | |||
283 | } | 298 | } |
284 | 299 | ||
285 | /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ | 300 | /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ |
286 | static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid) | 301 | static int transition_fid_vid(struct powernow_k8_data *data, |
302 | u32 reqfid, u32 reqvid) | ||
287 | { | 303 | { |
288 | if (core_voltage_pre_transition(data, reqvid)) | 304 | if (core_voltage_pre_transition(data, reqvid)) |
289 | return 1; | 305 | return 1; |
@@ -298,7 +314,8 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req | |||
298 | return 1; | 314 | return 1; |
299 | 315 | ||
300 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { | 316 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { |
301 | printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, curr 0x%x 0x%x\n", | 317 | printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, " |
318 | "curr 0x%x 0x%x\n", | ||
302 | smp_processor_id(), | 319 | smp_processor_id(), |
303 | reqfid, reqvid, data->currfid, data->currvid); | 320 | reqfid, reqvid, data->currfid, data->currvid); |
304 | return 1; | 321 | return 1; |
@@ -311,13 +328,15 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req | |||
311 | } | 328 | } |
312 | 329 | ||
313 | /* Phase 1 - core voltage transition ... setup voltage */ | 330 | /* Phase 1 - core voltage transition ... setup voltage */ |
314 | static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid) | 331 | static int core_voltage_pre_transition(struct powernow_k8_data *data, |
332 | u32 reqvid) | ||
315 | { | 333 | { |
316 | u32 rvosteps = data->rvo; | 334 | u32 rvosteps = data->rvo; |
317 | u32 savefid = data->currfid; | 335 | u32 savefid = data->currfid; |
318 | u32 maxvid, lo; | 336 | u32 maxvid, lo; |
319 | 337 | ||
320 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", | 338 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " |
339 | "reqvid 0x%x, rvo 0x%x\n", | ||
321 | smp_processor_id(), | 340 | smp_processor_id(), |
322 | data->currfid, data->currvid, reqvid, data->rvo); | 341 | data->currfid, data->currvid, reqvid, data->rvo); |
323 | 342 | ||
@@ -340,7 +359,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
340 | } else { | 359 | } else { |
341 | dprintk("ph1: changing vid for rvo, req 0x%x\n", | 360 | dprintk("ph1: changing vid for rvo, req 0x%x\n", |
342 | data->currvid - 1); | 361 | data->currvid - 1); |
343 | if (decrease_vid_code_by_step(data, data->currvid - 1, 1)) | 362 | if (decrease_vid_code_by_step(data, data->currvid-1, 1)) |
344 | return 1; | 363 | return 1; |
345 | rvosteps--; | 364 | rvosteps--; |
346 | } | 365 | } |
@@ -350,7 +369,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
350 | return 1; | 369 | return 1; |
351 | 370 | ||
352 | if (savefid != data->currfid) { | 371 | if (savefid != data->currfid) { |
353 | printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", data->currfid); | 372 | printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", |
373 | data->currfid); | ||
354 | return 1; | 374 | return 1; |
355 | } | 375 | } |
356 | 376 | ||
@@ -363,20 +383,24 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
363 | /* Phase 2 - core frequency transition */ | 383 | /* Phase 2 - core frequency transition */ |
364 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | 384 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) |
365 | { | 385 | { |
366 | u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid; | 386 | u32 vcoreqfid, vcocurrfid, vcofiddiff; |
387 | u32 fid_interval, savevid = data->currvid; | ||
367 | 388 | ||
368 | if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 389 | if ((reqfid < HI_FID_TABLE_BOTTOM) && |
369 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n", | 390 | (data->currfid < HI_FID_TABLE_BOTTOM)) { |
370 | reqfid, data->currfid); | 391 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition " |
392 | "0x%x 0x%x\n", reqfid, data->currfid); | ||
371 | return 1; | 393 | return 1; |
372 | } | 394 | } |
373 | 395 | ||
374 | if (data->currfid == reqfid) { | 396 | if (data->currfid == reqfid) { |
375 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", data->currfid); | 397 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", |
398 | data->currfid); | ||
376 | return 0; | 399 | return 0; |
377 | } | 400 | } |
378 | 401 | ||
379 | dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n", | 402 | dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " |
403 | "reqfid 0x%x\n", | ||
380 | smp_processor_id(), | 404 | smp_processor_id(), |
381 | data->currfid, data->currvid, reqfid); | 405 | data->currfid, data->currvid, reqfid); |
382 | 406 | ||
@@ -390,14 +414,14 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
390 | 414 | ||
391 | if (reqfid > data->currfid) { | 415 | if (reqfid > data->currfid) { |
392 | if (data->currfid > LO_FID_TABLE_TOP) { | 416 | if (data->currfid > LO_FID_TABLE_TOP) { |
393 | if (write_new_fid(data, data->currfid + fid_interval)) { | 417 | if (write_new_fid(data, |
418 | data->currfid + fid_interval)) | ||
394 | return 1; | 419 | return 1; |
395 | } | ||
396 | } else { | 420 | } else { |
397 | if (write_new_fid | 421 | if (write_new_fid |
398 | (data, 2 + convert_fid_to_vco_fid(data->currfid))) { | 422 | (data, |
423 | 2 + convert_fid_to_vco_fid(data->currfid))) | ||
399 | return 1; | 424 | return 1; |
400 | } | ||
401 | } | 425 | } |
402 | } else { | 426 | } else { |
403 | if (write_new_fid(data, data->currfid - fid_interval)) | 427 | if (write_new_fid(data, data->currfid - fid_interval)) |
@@ -417,7 +441,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
417 | 441 | ||
418 | if (data->currfid != reqfid) { | 442 | if (data->currfid != reqfid) { |
419 | printk(KERN_ERR PFX | 443 | printk(KERN_ERR PFX |
420 | "ph2: mismatch, failed fid transition, curr 0x%x, req 0x%x\n", | 444 | "ph2: mismatch, failed fid transition, " |
445 | "curr 0x%x, req 0x%x\n", | ||
421 | data->currfid, reqfid); | 446 | data->currfid, reqfid); |
422 | return 1; | 447 | return 1; |
423 | } | 448 | } |
@@ -435,7 +460,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
435 | } | 460 | } |
436 | 461 | ||
437 | /* Phase 3 - core voltage transition flow ... jump to the final vid. */ | 462 | /* Phase 3 - core voltage transition flow ... jump to the final vid. */ |
438 | static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid) | 463 | static int core_voltage_post_transition(struct powernow_k8_data *data, |
464 | u32 reqvid) | ||
439 | { | 465 | { |
440 | u32 savefid = data->currfid; | 466 | u32 savefid = data->currfid; |
441 | u32 savereqvid = reqvid; | 467 | u32 savereqvid = reqvid; |
@@ -457,7 +483,8 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
457 | 483 | ||
458 | if (data->currvid != reqvid) { | 484 | if (data->currvid != reqvid) { |
459 | printk(KERN_ERR PFX | 485 | printk(KERN_ERR PFX |
460 | "ph3: failed vid transition\n, req 0x%x, curr 0x%x", | 486 | "ph3: failed vid transition\n, " |
487 | "req 0x%x, curr 0x%x", | ||
461 | reqvid, data->currvid); | 488 | reqvid, data->currvid); |
462 | return 1; | 489 | return 1; |
463 | } | 490 | } |
@@ -508,7 +535,8 @@ static int check_supported_cpu(unsigned int cpu) | |||
508 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { | 535 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { |
509 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 536 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
510 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { | 537 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { |
511 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); | 538 | printk(KERN_INFO PFX |
539 | "Processor cpuid %x not supported\n", eax); | ||
512 | goto out; | 540 | goto out; |
513 | } | 541 | } |
514 | 542 | ||
@@ -520,8 +548,10 @@ static int check_supported_cpu(unsigned int cpu) | |||
520 | } | 548 | } |
521 | 549 | ||
522 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); | 550 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); |
523 | if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) { | 551 | if ((edx & P_STATE_TRANSITION_CAPABLE) |
524 | printk(KERN_INFO PFX "Power state transitions not supported\n"); | 552 | != P_STATE_TRANSITION_CAPABLE) { |
553 | printk(KERN_INFO PFX | ||
554 | "Power state transitions not supported\n"); | ||
525 | goto out; | 555 | goto out; |
526 | } | 556 | } |
527 | } else { /* must be a HW Pstate capable processor */ | 557 | } else { /* must be a HW Pstate capable processor */ |
@@ -539,7 +569,8 @@ out: | |||
539 | return rc; | 569 | return rc; |
540 | } | 570 | } |
541 | 571 | ||
542 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) | 572 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, |
573 | u8 maxvid) | ||
543 | { | 574 | { |
544 | unsigned int j; | 575 | unsigned int j; |
545 | u8 lastfid = 0xff; | 576 | u8 lastfid = 0xff; |
@@ -550,12 +581,14 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
550 | j, pst[j].vid); | 581 | j, pst[j].vid); |
551 | return -EINVAL; | 582 | return -EINVAL; |
552 | } | 583 | } |
553 | if (pst[j].vid < data->rvo) { /* vid + rvo >= 0 */ | 584 | if (pst[j].vid < data->rvo) { |
585 | /* vid + rvo >= 0 */ | ||
554 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" | 586 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" |
555 | " %d\n", j); | 587 | " %d\n", j); |
556 | return -ENODEV; | 588 | return -ENODEV; |
557 | } | 589 | } |
558 | if (pst[j].vid < maxvid + data->rvo) { /* vid + rvo >= maxvid */ | 590 | if (pst[j].vid < maxvid + data->rvo) { |
591 | /* vid + rvo >= maxvid */ | ||
559 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" | 592 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" |
560 | " %d\n", j); | 593 | " %d\n", j); |
561 | return -ENODEV; | 594 | return -ENODEV; |
@@ -579,23 +612,31 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
579 | return -EINVAL; | 612 | return -EINVAL; |
580 | } | 613 | } |
581 | if (lastfid > LO_FID_TABLE_TOP) | 614 | if (lastfid > LO_FID_TABLE_TOP) |
582 | printk(KERN_INFO FW_BUG PFX "first fid not from lo freq table\n"); | 615 | printk(KERN_INFO FW_BUG PFX |
616 | "first fid not from lo freq table\n"); | ||
583 | 617 | ||
584 | return 0; | 618 | return 0; |
585 | } | 619 | } |
586 | 620 | ||
621 | static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry) | ||
622 | { | ||
623 | data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID; | ||
624 | } | ||
625 | |||
587 | static void print_basics(struct powernow_k8_data *data) | 626 | static void print_basics(struct powernow_k8_data *data) |
588 | { | 627 | { |
589 | int j; | 628 | int j; |
590 | for (j = 0; j < data->numps; j++) { | 629 | for (j = 0; j < data->numps; j++) { |
591 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { | 630 | if (data->powernow_table[j].frequency != |
631 | CPUFREQ_ENTRY_INVALID) { | ||
592 | if (cpu_family == CPU_HW_PSTATE) { | 632 | if (cpu_family == CPU_HW_PSTATE) { |
593 | printk(KERN_INFO PFX " %d : pstate %d (%d MHz)\n", | 633 | printk(KERN_INFO PFX |
594 | j, | 634 | " %d : pstate %d (%d MHz)\n", j, |
595 | data->powernow_table[j].index, | 635 | data->powernow_table[j].index, |
596 | data->powernow_table[j].frequency/1000); | 636 | data->powernow_table[j].frequency/1000); |
597 | } else { | 637 | } else { |
598 | printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", | 638 | printk(KERN_INFO PFX |
639 | " %d : fid 0x%x (%d MHz), vid 0x%x\n", | ||
599 | j, | 640 | j, |
600 | data->powernow_table[j].index & 0xff, | 641 | data->powernow_table[j].index & 0xff, |
601 | data->powernow_table[j].frequency/1000, | 642 | data->powernow_table[j].frequency/1000, |
@@ -604,20 +645,25 @@ static void print_basics(struct powernow_k8_data *data) | |||
604 | } | 645 | } |
605 | } | 646 | } |
606 | if (data->batps) | 647 | if (data->batps) |
607 | printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps); | 648 | printk(KERN_INFO PFX "Only %d pstates on battery\n", |
649 | data->batps); | ||
608 | } | 650 | } |
609 | 651 | ||
610 | static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) | 652 | static int fill_powernow_table(struct powernow_k8_data *data, |
653 | struct pst_s *pst, u8 maxvid) | ||
611 | { | 654 | { |
612 | struct cpufreq_frequency_table *powernow_table; | 655 | struct cpufreq_frequency_table *powernow_table; |
613 | unsigned int j; | 656 | unsigned int j; |
614 | 657 | ||
615 | if (data->batps) { /* use ACPI support to get full speed on mains power */ | 658 | if (data->batps) { |
616 | printk(KERN_WARNING PFX "Only %d pstates usable (use ACPI driver for full range\n", data->batps); | 659 | /* use ACPI support to get full speed on mains power */ |
660 | printk(KERN_WARNING PFX | ||
661 | "Only %d pstates usable (use ACPI driver for full " | ||
662 | "range\n", data->batps); | ||
617 | data->numps = data->batps; | 663 | data->numps = data->batps; |
618 | } | 664 | } |
619 | 665 | ||
620 | for ( j=1; j<data->numps; j++ ) { | 666 | for (j = 1; j < data->numps; j++) { |
621 | if (pst[j-1].fid >= pst[j].fid) { | 667 | if (pst[j-1].fid >= pst[j].fid) { |
622 | printk(KERN_ERR PFX "PST out of sequence\n"); | 668 | printk(KERN_ERR PFX "PST out of sequence\n"); |
623 | return -EINVAL; | 669 | return -EINVAL; |
@@ -640,9 +686,11 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, | |||
640 | } | 686 | } |
641 | 687 | ||
642 | for (j = 0; j < data->numps; j++) { | 688 | for (j = 0; j < data->numps; j++) { |
689 | int freq; | ||
643 | powernow_table[j].index = pst[j].fid; /* lower 8 bits */ | 690 | powernow_table[j].index = pst[j].fid; /* lower 8 bits */ |
644 | powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ | 691 | powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ |
645 | powernow_table[j].frequency = find_khz_freq_from_fid(pst[j].fid); | 692 | freq = find_khz_freq_from_fid(pst[j].fid); |
693 | powernow_table[j].frequency = freq; | ||
646 | } | 694 | } |
647 | powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; | 695 | powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; |
648 | powernow_table[data->numps].index = 0; | 696 | powernow_table[data->numps].index = 0; |
@@ -654,11 +702,12 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, | |||
654 | 702 | ||
655 | dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); | 703 | dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); |
656 | data->powernow_table = powernow_table; | 704 | data->powernow_table = powernow_table; |
657 | if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) | 705 | if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) |
658 | print_basics(data); | 706 | print_basics(data); |
659 | 707 | ||
660 | for (j = 0; j < data->numps; j++) | 708 | for (j = 0; j < data->numps; j++) |
661 | if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid)) | 709 | if ((pst[j].fid == data->currfid) && |
710 | (pst[j].vid == data->currvid)) | ||
662 | return 0; | 711 | return 0; |
663 | 712 | ||
664 | dprintk("currfid/vid do not match PST, ignoring\n"); | 713 | dprintk("currfid/vid do not match PST, ignoring\n"); |
@@ -698,7 +747,8 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
698 | } | 747 | } |
699 | 748 | ||
700 | data->vstable = psb->vstable; | 749 | data->vstable = psb->vstable; |
701 | dprintk("voltage stabilization time: %d(*20us)\n", data->vstable); | 750 | dprintk("voltage stabilization time: %d(*20us)\n", |
751 | data->vstable); | ||
702 | 752 | ||
703 | dprintk("flags2: 0x%x\n", psb->flags2); | 753 | dprintk("flags2: 0x%x\n", psb->flags2); |
704 | data->rvo = psb->flags2 & 3; | 754 | data->rvo = psb->flags2 & 3; |
@@ -713,11 +763,12 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
713 | 763 | ||
714 | dprintk("numpst: 0x%x\n", psb->num_tables); | 764 | dprintk("numpst: 0x%x\n", psb->num_tables); |
715 | cpst = psb->num_tables; | 765 | cpst = psb->num_tables; |
716 | if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){ | 766 | if ((psb->cpuid == 0x00000fc0) || |
767 | (psb->cpuid == 0x00000fe0)) { | ||
717 | thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | 768 | thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); |
718 | if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) { | 769 | if ((thiscpuid == 0x00000fc0) || |
770 | (thiscpuid == 0x00000fe0)) | ||
719 | cpst = 1; | 771 | cpst = 1; |
720 | } | ||
721 | } | 772 | } |
722 | if (cpst != 1) { | 773 | if (cpst != 1) { |
723 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); | 774 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); |
@@ -732,7 +783,8 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
732 | 783 | ||
733 | data->numps = psb->numps; | 784 | data->numps = psb->numps; |
734 | dprintk("numpstates: 0x%x\n", data->numps); | 785 | dprintk("numpstates: 0x%x\n", data->numps); |
735 | return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid); | 786 | return fill_powernow_table(data, |
787 | (struct pst_s *)(psb+1), maxvid); | ||
736 | } | 788 | } |
737 | /* | 789 | /* |
738 | * If you see this message, complain to BIOS manufacturer. If | 790 | * If you see this message, complain to BIOS manufacturer. If |
@@ -745,28 +797,31 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
745 | * BIOS and Kernel Developer's Guide, which is available on | 797 | * BIOS and Kernel Developer's Guide, which is available on |
746 | * www.amd.com | 798 | * www.amd.com |
747 | */ | 799 | */ |
748 | printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n"); | 800 | printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n"); |
749 | return -ENODEV; | 801 | return -ENODEV; |
750 | } | 802 | } |
751 | 803 | ||
752 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 804 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, |
753 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) | 805 | unsigned int index) |
754 | { | 806 | { |
807 | acpi_integer control; | ||
808 | |||
755 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) | 809 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) |
756 | return; | 810 | return; |
757 | 811 | ||
758 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; | 812 | control = data->acpi_data.states[index].control; data->irt = (control |
759 | data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; | 813 | >> IRT_SHIFT) & IRT_MASK; data->rvo = (control >> |
760 | data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; | 814 | RVO_SHIFT) & RVO_MASK; data->exttype = (control |
761 | data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; | 815 | >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; |
762 | data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); | 816 | data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1 |
763 | data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; | 817 | << ((control >> MVS_SHIFT) & MVS_MASK); data->vstable = |
764 | } | 818 | (control >> VST_SHIFT) & VST_MASK; } |
765 | 819 | ||
766 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | 820 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) |
767 | { | 821 | { |
768 | struct cpufreq_frequency_table *powernow_table; | 822 | struct cpufreq_frequency_table *powernow_table; |
769 | int ret_val = -ENODEV; | 823 | int ret_val = -ENODEV; |
824 | acpi_integer space_id; | ||
770 | 825 | ||
771 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 826 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
772 | dprintk("register performance failed: bad ACPI data\n"); | 827 | dprintk("register performance failed: bad ACPI data\n"); |
@@ -779,11 +834,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
779 | goto err_out; | 834 | goto err_out; |
780 | } | 835 | } |
781 | 836 | ||
782 | if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || | 837 | space_id = data->acpi_data.control_register.space_id; |
783 | (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | 838 | if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || |
839 | (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | ||
784 | dprintk("Invalid control/status registers (%x - %x)\n", | 840 | dprintk("Invalid control/status registers (%x - %x)\n", |
785 | data->acpi_data.control_register.space_id, | 841 | data->acpi_data.control_register.space_id, |
786 | data->acpi_data.status_register.space_id); | 842 | space_id); |
787 | goto err_out; | 843 | goto err_out; |
788 | } | 844 | } |
789 | 845 | ||
@@ -802,13 +858,14 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
802 | if (ret_val) | 858 | if (ret_val) |
803 | goto err_out_mem; | 859 | goto err_out_mem; |
804 | 860 | ||
805 | powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END; | 861 | powernow_table[data->acpi_data.state_count].frequency = |
862 | CPUFREQ_TABLE_END; | ||
806 | powernow_table[data->acpi_data.state_count].index = 0; | 863 | powernow_table[data->acpi_data.state_count].index = 0; |
807 | data->powernow_table = powernow_table; | 864 | data->powernow_table = powernow_table; |
808 | 865 | ||
809 | /* fill in data */ | 866 | /* fill in data */ |
810 | data->numps = data->acpi_data.state_count; | 867 | data->numps = data->acpi_data.state_count; |
811 | if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) | 868 | if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) |
812 | print_basics(data); | 869 | print_basics(data); |
813 | powernow_k8_acpi_pst_values(data, 0); | 870 | powernow_k8_acpi_pst_values(data, 0); |
814 | 871 | ||
@@ -830,13 +887,15 @@ err_out_mem: | |||
830 | err_out: | 887 | err_out: |
831 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 888 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); |
832 | 889 | ||
833 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ | 890 | /* data->acpi_data.state_count informs us at ->exit() |
891 | * whether ACPI was used */ | ||
834 | data->acpi_data.state_count = 0; | 892 | data->acpi_data.state_count = 0; |
835 | 893 | ||
836 | return ret_val; | 894 | return ret_val; |
837 | } | 895 | } |
838 | 896 | ||
839 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 897 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, |
898 | struct cpufreq_frequency_table *powernow_table) | ||
840 | { | 899 | { |
841 | int i; | 900 | int i; |
842 | u32 hi = 0, lo = 0; | 901 | u32 hi = 0, lo = 0; |
@@ -848,84 +907,101 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf | |||
848 | 907 | ||
849 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; | 908 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; |
850 | if (index > data->max_hw_pstate) { | 909 | if (index > data->max_hw_pstate) { |
851 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); | 910 | printk(KERN_ERR PFX "invalid pstate %d - " |
852 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); | 911 | "bad value %d.\n", i, index); |
853 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 912 | printk(KERN_ERR PFX "Please report to BIOS " |
913 | "manufacturer\n"); | ||
914 | invalidate_entry(data, i); | ||
854 | continue; | 915 | continue; |
855 | } | 916 | } |
856 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); | 917 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); |
857 | if (!(hi & HW_PSTATE_VALID_MASK)) { | 918 | if (!(hi & HW_PSTATE_VALID_MASK)) { |
858 | dprintk("invalid pstate %d, ignoring\n", index); | 919 | dprintk("invalid pstate %d, ignoring\n", index); |
859 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 920 | invalidate_entry(data, i); |
860 | continue; | 921 | continue; |
861 | } | 922 | } |
862 | 923 | ||
863 | powernow_table[i].index = index; | 924 | powernow_table[i].index = index; |
864 | 925 | ||
865 | powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; | 926 | powernow_table[i].frequency = |
927 | data->acpi_data.states[i].core_frequency * 1000; | ||
866 | } | 928 | } |
867 | return 0; | 929 | return 0; |
868 | } | 930 | } |
869 | 931 | ||
870 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 932 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, |
933 | struct cpufreq_frequency_table *powernow_table) | ||
871 | { | 934 | { |
872 | int i; | 935 | int i; |
873 | int cntlofreq = 0; | 936 | int cntlofreq = 0; |
937 | |||
874 | for (i = 0; i < data->acpi_data.state_count; i++) { | 938 | for (i = 0; i < data->acpi_data.state_count; i++) { |
875 | u32 fid; | 939 | u32 fid; |
876 | u32 vid; | 940 | u32 vid; |
941 | u32 freq, index; | ||
942 | acpi_integer status, control; | ||
877 | 943 | ||
878 | if (data->exttype) { | 944 | if (data->exttype) { |
879 | fid = data->acpi_data.states[i].status & EXT_FID_MASK; | 945 | status = data->acpi_data.states[i].status; |
880 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; | 946 | fid = status & EXT_FID_MASK; |
947 | vid = (status >> VID_SHIFT) & EXT_VID_MASK; | ||
881 | } else { | 948 | } else { |
882 | fid = data->acpi_data.states[i].control & FID_MASK; | 949 | control = data->acpi_data.states[i].control; |
883 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; | 950 | fid = control & FID_MASK; |
951 | vid = (control >> VID_SHIFT) & VID_MASK; | ||
884 | } | 952 | } |
885 | 953 | ||
886 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); | 954 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); |
887 | 955 | ||
888 | powernow_table[i].index = fid; /* lower 8 bits */ | 956 | index = fid | (vid<<8); |
889 | powernow_table[i].index |= (vid << 8); /* upper 8 bits */ | 957 | powernow_table[i].index = index; |
890 | powernow_table[i].frequency = find_khz_freq_from_fid(fid); | 958 | |
959 | freq = find_khz_freq_from_fid(fid); | ||
960 | powernow_table[i].frequency = freq; | ||
891 | 961 | ||
892 | /* verify frequency is OK */ | 962 | /* verify frequency is OK */ |
893 | if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) || | 963 | if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) { |
894 | (powernow_table[i].frequency < (MIN_FREQ * 1000))) { | 964 | dprintk("invalid freq %u kHz, ignoring\n", freq); |
895 | dprintk("invalid freq %u kHz, ignoring\n", powernow_table[i].frequency); | 965 | invalidate_entry(data, i); |
896 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
897 | continue; | 966 | continue; |
898 | } | 967 | } |
899 | 968 | ||
900 | /* verify voltage is OK - BIOSs are using "off" to indicate invalid */ | 969 | /* verify voltage is OK - |
970 | * BIOSs are using "off" to indicate invalid */ | ||
901 | if (vid == VID_OFF) { | 971 | if (vid == VID_OFF) { |
902 | dprintk("invalid vid %u, ignoring\n", vid); | 972 | dprintk("invalid vid %u, ignoring\n", vid); |
903 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 973 | invalidate_entry(data, i); |
904 | continue; | 974 | continue; |
905 | } | 975 | } |
906 | 976 | ||
907 | /* verify only 1 entry from the lo frequency table */ | 977 | /* verify only 1 entry from the lo frequency table */ |
908 | if (fid < HI_FID_TABLE_BOTTOM) { | 978 | if (fid < HI_FID_TABLE_BOTTOM) { |
909 | if (cntlofreq) { | 979 | if (cntlofreq) { |
910 | /* if both entries are the same, ignore this one ... */ | 980 | /* if both entries are the same, |
911 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 981 | * ignore this one ... */ |
912 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 982 | if ((freq != powernow_table[cntlofreq].frequency) || |
913 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 983 | (index != powernow_table[cntlofreq].index)) { |
984 | printk(KERN_ERR PFX | ||
985 | "Too many lo freq table " | ||
986 | "entries\n"); | ||
914 | return 1; | 987 | return 1; |
915 | } | 988 | } |
916 | 989 | ||
917 | dprintk("double low frequency table entry, ignoring it.\n"); | 990 | dprintk("double low frequency table entry, " |
918 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 991 | "ignoring it.\n"); |
992 | invalidate_entry(data, i); | ||
919 | continue; | 993 | continue; |
920 | } else | 994 | } else |
921 | cntlofreq = i; | 995 | cntlofreq = i; |
922 | } | 996 | } |
923 | 997 | ||
924 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | 998 | if (freq != (data->acpi_data.states[i].core_frequency * 1000)) { |
925 | printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", | 999 | printk(KERN_INFO PFX "invalid freq entries " |
926 | powernow_table[i].frequency, | 1000 | "%u kHz vs. %u kHz\n", freq, |
927 | (unsigned int) (data->acpi_data.states[i].core_frequency * 1000)); | 1001 | (unsigned int) |
928 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 1002 | (data->acpi_data.states[i].core_frequency |
1003 | * 1000)); | ||
1004 | invalidate_entry(data, i); | ||
929 | continue; | 1005 | continue; |
930 | } | 1006 | } |
931 | } | 1007 | } |
@@ -935,7 +1011,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
935 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | 1011 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) |
936 | { | 1012 | { |
937 | if (data->acpi_data.state_count) | 1013 | if (data->acpi_data.state_count) |
938 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 1014 | acpi_processor_unregister_performance(&data->acpi_data, |
1015 | data->cpu); | ||
939 | free_cpumask_var(data->acpi_data.shared_cpu_map); | 1016 | free_cpumask_var(data->acpi_data.shared_cpu_map); |
940 | } | 1017 | } |
941 | 1018 | ||
@@ -953,15 +1030,9 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
953 | return 1000 * max_latency; | 1030 | return 1000 * max_latency; |
954 | } | 1031 | } |
955 | 1032 | ||
956 | #else | ||
957 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } | ||
958 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } | ||
959 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } | ||
960 | static int get_transition_latency(struct powernow_k8_data *data) { return 0; } | ||
961 | #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ | ||
962 | |||
963 | /* Take a frequency, and issue the fid/vid transition command */ | 1033 | /* Take a frequency, and issue the fid/vid transition command */ |
964 | static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index) | 1034 | static int transition_frequency_fidvid(struct powernow_k8_data *data, |
1035 | unsigned int index) | ||
965 | { | 1036 | { |
966 | u32 fid = 0; | 1037 | u32 fid = 0; |
967 | u32 vid = 0; | 1038 | u32 vid = 0; |
@@ -989,7 +1060,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i | |||
989 | return 0; | 1060 | return 0; |
990 | } | 1061 | } |
991 | 1062 | ||
992 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 1063 | if ((fid < HI_FID_TABLE_BOTTOM) && |
1064 | (data->currfid < HI_FID_TABLE_BOTTOM)) { | ||
993 | printk(KERN_ERR PFX | 1065 | printk(KERN_ERR PFX |
994 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | 1066 | "ignoring illegal change in lo freq table-%x to 0x%x\n", |
995 | data->currfid, fid); | 1067 | data->currfid, fid); |
@@ -1017,7 +1089,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i | |||
1017 | } | 1089 | } |
1018 | 1090 | ||
1019 | /* Take a frequency, and issue the hardware pstate transition command */ | 1091 | /* Take a frequency, and issue the hardware pstate transition command */ |
1020 | static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index) | 1092 | static int transition_frequency_pstate(struct powernow_k8_data *data, |
1093 | unsigned int index) | ||
1021 | { | 1094 | { |
1022 | u32 pstate = 0; | 1095 | u32 pstate = 0; |
1023 | int res, i; | 1096 | int res, i; |
@@ -1029,7 +1102,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1029 | pstate = index & HW_PSTATE_MASK; | 1102 | pstate = index & HW_PSTATE_MASK; |
1030 | if (pstate > data->max_hw_pstate) | 1103 | if (pstate > data->max_hw_pstate) |
1031 | return 0; | 1104 | return 0; |
1032 | freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); | 1105 | freqs.old = find_khz_freq_from_pstate(data->powernow_table, |
1106 | data->currpstate); | ||
1033 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); | 1107 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); |
1034 | 1108 | ||
1035 | for_each_cpu_mask_nr(i, *(data->available_cores)) { | 1109 | for_each_cpu_mask_nr(i, *(data->available_cores)) { |
@@ -1048,7 +1122,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1048 | } | 1122 | } |
1049 | 1123 | ||
1050 | /* Driver entry point to switch to the target frequency */ | 1124 | /* Driver entry point to switch to the target frequency */ |
1051 | static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation) | 1125 | static int powernowk8_target(struct cpufreq_policy *pol, |
1126 | unsigned targfreq, unsigned relation) | ||
1052 | { | 1127 | { |
1053 | cpumask_t oldmask; | 1128 | cpumask_t oldmask; |
1054 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1129 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
@@ -1087,14 +1162,18 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1087 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", | 1162 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", |
1088 | data->currfid, data->currvid); | 1163 | data->currfid, data->currvid); |
1089 | 1164 | ||
1090 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { | 1165 | if ((checkvid != data->currvid) || |
1166 | (checkfid != data->currfid)) { | ||
1091 | printk(KERN_INFO PFX | 1167 | printk(KERN_INFO PFX |
1092 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", | 1168 | "error - out of sync, fix 0x%x 0x%x, " |
1093 | checkfid, data->currfid, checkvid, data->currvid); | 1169 | "vid 0x%x 0x%x\n", |
1170 | checkfid, data->currfid, | ||
1171 | checkvid, data->currvid); | ||
1094 | } | 1172 | } |
1095 | } | 1173 | } |
1096 | 1174 | ||
1097 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 1175 | if (cpufreq_frequency_table_target(pol, data->powernow_table, |
1176 | targfreq, relation, &newstate)) | ||
1098 | goto err_out; | 1177 | goto err_out; |
1099 | 1178 | ||
1100 | mutex_lock(&fidvid_mutex); | 1179 | mutex_lock(&fidvid_mutex); |
@@ -1114,7 +1193,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1114 | mutex_unlock(&fidvid_mutex); | 1193 | mutex_unlock(&fidvid_mutex); |
1115 | 1194 | ||
1116 | if (cpu_family == CPU_HW_PSTATE) | 1195 | if (cpu_family == CPU_HW_PSTATE) |
1117 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate); | 1196 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, |
1197 | newstate); | ||
1118 | else | 1198 | else |
1119 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1199 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1120 | ret = 0; | 1200 | ret = 0; |
@@ -1141,6 +1221,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1141 | struct powernow_k8_data *data; | 1221 | struct powernow_k8_data *data; |
1142 | cpumask_t oldmask; | 1222 | cpumask_t oldmask; |
1143 | int rc; | 1223 | int rc; |
1224 | static int print_once; | ||
1144 | 1225 | ||
1145 | if (!cpu_online(pol->cpu)) | 1226 | if (!cpu_online(pol->cpu)) |
1146 | return -ENODEV; | 1227 | return -ENODEV; |
@@ -1163,33 +1244,31 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1163 | * an UP version, and is deprecated by AMD. | 1244 | * an UP version, and is deprecated by AMD. |
1164 | */ | 1245 | */ |
1165 | if (num_online_cpus() != 1) { | 1246 | if (num_online_cpus() != 1) { |
1166 | #ifndef CONFIG_ACPI_PROCESSOR | 1247 | /* |
1167 | printk(KERN_ERR PFX "ACPI Processor support is required " | 1248 | * Replace this one with print_once as soon as such a |
1168 | "for SMP systems but is absent. Please load the " | 1249 | * thing gets introduced |
1169 | "ACPI Processor module before starting this " | 1250 | */ |
1170 | "driver.\n"); | 1251 | if (!print_once) { |
1171 | #else | 1252 | WARN_ONCE(1, KERN_ERR FW_BUG PFX "Your BIOS " |
1172 | printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide" | 1253 | "does not provide ACPI _PSS objects " |
1173 | " ACPI _PSS objects in a way that Linux " | 1254 | "in a way that Linux understands. " |
1174 | "understands. Please report this to the Linux " | 1255 | "Please report this to the Linux ACPI" |
1175 | "ACPI maintainers and complain to your BIOS " | 1256 | " maintainers and complain to your " |
1176 | "vendor.\n"); | 1257 | "BIOS vendor.\n"); |
1177 | #endif | 1258 | print_once++; |
1178 | kfree(data); | 1259 | } |
1179 | return -ENODEV; | 1260 | goto err_out; |
1180 | } | 1261 | } |
1181 | if (pol->cpu != 0) { | 1262 | if (pol->cpu != 0) { |
1182 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " | 1263 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " |
1183 | "CPU other than CPU0. Complain to your BIOS " | 1264 | "CPU other than CPU0. Complain to your BIOS " |
1184 | "vendor.\n"); | 1265 | "vendor.\n"); |
1185 | kfree(data); | 1266 | goto err_out; |
1186 | return -ENODEV; | ||
1187 | } | 1267 | } |
1188 | rc = find_psb_table(data); | 1268 | rc = find_psb_table(data); |
1189 | if (rc) { | 1269 | if (rc) |
1190 | kfree(data); | 1270 | goto err_out; |
1191 | return -ENODEV; | 1271 | |
1192 | } | ||
1193 | /* Take a crude guess here. | 1272 | /* Take a crude guess here. |
1194 | * That guess was in microseconds, so multiply with 1000 */ | 1273 | * That guess was in microseconds, so multiply with 1000 */ |
1195 | pol->cpuinfo.transition_latency = ( | 1274 | pol->cpuinfo.transition_latency = ( |
@@ -1204,16 +1283,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1204 | 1283 | ||
1205 | if (smp_processor_id() != pol->cpu) { | 1284 | if (smp_processor_id() != pol->cpu) { |
1206 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1285 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
1207 | goto err_out; | 1286 | goto err_out_unmask; |
1208 | } | 1287 | } |
1209 | 1288 | ||
1210 | if (pending_bit_stuck()) { | 1289 | if (pending_bit_stuck()) { |
1211 | printk(KERN_ERR PFX "failing init, change pending bit set\n"); | 1290 | printk(KERN_ERR PFX "failing init, change pending bit set\n"); |
1212 | goto err_out; | 1291 | goto err_out_unmask; |
1213 | } | 1292 | } |
1214 | 1293 | ||
1215 | if (query_current_values_with_pending_wait(data)) | 1294 | if (query_current_values_with_pending_wait(data)) |
1216 | goto err_out; | 1295 | goto err_out_unmask; |
1217 | 1296 | ||
1218 | if (cpu_family == CPU_OPTERON) | 1297 | if (cpu_family == CPU_OPTERON) |
1219 | fidvid_msr_init(); | 1298 | fidvid_msr_init(); |
@@ -1224,11 +1303,12 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1224 | if (cpu_family == CPU_HW_PSTATE) | 1303 | if (cpu_family == CPU_HW_PSTATE) |
1225 | cpumask_copy(pol->cpus, cpumask_of(pol->cpu)); | 1304 | cpumask_copy(pol->cpus, cpumask_of(pol->cpu)); |
1226 | else | 1305 | else |
1227 | cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu)); | 1306 | cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu)); |
1228 | data->available_cores = pol->cpus; | 1307 | data->available_cores = pol->cpus; |
1229 | 1308 | ||
1230 | if (cpu_family == CPU_HW_PSTATE) | 1309 | if (cpu_family == CPU_HW_PSTATE) |
1231 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); | 1310 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, |
1311 | data->currpstate); | ||
1232 | else | 1312 | else |
1233 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1313 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1234 | dprintk("policy current frequency %d kHz\n", pol->cur); | 1314 | dprintk("policy current frequency %d kHz\n", pol->cur); |
@@ -1245,7 +1325,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1245 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); | 1325 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); |
1246 | 1326 | ||
1247 | if (cpu_family == CPU_HW_PSTATE) | 1327 | if (cpu_family == CPU_HW_PSTATE) |
1248 | dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate); | 1328 | dprintk("cpu_init done, current pstate 0x%x\n", |
1329 | data->currpstate); | ||
1249 | else | 1330 | else |
1250 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1331 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1251 | data->currfid, data->currvid); | 1332 | data->currfid, data->currvid); |
@@ -1254,15 +1335,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1254 | 1335 | ||
1255 | return 0; | 1336 | return 0; |
1256 | 1337 | ||
1257 | err_out: | 1338 | err_out_unmask: |
1258 | set_cpus_allowed_ptr(current, &oldmask); | 1339 | set_cpus_allowed_ptr(current, &oldmask); |
1259 | powernow_k8_cpu_exit_acpi(data); | 1340 | powernow_k8_cpu_exit_acpi(data); |
1260 | 1341 | ||
1342 | err_out: | ||
1261 | kfree(data); | 1343 | kfree(data); |
1262 | return -ENODEV; | 1344 | return -ENODEV; |
1263 | } | 1345 | } |
1264 | 1346 | ||
1265 | static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) | 1347 | static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol) |
1266 | { | 1348 | { |
1267 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1349 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1268 | 1350 | ||
@@ -1279,14 +1361,14 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) | |||
1279 | return 0; | 1361 | return 0; |
1280 | } | 1362 | } |
1281 | 1363 | ||
1282 | static unsigned int powernowk8_get (unsigned int cpu) | 1364 | static unsigned int powernowk8_get(unsigned int cpu) |
1283 | { | 1365 | { |
1284 | struct powernow_k8_data *data; | 1366 | struct powernow_k8_data *data; |
1285 | cpumask_t oldmask = current->cpus_allowed; | 1367 | cpumask_t oldmask = current->cpus_allowed; |
1286 | unsigned int khz = 0; | 1368 | unsigned int khz = 0; |
1287 | unsigned int first; | 1369 | unsigned int first; |
1288 | 1370 | ||
1289 | first = first_cpu(per_cpu(cpu_core_map, cpu)); | 1371 | first = cpumask_first(cpu_core_mask(cpu)); |
1290 | data = per_cpu(powernow_data, first); | 1372 | data = per_cpu(powernow_data, first); |
1291 | 1373 | ||
1292 | if (!data) | 1374 | if (!data) |
@@ -1315,7 +1397,7 @@ out: | |||
1315 | return khz; | 1397 | return khz; |
1316 | } | 1398 | } |
1317 | 1399 | ||
1318 | static struct freq_attr* powernow_k8_attr[] = { | 1400 | static struct freq_attr *powernow_k8_attr[] = { |
1319 | &cpufreq_freq_attr_scaling_available_freqs, | 1401 | &cpufreq_freq_attr_scaling_available_freqs, |
1320 | NULL, | 1402 | NULL, |
1321 | }; | 1403 | }; |
@@ -1360,7 +1442,8 @@ static void __exit powernowk8_exit(void) | |||
1360 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1442 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1361 | } | 1443 | } |
1362 | 1444 | ||
1363 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>"); | 1445 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and " |
1446 | "Mark Langsdorf <mark.langsdorf@amd.com>"); | ||
1364 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1447 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1365 | MODULE_LICENSE("GPL"); | 1448 | MODULE_LICENSE("GPL"); |
1366 | 1449 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index 8ecc75b6c7c3..6c6698feade1 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -45,11 +45,10 @@ struct powernow_k8_data { | |||
45 | * frequency is in kHz */ | 45 | * frequency is in kHz */ |
46 | struct cpufreq_frequency_table *powernow_table; | 46 | struct cpufreq_frequency_table *powernow_table; |
47 | 47 | ||
48 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | ||
49 | /* the acpi table needs to be kept. it's only available if ACPI was | 48 | /* the acpi table needs to be kept. it's only available if ACPI was |
50 | * used to determine valid frequency/vid/fid states */ | 49 | * used to determine valid frequency/vid/fid states */ |
51 | struct acpi_processor_performance acpi_data; | 50 | struct acpi_processor_performance acpi_data; |
52 | #endif | 51 | |
53 | /* we need to keep track of associated cores, but let cpufreq | 52 | /* we need to keep track of associated cores, but let cpufreq |
54 | * handle hotplug events - so just point at cpufreq pol->cpus | 53 | * handle hotplug events - so just point at cpufreq pol->cpus |
55 | * structure */ | 54 | * structure */ |
@@ -222,10 +221,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | |||
222 | 221 | ||
223 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); | 222 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); |
224 | 223 | ||
225 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | ||
226 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); | 224 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); |
227 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); | 225 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); |
228 | #endif | ||
229 | 226 | ||
230 | #ifdef CONFIG_SMP | 227 | #ifdef CONFIG_SMP |
231 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | 228 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) |
diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c index 42da9bd677d6..435a996a613a 100644 --- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c +++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c | |||
@@ -19,17 +19,19 @@ | |||
19 | 19 | ||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/cpufreq.h> | 21 | #include <linux/cpufreq.h> |
22 | #include <linux/timex.h> | ||
23 | #include <linux/io.h> | ||
22 | 24 | ||
23 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
24 | #include <asm/timex.h> | ||
25 | #include <asm/io.h> | ||
26 | 26 | ||
27 | #define MMCR_BASE 0xfffef000 /* The default base address */ | 27 | #define MMCR_BASE 0xfffef000 /* The default base address */ |
28 | #define OFFS_CPUCTL 0x2 /* CPU Control Register */ | 28 | #define OFFS_CPUCTL 0x2 /* CPU Control Register */ |
29 | 29 | ||
30 | static __u8 __iomem *cpuctl; | 30 | static __u8 __iomem *cpuctl; |
31 | 31 | ||
32 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg) | 32 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
33 | "sc520_freq", msg) | ||
34 | #define PFX "sc520_freq: " | ||
33 | 35 | ||
34 | static struct cpufreq_frequency_table sc520_freq_table[] = { | 36 | static struct cpufreq_frequency_table sc520_freq_table[] = { |
35 | {0x01, 100000}, | 37 | {0x01, 100000}, |
@@ -43,7 +45,8 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | |||
43 | 45 | ||
44 | switch (clockspeed_reg & 0x03) { | 46 | switch (clockspeed_reg & 0x03) { |
45 | default: | 47 | default: |
46 | printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg); | 48 | printk(KERN_ERR PFX "error: cpuctl register has unexpected " |
49 | "value %02x\n", clockspeed_reg); | ||
47 | case 0x01: | 50 | case 0x01: |
48 | return 100000; | 51 | return 100000; |
49 | case 0x02: | 52 | case 0x02: |
@@ -51,7 +54,7 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | |||
51 | } | 54 | } |
52 | } | 55 | } |
53 | 56 | ||
54 | static void sc520_freq_set_cpu_state (unsigned int state) | 57 | static void sc520_freq_set_cpu_state(unsigned int state) |
55 | { | 58 | { |
56 | 59 | ||
57 | struct cpufreq_freqs freqs; | 60 | struct cpufreq_freqs freqs; |
@@ -76,18 +79,19 @@ static void sc520_freq_set_cpu_state (unsigned int state) | |||
76 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 79 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
77 | }; | 80 | }; |
78 | 81 | ||
79 | static int sc520_freq_verify (struct cpufreq_policy *policy) | 82 | static int sc520_freq_verify(struct cpufreq_policy *policy) |
80 | { | 83 | { |
81 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); | 84 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); |
82 | } | 85 | } |
83 | 86 | ||
84 | static int sc520_freq_target (struct cpufreq_policy *policy, | 87 | static int sc520_freq_target(struct cpufreq_policy *policy, |
85 | unsigned int target_freq, | 88 | unsigned int target_freq, |
86 | unsigned int relation) | 89 | unsigned int relation) |
87 | { | 90 | { |
88 | unsigned int newstate = 0; | 91 | unsigned int newstate = 0; |
89 | 92 | ||
90 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate)) | 93 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, |
94 | target_freq, relation, &newstate)) | ||
91 | return -EINVAL; | 95 | return -EINVAL; |
92 | 96 | ||
93 | sc520_freq_set_cpu_state(newstate); | 97 | sc520_freq_set_cpu_state(newstate); |
@@ -116,7 +120,7 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | |||
116 | 120 | ||
117 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); | 121 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); |
118 | if (result) | 122 | if (result) |
119 | return (result); | 123 | return result; |
120 | 124 | ||
121 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); | 125 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); |
122 | 126 | ||
@@ -131,7 +135,7 @@ static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) | |||
131 | } | 135 | } |
132 | 136 | ||
133 | 137 | ||
134 | static struct freq_attr* sc520_freq_attr[] = { | 138 | static struct freq_attr *sc520_freq_attr[] = { |
135 | &cpufreq_freq_attr_scaling_available_freqs, | 139 | &cpufreq_freq_attr_scaling_available_freqs, |
136 | NULL, | 140 | NULL, |
137 | }; | 141 | }; |
@@ -155,13 +159,13 @@ static int __init sc520_freq_init(void) | |||
155 | int err; | 159 | int err; |
156 | 160 | ||
157 | /* Test if we have the right hardware */ | 161 | /* Test if we have the right hardware */ |
158 | if(c->x86_vendor != X86_VENDOR_AMD || | 162 | if (c->x86_vendor != X86_VENDOR_AMD || |
159 | c->x86 != 4 || c->x86_model != 9) { | 163 | c->x86 != 4 || c->x86_model != 9) { |
160 | dprintk("no Elan SC520 processor found!\n"); | 164 | dprintk("no Elan SC520 processor found!\n"); |
161 | return -ENODEV; | 165 | return -ENODEV; |
162 | } | 166 | } |
163 | cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); | 167 | cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); |
164 | if(!cpuctl) { | 168 | if (!cpuctl) { |
165 | printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); | 169 | printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); |
166 | return -ENOMEM; | 170 | return -ENOMEM; |
167 | } | 171 | } |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index dedc1e98f168..016c1a4fa3fc 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
@@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev; | |||
39 | 39 | ||
40 | /* speedstep_processor | 40 | /* speedstep_processor |
41 | */ | 41 | */ |
42 | static unsigned int speedstep_processor = 0; | 42 | static unsigned int speedstep_processor; |
43 | 43 | ||
44 | static u32 pmbase; | 44 | static u32 pmbase; |
45 | 45 | ||
@@ -54,7 +54,8 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | 56 | ||
57 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-ich", msg) | 57 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
58 | "speedstep-ich", msg) | ||
58 | 59 | ||
59 | 60 | ||
60 | /** | 61 | /** |
@@ -62,7 +63,7 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { | |||
62 | * | 63 | * |
63 | * Returns: -ENODEV if no register could be found | 64 | * Returns: -ENODEV if no register could be found |
64 | */ | 65 | */ |
65 | static int speedstep_find_register (void) | 66 | static int speedstep_find_register(void) |
66 | { | 67 | { |
67 | if (!speedstep_chipset_dev) | 68 | if (!speedstep_chipset_dev) |
68 | return -ENODEV; | 69 | return -ENODEV; |
@@ -90,7 +91,7 @@ static int speedstep_find_register (void) | |||
90 | * | 91 | * |
91 | * Tries to change the SpeedStep state. | 92 | * Tries to change the SpeedStep state. |
92 | */ | 93 | */ |
93 | static void speedstep_set_state (unsigned int state) | 94 | static void speedstep_set_state(unsigned int state) |
94 | { | 95 | { |
95 | u8 pm2_blk; | 96 | u8 pm2_blk; |
96 | u8 value; | 97 | u8 value; |
@@ -133,11 +134,11 @@ static void speedstep_set_state (unsigned int state) | |||
133 | 134 | ||
134 | dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); | 135 | dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); |
135 | 136 | ||
136 | if (state == (value & 0x1)) { | 137 | if (state == (value & 0x1)) |
137 | dprintk("change to %u MHz succeeded\n", (speedstep_get_processor_frequency(speedstep_processor) / 1000)); | 138 | dprintk("change to %u MHz succeeded\n", |
138 | } else { | 139 | speedstep_get_frequency(speedstep_processor) / 1000); |
139 | printk (KERN_ERR "cpufreq: change failed - I/O error\n"); | 140 | else |
140 | } | 141 | printk(KERN_ERR "cpufreq: change failed - I/O error\n"); |
141 | 142 | ||
142 | return; | 143 | return; |
143 | } | 144 | } |
@@ -149,7 +150,7 @@ static void speedstep_set_state (unsigned int state) | |||
149 | * Tries to activate the SpeedStep status and control registers. | 150 | * Tries to activate the SpeedStep status and control registers. |
150 | * Returns -EINVAL on an unsupported chipset, and zero on success. | 151 | * Returns -EINVAL on an unsupported chipset, and zero on success. |
151 | */ | 152 | */ |
152 | static int speedstep_activate (void) | 153 | static int speedstep_activate(void) |
153 | { | 154 | { |
154 | u16 value = 0; | 155 | u16 value = 0; |
155 | 156 | ||
@@ -175,20 +176,18 @@ static int speedstep_activate (void) | |||
175 | * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected | 176 | * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected |
176 | * chipset, or zero on failure. | 177 | * chipset, or zero on failure. |
177 | */ | 178 | */ |
178 | static unsigned int speedstep_detect_chipset (void) | 179 | static unsigned int speedstep_detect_chipset(void) |
179 | { | 180 | { |
180 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | 181 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, |
181 | PCI_DEVICE_ID_INTEL_82801DB_12, | 182 | PCI_DEVICE_ID_INTEL_82801DB_12, |
182 | PCI_ANY_ID, | 183 | PCI_ANY_ID, PCI_ANY_ID, |
183 | PCI_ANY_ID, | ||
184 | NULL); | 184 | NULL); |
185 | if (speedstep_chipset_dev) | 185 | if (speedstep_chipset_dev) |
186 | return 4; /* 4-M */ | 186 | return 4; /* 4-M */ |
187 | 187 | ||
188 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | 188 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, |
189 | PCI_DEVICE_ID_INTEL_82801CA_12, | 189 | PCI_DEVICE_ID_INTEL_82801CA_12, |
190 | PCI_ANY_ID, | 190 | PCI_ANY_ID, PCI_ANY_ID, |
191 | PCI_ANY_ID, | ||
192 | NULL); | 191 | NULL); |
193 | if (speedstep_chipset_dev) | 192 | if (speedstep_chipset_dev) |
194 | return 3; /* 3-M */ | 193 | return 3; /* 3-M */ |
@@ -196,8 +195,7 @@ static unsigned int speedstep_detect_chipset (void) | |||
196 | 195 | ||
197 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | 196 | speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, |
198 | PCI_DEVICE_ID_INTEL_82801BA_10, | 197 | PCI_DEVICE_ID_INTEL_82801BA_10, |
199 | PCI_ANY_ID, | 198 | PCI_ANY_ID, PCI_ANY_ID, |
200 | PCI_ANY_ID, | ||
201 | NULL); | 199 | NULL); |
202 | if (speedstep_chipset_dev) { | 200 | if (speedstep_chipset_dev) { |
203 | /* speedstep.c causes lockups on Dell Inspirons 8000 and | 201 | /* speedstep.c causes lockups on Dell Inspirons 8000 and |
@@ -208,8 +206,7 @@ static unsigned int speedstep_detect_chipset (void) | |||
208 | 206 | ||
209 | hostbridge = pci_get_subsys(PCI_VENDOR_ID_INTEL, | 207 | hostbridge = pci_get_subsys(PCI_VENDOR_ID_INTEL, |
210 | PCI_DEVICE_ID_INTEL_82815_MC, | 208 | PCI_DEVICE_ID_INTEL_82815_MC, |
211 | PCI_ANY_ID, | 209 | PCI_ANY_ID, PCI_ANY_ID, |
212 | PCI_ANY_ID, | ||
213 | NULL); | 210 | NULL); |
214 | 211 | ||
215 | if (!hostbridge) | 212 | if (!hostbridge) |
@@ -236,7 +233,7 @@ static unsigned int _speedstep_get(const struct cpumask *cpus) | |||
236 | 233 | ||
237 | cpus_allowed = current->cpus_allowed; | 234 | cpus_allowed = current->cpus_allowed; |
238 | set_cpus_allowed_ptr(current, cpus); | 235 | set_cpus_allowed_ptr(current, cpus); |
239 | speed = speedstep_get_processor_frequency(speedstep_processor); | 236 | speed = speedstep_get_frequency(speedstep_processor); |
240 | set_cpus_allowed_ptr(current, &cpus_allowed); | 237 | set_cpus_allowed_ptr(current, &cpus_allowed); |
241 | dprintk("detected %u kHz as current frequency\n", speed); | 238 | dprintk("detected %u kHz as current frequency\n", speed); |
242 | return speed; | 239 | return speed; |
@@ -251,11 +248,12 @@ static unsigned int speedstep_get(unsigned int cpu) | |||
251 | * speedstep_target - set a new CPUFreq policy | 248 | * speedstep_target - set a new CPUFreq policy |
252 | * @policy: new policy | 249 | * @policy: new policy |
253 | * @target_freq: the target frequency | 250 | * @target_freq: the target frequency |
254 | * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | 251 | * @relation: how that frequency relates to achieved frequency |
252 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
255 | * | 253 | * |
256 | * Sets a new CPUFreq policy. | 254 | * Sets a new CPUFreq policy. |
257 | */ | 255 | */ |
258 | static int speedstep_target (struct cpufreq_policy *policy, | 256 | static int speedstep_target(struct cpufreq_policy *policy, |
259 | unsigned int target_freq, | 257 | unsigned int target_freq, |
260 | unsigned int relation) | 258 | unsigned int relation) |
261 | { | 259 | { |
@@ -264,7 +262,8 @@ static int speedstep_target (struct cpufreq_policy *policy, | |||
264 | cpumask_t cpus_allowed; | 262 | cpumask_t cpus_allowed; |
265 | int i; | 263 | int i; |
266 | 264 | ||
267 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) | 265 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], |
266 | target_freq, relation, &newstate)) | ||
268 | return -EINVAL; | 267 | return -EINVAL; |
269 | 268 | ||
270 | freqs.old = _speedstep_get(policy->cpus); | 269 | freqs.old = _speedstep_get(policy->cpus); |
@@ -308,7 +307,7 @@ static int speedstep_target (struct cpufreq_policy *policy, | |||
308 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with | 307 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with |
309 | * at least one border included. | 308 | * at least one border included. |
310 | */ | 309 | */ |
311 | static int speedstep_verify (struct cpufreq_policy *policy) | 310 | static int speedstep_verify(struct cpufreq_policy *policy) |
312 | { | 311 | { |
313 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); | 312 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); |
314 | } | 313 | } |
@@ -322,7 +321,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
322 | 321 | ||
323 | /* only run on CPU to be set, or on its sibling */ | 322 | /* only run on CPU to be set, or on its sibling */ |
324 | #ifdef CONFIG_SMP | 323 | #ifdef CONFIG_SMP |
325 | cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu)); | 324 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); |
326 | #endif | 325 | #endif |
327 | 326 | ||
328 | cpus_allowed = current->cpus_allowed; | 327 | cpus_allowed = current->cpus_allowed; |
@@ -344,7 +343,8 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
344 | return -EIO; | 343 | return -EIO; |
345 | 344 | ||
346 | dprintk("currently at %s speed setting - %i MHz\n", | 345 | dprintk("currently at %s speed setting - %i MHz\n", |
347 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", | 346 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) |
347 | ? "low" : "high", | ||
348 | (speed / 1000)); | 348 | (speed / 1000)); |
349 | 349 | ||
350 | /* cpuinfo and default policy values */ | 350 | /* cpuinfo and default policy values */ |
@@ -352,9 +352,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
352 | 352 | ||
353 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); | 353 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); |
354 | if (result) | 354 | if (result) |
355 | return (result); | 355 | return result; |
356 | 356 | ||
357 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); | 357 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); |
358 | 358 | ||
359 | return 0; | 359 | return 0; |
360 | } | 360 | } |
@@ -366,7 +366,7 @@ static int speedstep_cpu_exit(struct cpufreq_policy *policy) | |||
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | static struct freq_attr* speedstep_attr[] = { | 369 | static struct freq_attr *speedstep_attr[] = { |
370 | &cpufreq_freq_attr_scaling_available_freqs, | 370 | &cpufreq_freq_attr_scaling_available_freqs, |
371 | NULL, | 371 | NULL, |
372 | }; | 372 | }; |
@@ -396,13 +396,15 @@ static int __init speedstep_init(void) | |||
396 | /* detect processor */ | 396 | /* detect processor */ |
397 | speedstep_processor = speedstep_detect_processor(); | 397 | speedstep_processor = speedstep_detect_processor(); |
398 | if (!speedstep_processor) { | 398 | if (!speedstep_processor) { |
399 | dprintk("Intel(R) SpeedStep(TM) capable processor not found\n"); | 399 | dprintk("Intel(R) SpeedStep(TM) capable processor " |
400 | "not found\n"); | ||
400 | return -ENODEV; | 401 | return -ENODEV; |
401 | } | 402 | } |
402 | 403 | ||
403 | /* detect chipset */ | 404 | /* detect chipset */ |
404 | if (!speedstep_detect_chipset()) { | 405 | if (!speedstep_detect_chipset()) { |
405 | dprintk("Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n"); | 406 | dprintk("Intel(R) SpeedStep(TM) for this chipset not " |
407 | "(yet) available.\n"); | ||
406 | return -ENODEV; | 408 | return -ENODEV; |
407 | } | 409 | } |
408 | 410 | ||
@@ -431,9 +433,11 @@ static void __exit speedstep_exit(void) | |||
431 | } | 433 | } |
432 | 434 | ||
433 | 435 | ||
434 | MODULE_AUTHOR ("Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>"); | 436 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, " |
435 | MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges."); | 437 | "Dominik Brodowski <linux@brodo.de>"); |
436 | MODULE_LICENSE ("GPL"); | 438 | MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets " |
439 | "with ICH-M southbridges."); | ||
440 | MODULE_LICENSE("GPL"); | ||
437 | 441 | ||
438 | module_init(speedstep_init); | 442 | module_init(speedstep_init); |
439 | module_exit(speedstep_exit); | 443 | module_exit(speedstep_exit); |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index cdac7d62369b..2e3c6862657b 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -16,12 +16,16 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | 17 | ||
18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
19 | #include <asm/tsc.h> | ||
19 | #include "speedstep-lib.h" | 20 | #include "speedstep-lib.h" |
20 | 21 | ||
21 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-lib", msg) | 22 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
23 | "speedstep-lib", msg) | ||
24 | |||
25 | #define PFX "speedstep-lib: " | ||
22 | 26 | ||
23 | #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK | 27 | #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK |
24 | static int relaxed_check = 0; | 28 | static int relaxed_check; |
25 | #else | 29 | #else |
26 | #define relaxed_check 0 | 30 | #define relaxed_check 0 |
27 | #endif | 31 | #endif |
@@ -30,14 +34,14 @@ static int relaxed_check = 0; | |||
30 | * GET PROCESSOR CORE SPEED IN KHZ * | 34 | * GET PROCESSOR CORE SPEED IN KHZ * |
31 | *********************************************************************/ | 35 | *********************************************************************/ |
32 | 36 | ||
33 | static unsigned int pentium3_get_frequency (unsigned int processor) | 37 | static unsigned int pentium3_get_frequency(unsigned int processor) |
34 | { | 38 | { |
35 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ | 39 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ |
36 | struct { | 40 | struct { |
37 | unsigned int ratio; /* Frequency Multiplier (x10) */ | 41 | unsigned int ratio; /* Frequency Multiplier (x10) */ |
38 | u8 bitmap; /* power on configuration bits | 42 | u8 bitmap; /* power on configuration bits |
39 | [27, 25:22] (in MSR 0x2a) */ | 43 | [27, 25:22] (in MSR 0x2a) */ |
40 | } msr_decode_mult [] = { | 44 | } msr_decode_mult[] = { |
41 | { 30, 0x01 }, | 45 | { 30, 0x01 }, |
42 | { 35, 0x05 }, | 46 | { 35, 0x05 }, |
43 | { 40, 0x02 }, | 47 | { 40, 0x02 }, |
@@ -52,7 +56,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
52 | { 85, 0x26 }, | 56 | { 85, 0x26 }, |
53 | { 90, 0x20 }, | 57 | { 90, 0x20 }, |
54 | { 100, 0x2b }, | 58 | { 100, 0x2b }, |
55 | { 0, 0xff } /* error or unknown value */ | 59 | { 0, 0xff } /* error or unknown value */ |
56 | }; | 60 | }; |
57 | 61 | ||
58 | /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ | 62 | /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ |
@@ -60,7 +64,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
60 | unsigned int value; /* Front Side Bus speed in MHz */ | 64 | unsigned int value; /* Front Side Bus speed in MHz */ |
61 | u8 bitmap; /* power on configuration bits [18: 19] | 65 | u8 bitmap; /* power on configuration bits [18: 19] |
62 | (in MSR 0x2a) */ | 66 | (in MSR 0x2a) */ |
63 | } msr_decode_fsb [] = { | 67 | } msr_decode_fsb[] = { |
64 | { 66, 0x0 }, | 68 | { 66, 0x0 }, |
65 | { 100, 0x2 }, | 69 | { 100, 0x2 }, |
66 | { 133, 0x1 }, | 70 | { 133, 0x1 }, |
@@ -85,7 +89,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
85 | } | 89 | } |
86 | 90 | ||
87 | /* decode the multiplier */ | 91 | /* decode the multiplier */ |
88 | if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) { | 92 | if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) { |
89 | dprintk("workaround for early PIIIs\n"); | 93 | dprintk("workaround for early PIIIs\n"); |
90 | msr_lo &= 0x03c00000; | 94 | msr_lo &= 0x03c00000; |
91 | } else | 95 | } else |
@@ -97,9 +101,10 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
97 | j++; | 101 | j++; |
98 | } | 102 | } |
99 | 103 | ||
100 | dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100)); | 104 | dprintk("speed is %u\n", |
105 | (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100)); | ||
101 | 106 | ||
102 | return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100); | 107 | return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100; |
103 | } | 108 | } |
104 | 109 | ||
105 | 110 | ||
@@ -112,20 +117,23 @@ static unsigned int pentiumM_get_frequency(void) | |||
112 | 117 | ||
113 | /* see table B-2 of 24547212.pdf */ | 118 | /* see table B-2 of 24547212.pdf */ |
114 | if (msr_lo & 0x00040000) { | 119 | if (msr_lo & 0x00040000) { |
115 | printk(KERN_DEBUG "speedstep-lib: PM - invalid FSB: 0x%x 0x%x\n", msr_lo, msr_tmp); | 120 | printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n", |
121 | msr_lo, msr_tmp); | ||
116 | return 0; | 122 | return 0; |
117 | } | 123 | } |
118 | 124 | ||
119 | msr_tmp = (msr_lo >> 22) & 0x1f; | 125 | msr_tmp = (msr_lo >> 22) & 0x1f; |
120 | dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000)); | 126 | dprintk("bits 22-26 are 0x%x, speed is %u\n", |
127 | msr_tmp, (msr_tmp * 100 * 1000)); | ||
121 | 128 | ||
122 | return (msr_tmp * 100 * 1000); | 129 | return msr_tmp * 100 * 1000; |
123 | } | 130 | } |
124 | 131 | ||
125 | static unsigned int pentium_core_get_frequency(void) | 132 | static unsigned int pentium_core_get_frequency(void) |
126 | { | 133 | { |
127 | u32 fsb = 0; | 134 | u32 fsb = 0; |
128 | u32 msr_lo, msr_tmp; | 135 | u32 msr_lo, msr_tmp; |
136 | int ret; | ||
129 | 137 | ||
130 | rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp); | 138 | rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp); |
131 | /* see table B-2 of 25366920.pdf */ | 139 | /* see table B-2 of 25366920.pdf */ |
@@ -153,12 +161,15 @@ static unsigned int pentium_core_get_frequency(void) | |||
153 | } | 161 | } |
154 | 162 | ||
155 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); | 163 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); |
156 | dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); | 164 | dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", |
165 | msr_lo, msr_tmp); | ||
157 | 166 | ||
158 | msr_tmp = (msr_lo >> 22) & 0x1f; | 167 | msr_tmp = (msr_lo >> 22) & 0x1f; |
159 | dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb)); | 168 | dprintk("bits 22-26 are 0x%x, speed is %u\n", |
169 | msr_tmp, (msr_tmp * fsb)); | ||
160 | 170 | ||
161 | return (msr_tmp * fsb); | 171 | ret = (msr_tmp * fsb); |
172 | return ret; | ||
162 | } | 173 | } |
163 | 174 | ||
164 | 175 | ||
@@ -167,6 +178,16 @@ static unsigned int pentium4_get_frequency(void) | |||
167 | struct cpuinfo_x86 *c = &boot_cpu_data; | 178 | struct cpuinfo_x86 *c = &boot_cpu_data; |
168 | u32 msr_lo, msr_hi, mult; | 179 | u32 msr_lo, msr_hi, mult; |
169 | unsigned int fsb = 0; | 180 | unsigned int fsb = 0; |
181 | unsigned int ret; | ||
182 | u8 fsb_code; | ||
183 | |||
184 | /* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency | ||
185 | * to System Bus Frequency Ratio Field in the Processor Frequency | ||
186 | * Configuration Register of the MSR. Therefore the current | ||
187 | * frequency cannot be calculated and has to be measured. | ||
188 | */ | ||
189 | if (c->x86_model < 2) | ||
190 | return cpu_khz; | ||
170 | 191 | ||
171 | rdmsr(0x2c, msr_lo, msr_hi); | 192 | rdmsr(0x2c, msr_lo, msr_hi); |
172 | 193 | ||
@@ -177,62 +198,61 @@ static unsigned int pentium4_get_frequency(void) | |||
177 | * revision #12 in Table B-1: MSRs in the Pentium 4 and | 198 | * revision #12 in Table B-1: MSRs in the Pentium 4 and |
178 | * Intel Xeon Processors, on page B-4 and B-5. | 199 | * Intel Xeon Processors, on page B-4 and B-5. |
179 | */ | 200 | */ |
180 | if (c->x86_model < 2) | 201 | fsb_code = (msr_lo >> 16) & 0x7; |
202 | switch (fsb_code) { | ||
203 | case 0: | ||
181 | fsb = 100 * 1000; | 204 | fsb = 100 * 1000; |
182 | else { | 205 | break; |
183 | u8 fsb_code = (msr_lo >> 16) & 0x7; | 206 | case 1: |
184 | switch (fsb_code) { | 207 | fsb = 13333 * 10; |
185 | case 0: | 208 | break; |
186 | fsb = 100 * 1000; | 209 | case 2: |
187 | break; | 210 | fsb = 200 * 1000; |
188 | case 1: | 211 | break; |
189 | fsb = 13333 * 10; | ||
190 | break; | ||
191 | case 2: | ||
192 | fsb = 200 * 1000; | ||
193 | break; | ||
194 | } | ||
195 | } | 212 | } |
196 | 213 | ||
197 | if (!fsb) | 214 | if (!fsb) |
198 | printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n"); | 215 | printk(KERN_DEBUG PFX "couldn't detect FSB speed. " |
216 | "Please send an e-mail to <linux@brodo.de>\n"); | ||
199 | 217 | ||
200 | /* Multiplier. */ | 218 | /* Multiplier. */ |
201 | mult = msr_lo >> 24; | 219 | mult = msr_lo >> 24; |
202 | 220 | ||
203 | dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult)); | 221 | dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", |
222 | fsb, mult, (fsb * mult)); | ||
204 | 223 | ||
205 | return (fsb * mult); | 224 | ret = (fsb * mult); |
225 | return ret; | ||
206 | } | 226 | } |
207 | 227 | ||
208 | 228 | ||
209 | unsigned int speedstep_get_processor_frequency(unsigned int processor) | 229 | unsigned int speedstep_get_frequency(unsigned int processor) |
210 | { | 230 | { |
211 | switch (processor) { | 231 | switch (processor) { |
212 | case SPEEDSTEP_PROCESSOR_PCORE: | 232 | case SPEEDSTEP_CPU_PCORE: |
213 | return pentium_core_get_frequency(); | 233 | return pentium_core_get_frequency(); |
214 | case SPEEDSTEP_PROCESSOR_PM: | 234 | case SPEEDSTEP_CPU_PM: |
215 | return pentiumM_get_frequency(); | 235 | return pentiumM_get_frequency(); |
216 | case SPEEDSTEP_PROCESSOR_P4D: | 236 | case SPEEDSTEP_CPU_P4D: |
217 | case SPEEDSTEP_PROCESSOR_P4M: | 237 | case SPEEDSTEP_CPU_P4M: |
218 | return pentium4_get_frequency(); | 238 | return pentium4_get_frequency(); |
219 | case SPEEDSTEP_PROCESSOR_PIII_T: | 239 | case SPEEDSTEP_CPU_PIII_T: |
220 | case SPEEDSTEP_PROCESSOR_PIII_C: | 240 | case SPEEDSTEP_CPU_PIII_C: |
221 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: | 241 | case SPEEDSTEP_CPU_PIII_C_EARLY: |
222 | return pentium3_get_frequency(processor); | 242 | return pentium3_get_frequency(processor); |
223 | default: | 243 | default: |
224 | return 0; | 244 | return 0; |
225 | }; | 245 | }; |
226 | return 0; | 246 | return 0; |
227 | } | 247 | } |
228 | EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency); | 248 | EXPORT_SYMBOL_GPL(speedstep_get_frequency); |
229 | 249 | ||
230 | 250 | ||
231 | /********************************************************************* | 251 | /********************************************************************* |
232 | * DETECT SPEEDSTEP-CAPABLE PROCESSOR * | 252 | * DETECT SPEEDSTEP-CAPABLE PROCESSOR * |
233 | *********************************************************************/ | 253 | *********************************************************************/ |
234 | 254 | ||
235 | unsigned int speedstep_detect_processor (void) | 255 | unsigned int speedstep_detect_processor(void) |
236 | { | 256 | { |
237 | struct cpuinfo_x86 *c = &cpu_data(0); | 257 | struct cpuinfo_x86 *c = &cpu_data(0); |
238 | u32 ebx, msr_lo, msr_hi; | 258 | u32 ebx, msr_lo, msr_hi; |
@@ -261,7 +281,7 @@ unsigned int speedstep_detect_processor (void) | |||
261 | * sample has ebx = 0x0f, production has 0x0e. | 281 | * sample has ebx = 0x0f, production has 0x0e. |
262 | */ | 282 | */ |
263 | if ((ebx == 0x0e) || (ebx == 0x0f)) | 283 | if ((ebx == 0x0e) || (ebx == 0x0f)) |
264 | return SPEEDSTEP_PROCESSOR_P4M; | 284 | return SPEEDSTEP_CPU_P4M; |
265 | break; | 285 | break; |
266 | case 7: | 286 | case 7: |
267 | /* | 287 | /* |
@@ -272,7 +292,7 @@ unsigned int speedstep_detect_processor (void) | |||
272 | * samples are only of B-stepping... | 292 | * samples are only of B-stepping... |
273 | */ | 293 | */ |
274 | if (ebx == 0x0e) | 294 | if (ebx == 0x0e) |
275 | return SPEEDSTEP_PROCESSOR_P4M; | 295 | return SPEEDSTEP_CPU_P4M; |
276 | break; | 296 | break; |
277 | case 9: | 297 | case 9: |
278 | /* | 298 | /* |
@@ -288,10 +308,13 @@ unsigned int speedstep_detect_processor (void) | |||
288 | * M-P4-Ms may have either ebx=0xe or 0xf [see above] | 308 | * M-P4-Ms may have either ebx=0xe or 0xf [see above] |
289 | * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf] | 309 | * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf] |
290 | * also, M-P4M HTs have ebx=0x8, too | 310 | * also, M-P4M HTs have ebx=0x8, too |
291 | * For now, they are distinguished by the model_id string | 311 | * For now, they are distinguished by the model_id |
312 | * string | ||
292 | */ | 313 | */ |
293 | if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) | 314 | if ((ebx == 0x0e) || |
294 | return SPEEDSTEP_PROCESSOR_P4M; | 315 | (strstr(c->x86_model_id, |
316 | "Mobile Intel(R) Pentium(R) 4") != NULL)) | ||
317 | return SPEEDSTEP_CPU_P4M; | ||
295 | break; | 318 | break; |
296 | default: | 319 | default: |
297 | break; | 320 | break; |
@@ -301,7 +324,8 @@ unsigned int speedstep_detect_processor (void) | |||
301 | 324 | ||
302 | switch (c->x86_model) { | 325 | switch (c->x86_model) { |
303 | case 0x0B: /* Intel PIII [Tualatin] */ | 326 | case 0x0B: /* Intel PIII [Tualatin] */ |
304 | /* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */ | 327 | /* cpuid_ebx(1) is 0x04 for desktop PIII, |
328 | * 0x06 for mobile PIII-M */ | ||
305 | ebx = cpuid_ebx(0x00000001); | 329 | ebx = cpuid_ebx(0x00000001); |
306 | dprintk("ebx is %x\n", ebx); | 330 | dprintk("ebx is %x\n", ebx); |
307 | 331 | ||
@@ -313,14 +337,15 @@ unsigned int speedstep_detect_processor (void) | |||
313 | /* So far all PIII-M processors support SpeedStep. See | 337 | /* So far all PIII-M processors support SpeedStep. See |
314 | * Intel's 24540640.pdf of June 2003 | 338 | * Intel's 24540640.pdf of June 2003 |
315 | */ | 339 | */ |
316 | return SPEEDSTEP_PROCESSOR_PIII_T; | 340 | return SPEEDSTEP_CPU_PIII_T; |
317 | 341 | ||
318 | case 0x08: /* Intel PIII [Coppermine] */ | 342 | case 0x08: /* Intel PIII [Coppermine] */ |
319 | 343 | ||
320 | /* all mobile PIII Coppermines have FSB 100 MHz | 344 | /* all mobile PIII Coppermines have FSB 100 MHz |
321 | * ==> sort out a few desktop PIIIs. */ | 345 | * ==> sort out a few desktop PIIIs. */ |
322 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); | 346 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); |
323 | dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi); | 347 | dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", |
348 | msr_lo, msr_hi); | ||
324 | msr_lo &= 0x00c0000; | 349 | msr_lo &= 0x00c0000; |
325 | if (msr_lo != 0x0080000) | 350 | if (msr_lo != 0x0080000) |
326 | return 0; | 351 | return 0; |
@@ -332,13 +357,15 @@ unsigned int speedstep_detect_processor (void) | |||
332 | * bit 56 or 57 is set | 357 | * bit 56 or 57 is set |
333 | */ | 358 | */ |
334 | rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); | 359 | rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); |
335 | dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi); | 360 | dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", |
336 | if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) { | 361 | msr_lo, msr_hi); |
362 | if ((msr_hi & (1<<18)) && | ||
363 | (relaxed_check ? 1 : (msr_hi & (3<<24)))) { | ||
337 | if (c->x86_mask == 0x01) { | 364 | if (c->x86_mask == 0x01) { |
338 | dprintk("early PIII version\n"); | 365 | dprintk("early PIII version\n"); |
339 | return SPEEDSTEP_PROCESSOR_PIII_C_EARLY; | 366 | return SPEEDSTEP_CPU_PIII_C_EARLY; |
340 | } else | 367 | } else |
341 | return SPEEDSTEP_PROCESSOR_PIII_C; | 368 | return SPEEDSTEP_CPU_PIII_C; |
342 | } | 369 | } |
343 | 370 | ||
344 | default: | 371 | default: |
@@ -369,7 +396,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
369 | dprintk("trying to determine both speeds\n"); | 396 | dprintk("trying to determine both speeds\n"); |
370 | 397 | ||
371 | /* get current speed */ | 398 | /* get current speed */ |
372 | prev_speed = speedstep_get_processor_frequency(processor); | 399 | prev_speed = speedstep_get_frequency(processor); |
373 | if (!prev_speed) | 400 | if (!prev_speed) |
374 | return -EIO; | 401 | return -EIO; |
375 | 402 | ||
@@ -379,7 +406,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
379 | 406 | ||
380 | /* switch to low state */ | 407 | /* switch to low state */ |
381 | set_state(SPEEDSTEP_LOW); | 408 | set_state(SPEEDSTEP_LOW); |
382 | *low_speed = speedstep_get_processor_frequency(processor); | 409 | *low_speed = speedstep_get_frequency(processor); |
383 | if (!*low_speed) { | 410 | if (!*low_speed) { |
384 | ret = -EIO; | 411 | ret = -EIO; |
385 | goto out; | 412 | goto out; |
@@ -398,7 +425,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
398 | if (transition_latency) | 425 | if (transition_latency) |
399 | do_gettimeofday(&tv2); | 426 | do_gettimeofday(&tv2); |
400 | 427 | ||
401 | *high_speed = speedstep_get_processor_frequency(processor); | 428 | *high_speed = speedstep_get_frequency(processor); |
402 | if (!*high_speed) { | 429 | if (!*high_speed) { |
403 | ret = -EIO; | 430 | ret = -EIO; |
404 | goto out; | 431 | goto out; |
@@ -426,9 +453,12 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
426 | /* check if the latency measurement is too high or too low | 453 | /* check if the latency measurement is too high or too low |
427 | * and set it to a safe value (500uSec) in that case | 454 | * and set it to a safe value (500uSec) in that case |
428 | */ | 455 | */ |
429 | if (*transition_latency > 10000000 || *transition_latency < 50000) { | 456 | if (*transition_latency > 10000000 || |
430 | printk (KERN_WARNING "speedstep: frequency transition measured seems out of " | 457 | *transition_latency < 50000) { |
431 | "range (%u nSec), falling back to a safe one of %u nSec.\n", | 458 | printk(KERN_WARNING PFX "frequency transition " |
459 | "measured seems out of range (%u " | ||
460 | "nSec), falling back to a safe one of" | ||
461 | "%u nSec.\n", | ||
432 | *transition_latency, 500000); | 462 | *transition_latency, 500000); |
433 | *transition_latency = 500000; | 463 | *transition_latency = 500000; |
434 | } | 464 | } |
@@ -436,15 +466,16 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
436 | 466 | ||
437 | out: | 467 | out: |
438 | local_irq_restore(flags); | 468 | local_irq_restore(flags); |
439 | return (ret); | 469 | return ret; |
440 | } | 470 | } |
441 | EXPORT_SYMBOL_GPL(speedstep_get_freqs); | 471 | EXPORT_SYMBOL_GPL(speedstep_get_freqs); |
442 | 472 | ||
443 | #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK | 473 | #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK |
444 | module_param(relaxed_check, int, 0444); | 474 | module_param(relaxed_check, int, 0444); |
445 | MODULE_PARM_DESC(relaxed_check, "Don't do all checks for speedstep capability."); | 475 | MODULE_PARM_DESC(relaxed_check, |
476 | "Don't do all checks for speedstep capability."); | ||
446 | #endif | 477 | #endif |
447 | 478 | ||
448 | MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>"); | 479 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); |
449 | MODULE_DESCRIPTION ("Library for Intel SpeedStep 1 or 2 cpufreq drivers."); | 480 | MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers."); |
450 | MODULE_LICENSE ("GPL"); | 481 | MODULE_LICENSE("GPL"); |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h index b11bcc608cac..2b6c04e5a304 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h | |||
@@ -12,17 +12,17 @@ | |||
12 | 12 | ||
13 | /* processors */ | 13 | /* processors */ |
14 | 14 | ||
15 | #define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ | 15 | #define SPEEDSTEP_CPU_PIII_C_EARLY 0x00000001 /* Coppermine core */ |
16 | #define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ | 16 | #define SPEEDSTEP_CPU_PIII_C 0x00000002 /* Coppermine core */ |
17 | #define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ | 17 | #define SPEEDSTEP_CPU_PIII_T 0x00000003 /* Tualatin core */ |
18 | #define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */ | 18 | #define SPEEDSTEP_CPU_P4M 0x00000004 /* P4-M */ |
19 | 19 | ||
20 | /* the following processors are not speedstep-capable and are not auto-detected | 20 | /* the following processors are not speedstep-capable and are not auto-detected |
21 | * in speedstep_detect_processor(). However, their speed can be detected using | 21 | * in speedstep_detect_processor(). However, their speed can be detected using |
22 | * the speedstep_get_processor_frequency() call. */ | 22 | * the speedstep_get_frequency() call. */ |
23 | #define SPEEDSTEP_PROCESSOR_PM 0xFFFFFF03 /* Pentium M */ | 23 | #define SPEEDSTEP_CPU_PM 0xFFFFFF03 /* Pentium M */ |
24 | #define SPEEDSTEP_PROCESSOR_P4D 0xFFFFFF04 /* desktop P4 */ | 24 | #define SPEEDSTEP_CPU_P4D 0xFFFFFF04 /* desktop P4 */ |
25 | #define SPEEDSTEP_PROCESSOR_PCORE 0xFFFFFF05 /* Core */ | 25 | #define SPEEDSTEP_CPU_PCORE 0xFFFFFF05 /* Core */ |
26 | 26 | ||
27 | /* speedstep states -- only two of them */ | 27 | /* speedstep states -- only two of them */ |
28 | 28 | ||
@@ -34,7 +34,7 @@ | |||
34 | extern unsigned int speedstep_detect_processor (void); | 34 | extern unsigned int speedstep_detect_processor (void); |
35 | 35 | ||
36 | /* detect the current speed (in khz) of the processor */ | 36 | /* detect the current speed (in khz) of the processor */ |
37 | extern unsigned int speedstep_get_processor_frequency(unsigned int processor); | 37 | extern unsigned int speedstep_get_frequency(unsigned int processor); |
38 | 38 | ||
39 | 39 | ||
40 | /* detect the low and high speeds of the processor. The callback | 40 | /* detect the low and high speeds of the processor. The callback |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index 8a85c93bd62a..befea088e4f5 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/cpufreq.h> | 19 | #include <linux/cpufreq.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/io.h> | ||
22 | #include <asm/ist.h> | 23 | #include <asm/ist.h> |
23 | #include <asm/io.h> | ||
24 | 24 | ||
25 | #include "speedstep-lib.h" | 25 | #include "speedstep-lib.h" |
26 | 26 | ||
@@ -30,12 +30,12 @@ | |||
30 | * If user gives it, these are used. | 30 | * If user gives it, these are used. |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | static int smi_port = 0; | 33 | static int smi_port; |
34 | static int smi_cmd = 0; | 34 | static int smi_cmd; |
35 | static unsigned int smi_sig = 0; | 35 | static unsigned int smi_sig; |
36 | 36 | ||
37 | /* info about the processor */ | 37 | /* info about the processor */ |
38 | static unsigned int speedstep_processor = 0; | 38 | static unsigned int speedstep_processor; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * There are only two frequency states for each processor. Values | 41 | * There are only two frequency states for each processor. Values |
@@ -56,12 +56,13 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { | |||
56 | * of DMA activity going on? */ | 56 | * of DMA activity going on? */ |
57 | #define SMI_TRIES 5 | 57 | #define SMI_TRIES 5 |
58 | 58 | ||
59 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-smi", msg) | 59 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ |
60 | "speedstep-smi", msg) | ||
60 | 61 | ||
61 | /** | 62 | /** |
62 | * speedstep_smi_ownership | 63 | * speedstep_smi_ownership |
63 | */ | 64 | */ |
64 | static int speedstep_smi_ownership (void) | 65 | static int speedstep_smi_ownership(void) |
65 | { | 66 | { |
66 | u32 command, result, magic, dummy; | 67 | u32 command, result, magic, dummy; |
67 | u32 function = GET_SPEEDSTEP_OWNER; | 68 | u32 function = GET_SPEEDSTEP_OWNER; |
@@ -70,16 +71,18 @@ static int speedstep_smi_ownership (void) | |||
70 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); | 71 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); |
71 | magic = virt_to_phys(magic_data); | 72 | magic = virt_to_phys(magic_data); |
72 | 73 | ||
73 | dprintk("trying to obtain ownership with command %x at port %x\n", command, smi_port); | 74 | dprintk("trying to obtain ownership with command %x at port %x\n", |
75 | command, smi_port); | ||
74 | 76 | ||
75 | __asm__ __volatile__( | 77 | __asm__ __volatile__( |
76 | "push %%ebp\n" | 78 | "push %%ebp\n" |
77 | "out %%al, (%%dx)\n" | 79 | "out %%al, (%%dx)\n" |
78 | "pop %%ebp\n" | 80 | "pop %%ebp\n" |
79 | : "=D" (result), "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy), | 81 | : "=D" (result), |
80 | "=S" (dummy) | 82 | "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy), |
83 | "=S" (dummy) | ||
81 | : "a" (command), "b" (function), "c" (0), "d" (smi_port), | 84 | : "a" (command), "b" (function), "c" (0), "d" (smi_port), |
82 | "D" (0), "S" (magic) | 85 | "D" (0), "S" (magic) |
83 | : "memory" | 86 | : "memory" |
84 | ); | 87 | ); |
85 | 88 | ||
@@ -97,10 +100,10 @@ static int speedstep_smi_ownership (void) | |||
97 | * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing | 100 | * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing |
98 | * shows that the latter occurs if !(ist_info.event & 0xFFFF). | 101 | * shows that the latter occurs if !(ist_info.event & 0xFFFF). |
99 | */ | 102 | */ |
100 | static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) | 103 | static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high) |
101 | { | 104 | { |
102 | u32 command, result = 0, edi, high_mhz, low_mhz, dummy; | 105 | u32 command, result = 0, edi, high_mhz, low_mhz, dummy; |
103 | u32 state=0; | 106 | u32 state = 0; |
104 | u32 function = GET_SPEEDSTEP_FREQS; | 107 | u32 function = GET_SPEEDSTEP_FREQS; |
105 | 108 | ||
106 | if (!(ist_info.event & 0xFFFF)) { | 109 | if (!(ist_info.event & 0xFFFF)) { |
@@ -110,17 +113,25 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) | |||
110 | 113 | ||
111 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); | 114 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); |
112 | 115 | ||
113 | dprintk("trying to determine frequencies with command %x at port %x\n", command, smi_port); | 116 | dprintk("trying to determine frequencies with command %x at port %x\n", |
117 | command, smi_port); | ||
114 | 118 | ||
115 | __asm__ __volatile__( | 119 | __asm__ __volatile__( |
116 | "push %%ebp\n" | 120 | "push %%ebp\n" |
117 | "out %%al, (%%dx)\n" | 121 | "out %%al, (%%dx)\n" |
118 | "pop %%ebp" | 122 | "pop %%ebp" |
119 | : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi), "=S" (dummy) | 123 | : "=a" (result), |
120 | : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0) | 124 | "=b" (high_mhz), |
125 | "=c" (low_mhz), | ||
126 | "=d" (state), "=D" (edi), "=S" (dummy) | ||
127 | : "a" (command), | ||
128 | "b" (function), | ||
129 | "c" (state), | ||
130 | "d" (smi_port), "S" (0), "D" (0) | ||
121 | ); | 131 | ); |
122 | 132 | ||
123 | dprintk("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz); | 133 | dprintk("result %x, low_freq %u, high_freq %u\n", |
134 | result, low_mhz, high_mhz); | ||
124 | 135 | ||
125 | /* abort if results are obviously incorrect... */ | 136 | /* abort if results are obviously incorrect... */ |
126 | if ((high_mhz + low_mhz) < 600) | 137 | if ((high_mhz + low_mhz) < 600) |
@@ -137,26 +148,30 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) | |||
137 | * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | 148 | * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) |
138 | * | 149 | * |
139 | */ | 150 | */ |
140 | static int speedstep_get_state (void) | 151 | static int speedstep_get_state(void) |
141 | { | 152 | { |
142 | u32 function=GET_SPEEDSTEP_STATE; | 153 | u32 function = GET_SPEEDSTEP_STATE; |
143 | u32 result, state, edi, command, dummy; | 154 | u32 result, state, edi, command, dummy; |
144 | 155 | ||
145 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); | 156 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); |
146 | 157 | ||
147 | dprintk("trying to determine current setting with command %x at port %x\n", command, smi_port); | 158 | dprintk("trying to determine current setting with command %x " |
159 | "at port %x\n", command, smi_port); | ||
148 | 160 | ||
149 | __asm__ __volatile__( | 161 | __asm__ __volatile__( |
150 | "push %%ebp\n" | 162 | "push %%ebp\n" |
151 | "out %%al, (%%dx)\n" | 163 | "out %%al, (%%dx)\n" |
152 | "pop %%ebp\n" | 164 | "pop %%ebp\n" |
153 | : "=a" (result), "=b" (state), "=D" (edi), "=c" (dummy), "=d" (dummy), "=S" (dummy) | 165 | : "=a" (result), |
154 | : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0), "D" (0) | 166 | "=b" (state), "=D" (edi), |
167 | "=c" (dummy), "=d" (dummy), "=S" (dummy) | ||
168 | : "a" (command), "b" (function), "c" (0), | ||
169 | "d" (smi_port), "S" (0), "D" (0) | ||
155 | ); | 170 | ); |
156 | 171 | ||
157 | dprintk("state is %x, result is %x\n", state, result); | 172 | dprintk("state is %x, result is %x\n", state, result); |
158 | 173 | ||
159 | return (state & 1); | 174 | return state & 1; |
160 | } | 175 | } |
161 | 176 | ||
162 | 177 | ||
@@ -165,11 +180,11 @@ static int speedstep_get_state (void) | |||
165 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | 180 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) |
166 | * | 181 | * |
167 | */ | 182 | */ |
168 | static void speedstep_set_state (unsigned int state) | 183 | static void speedstep_set_state(unsigned int state) |
169 | { | 184 | { |
170 | unsigned int result = 0, command, new_state, dummy; | 185 | unsigned int result = 0, command, new_state, dummy; |
171 | unsigned long flags; | 186 | unsigned long flags; |
172 | unsigned int function=SET_SPEEDSTEP_STATE; | 187 | unsigned int function = SET_SPEEDSTEP_STATE; |
173 | unsigned int retry = 0; | 188 | unsigned int retry = 0; |
174 | 189 | ||
175 | if (state > 0x1) | 190 | if (state > 0x1) |
@@ -180,11 +195,14 @@ static void speedstep_set_state (unsigned int state) | |||
180 | 195 | ||
181 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); | 196 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); |
182 | 197 | ||
183 | dprintk("trying to set frequency to state %u with command %x at port %x\n", state, command, smi_port); | 198 | dprintk("trying to set frequency to state %u " |
199 | "with command %x at port %x\n", | ||
200 | state, command, smi_port); | ||
184 | 201 | ||
185 | do { | 202 | do { |
186 | if (retry) { | 203 | if (retry) { |
187 | dprintk("retry %u, previous result %u, waiting...\n", retry, result); | 204 | dprintk("retry %u, previous result %u, waiting...\n", |
205 | retry, result); | ||
188 | mdelay(retry * 50); | 206 | mdelay(retry * 50); |
189 | } | 207 | } |
190 | retry++; | 208 | retry++; |
@@ -192,20 +210,26 @@ static void speedstep_set_state (unsigned int state) | |||
192 | "push %%ebp\n" | 210 | "push %%ebp\n" |
193 | "out %%al, (%%dx)\n" | 211 | "out %%al, (%%dx)\n" |
194 | "pop %%ebp" | 212 | "pop %%ebp" |
195 | : "=b" (new_state), "=D" (result), "=c" (dummy), "=a" (dummy), | 213 | : "=b" (new_state), "=D" (result), |
196 | "=d" (dummy), "=S" (dummy) | 214 | "=c" (dummy), "=a" (dummy), |
197 | : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0) | 215 | "=d" (dummy), "=S" (dummy) |
216 | : "a" (command), "b" (function), "c" (state), | ||
217 | "d" (smi_port), "S" (0), "D" (0) | ||
198 | ); | 218 | ); |
199 | } while ((new_state != state) && (retry <= SMI_TRIES)); | 219 | } while ((new_state != state) && (retry <= SMI_TRIES)); |
200 | 220 | ||
201 | /* enable IRQs */ | 221 | /* enable IRQs */ |
202 | local_irq_restore(flags); | 222 | local_irq_restore(flags); |
203 | 223 | ||
204 | if (new_state == state) { | 224 | if (new_state == state) |
205 | dprintk("change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result); | 225 | dprintk("change to %u MHz succeeded after %u tries " |
206 | } else { | 226 | "with result %u\n", |
207 | printk(KERN_ERR "cpufreq: change to state %u failed with new_state %u and result %u\n", state, new_state, result); | 227 | (speedstep_freqs[new_state].frequency / 1000), |
208 | } | 228 | retry, result); |
229 | else | ||
230 | printk(KERN_ERR "cpufreq: change to state %u " | ||
231 | "failed with new_state %u and result %u\n", | ||
232 | state, new_state, result); | ||
209 | 233 | ||
210 | return; | 234 | return; |
211 | } | 235 | } |
@@ -219,13 +243,14 @@ static void speedstep_set_state (unsigned int state) | |||
219 | * | 243 | * |
220 | * Sets a new CPUFreq policy/freq. | 244 | * Sets a new CPUFreq policy/freq. |
221 | */ | 245 | */ |
222 | static int speedstep_target (struct cpufreq_policy *policy, | 246 | static int speedstep_target(struct cpufreq_policy *policy, |
223 | unsigned int target_freq, unsigned int relation) | 247 | unsigned int target_freq, unsigned int relation) |
224 | { | 248 | { |
225 | unsigned int newstate = 0; | 249 | unsigned int newstate = 0; |
226 | struct cpufreq_freqs freqs; | 250 | struct cpufreq_freqs freqs; |
227 | 251 | ||
228 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) | 252 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], |
253 | target_freq, relation, &newstate)) | ||
229 | return -EINVAL; | 254 | return -EINVAL; |
230 | 255 | ||
231 | freqs.old = speedstep_freqs[speedstep_get_state()].frequency; | 256 | freqs.old = speedstep_freqs[speedstep_get_state()].frequency; |
@@ -250,7 +275,7 @@ static int speedstep_target (struct cpufreq_policy *policy, | |||
250 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with | 275 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with |
251 | * at least one border included. | 276 | * at least one border included. |
252 | */ | 277 | */ |
253 | static int speedstep_verify (struct cpufreq_policy *policy) | 278 | static int speedstep_verify(struct cpufreq_policy *policy) |
254 | { | 279 | { |
255 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); | 280 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); |
256 | } | 281 | } |
@@ -259,7 +284,8 @@ static int speedstep_verify (struct cpufreq_policy *policy) | |||
259 | static int speedstep_cpu_init(struct cpufreq_policy *policy) | 284 | static int speedstep_cpu_init(struct cpufreq_policy *policy) |
260 | { | 285 | { |
261 | int result; | 286 | int result; |
262 | unsigned int speed,state; | 287 | unsigned int speed, state; |
288 | unsigned int *low, *high; | ||
263 | 289 | ||
264 | /* capability check */ | 290 | /* capability check */ |
265 | if (policy->cpu != 0) | 291 | if (policy->cpu != 0) |
@@ -272,19 +298,23 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
272 | } | 298 | } |
273 | 299 | ||
274 | /* detect low and high frequency */ | 300 | /* detect low and high frequency */ |
275 | result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency, | 301 | low = &speedstep_freqs[SPEEDSTEP_LOW].frequency; |
276 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency); | 302 | high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency; |
303 | |||
304 | result = speedstep_smi_get_freqs(low, high); | ||
277 | if (result) { | 305 | if (result) { |
278 | /* fall back to speedstep_lib.c dection mechanism: try both states out */ | 306 | /* fall back to speedstep_lib.c dection mechanism: |
279 | dprintk("could not detect low and high frequencies by SMI call.\n"); | 307 | * try both states out */ |
308 | dprintk("could not detect low and high frequencies " | ||
309 | "by SMI call.\n"); | ||
280 | result = speedstep_get_freqs(speedstep_processor, | 310 | result = speedstep_get_freqs(speedstep_processor, |
281 | &speedstep_freqs[SPEEDSTEP_LOW].frequency, | 311 | low, high, |
282 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency, | ||
283 | NULL, | 312 | NULL, |
284 | &speedstep_set_state); | 313 | &speedstep_set_state); |
285 | 314 | ||
286 | if (result) { | 315 | if (result) { |
287 | dprintk("could not detect two different speeds -- aborting.\n"); | 316 | dprintk("could not detect two different speeds" |
317 | " -- aborting.\n"); | ||
288 | return result; | 318 | return result; |
289 | } else | 319 | } else |
290 | dprintk("workaround worked.\n"); | 320 | dprintk("workaround worked.\n"); |
@@ -295,7 +325,8 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
295 | speed = speedstep_freqs[state].frequency; | 325 | speed = speedstep_freqs[state].frequency; |
296 | 326 | ||
297 | dprintk("currently at %s speed setting - %i MHz\n", | 327 | dprintk("currently at %s speed setting - %i MHz\n", |
298 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", | 328 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) |
329 | ? "low" : "high", | ||
299 | (speed / 1000)); | 330 | (speed / 1000)); |
300 | 331 | ||
301 | /* cpuinfo and default policy values */ | 332 | /* cpuinfo and default policy values */ |
@@ -304,7 +335,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
304 | 335 | ||
305 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); | 336 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); |
306 | if (result) | 337 | if (result) |
307 | return (result); | 338 | return result; |
308 | 339 | ||
309 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); | 340 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); |
310 | 341 | ||
@@ -321,7 +352,7 @@ static unsigned int speedstep_get(unsigned int cpu) | |||
321 | { | 352 | { |
322 | if (cpu) | 353 | if (cpu) |
323 | return -ENODEV; | 354 | return -ENODEV; |
324 | return speedstep_get_processor_frequency(speedstep_processor); | 355 | return speedstep_get_frequency(speedstep_processor); |
325 | } | 356 | } |
326 | 357 | ||
327 | 358 | ||
@@ -335,7 +366,7 @@ static int speedstep_resume(struct cpufreq_policy *policy) | |||
335 | return result; | 366 | return result; |
336 | } | 367 | } |
337 | 368 | ||
338 | static struct freq_attr* speedstep_attr[] = { | 369 | static struct freq_attr *speedstep_attr[] = { |
339 | &cpufreq_freq_attr_scaling_available_freqs, | 370 | &cpufreq_freq_attr_scaling_available_freqs, |
340 | NULL, | 371 | NULL, |
341 | }; | 372 | }; |
@@ -364,21 +395,23 @@ static int __init speedstep_init(void) | |||
364 | speedstep_processor = speedstep_detect_processor(); | 395 | speedstep_processor = speedstep_detect_processor(); |
365 | 396 | ||
366 | switch (speedstep_processor) { | 397 | switch (speedstep_processor) { |
367 | case SPEEDSTEP_PROCESSOR_PIII_T: | 398 | case SPEEDSTEP_CPU_PIII_T: |
368 | case SPEEDSTEP_PROCESSOR_PIII_C: | 399 | case SPEEDSTEP_CPU_PIII_C: |
369 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: | 400 | case SPEEDSTEP_CPU_PIII_C_EARLY: |
370 | break; | 401 | break; |
371 | default: | 402 | default: |
372 | speedstep_processor = 0; | 403 | speedstep_processor = 0; |
373 | } | 404 | } |
374 | 405 | ||
375 | if (!speedstep_processor) { | 406 | if (!speedstep_processor) { |
376 | dprintk ("No supported Intel CPU detected.\n"); | 407 | dprintk("No supported Intel CPU detected.\n"); |
377 | return -ENODEV; | 408 | return -ENODEV; |
378 | } | 409 | } |
379 | 410 | ||
380 | dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", | 411 | dprintk("signature:0x%.8lx, command:0x%.8lx, " |
381 | ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level); | 412 | "event:0x%.8lx, perf_level:0x%.8lx.\n", |
413 | ist_info.signature, ist_info.command, | ||
414 | ist_info.event, ist_info.perf_level); | ||
382 | 415 | ||
383 | /* Error if no IST-SMI BIOS or no PARM | 416 | /* Error if no IST-SMI BIOS or no PARM |
384 | sig= 'ISGE' aka 'Intel Speedstep Gate E' */ | 417 | sig= 'ISGE' aka 'Intel Speedstep Gate E' */ |
@@ -416,17 +449,20 @@ static void __exit speedstep_exit(void) | |||
416 | cpufreq_unregister_driver(&speedstep_driver); | 449 | cpufreq_unregister_driver(&speedstep_driver); |
417 | } | 450 | } |
418 | 451 | ||
419 | module_param(smi_port, int, 0444); | 452 | module_param(smi_port, int, 0444); |
420 | module_param(smi_cmd, int, 0444); | 453 | module_param(smi_cmd, int, 0444); |
421 | module_param(smi_sig, uint, 0444); | 454 | module_param(smi_sig, uint, 0444); |
422 | 455 | ||
423 | MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value -- Intel's default setting is 0xb2"); | 456 | MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value " |
424 | MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value -- Intel's default setting is 0x82"); | 457 | "-- Intel's default setting is 0xb2"); |
425 | MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the SMI interface."); | 458 | MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value " |
459 | "-- Intel's default setting is 0x82"); | ||
460 | MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the " | ||
461 | "SMI interface."); | ||
426 | 462 | ||
427 | MODULE_AUTHOR ("Hiroshi Miura"); | 463 | MODULE_AUTHOR("Hiroshi Miura"); |
428 | MODULE_DESCRIPTION ("Speedstep driver for IST applet SMI interface."); | 464 | MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface."); |
429 | MODULE_LICENSE ("GPL"); | 465 | MODULE_LICENSE("GPL"); |
430 | 466 | ||
431 | module_init(speedstep_init); | 467 | module_init(speedstep_init); |
432 | module_exit(speedstep_exit); | 468 | module_exit(speedstep_exit); |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index b09d4eb52bb9..7437fa133c02 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
5 | #include <linux/bitops.h> | 5 | #include <linux/bitops.h> |
6 | #include <linux/smp.h> | 6 | #include <linux/smp.h> |
7 | #include <linux/sched.h> | ||
7 | #include <linux/thread_info.h> | 8 | #include <linux/thread_info.h> |
8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
9 | 10 | ||
@@ -61,11 +62,16 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate | 64 | * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate |
64 | * with P/T states and does not stop in deep C-states | 65 | * with P/T states and does not stop in deep C-states. |
66 | * | ||
67 | * It is also reliable across cores and sockets. (but not across | ||
68 | * cabinets - we turn it off in that case explicitly.) | ||
65 | */ | 69 | */ |
66 | if (c->x86_power & (1 << 8)) { | 70 | if (c->x86_power & (1 << 8)) { |
67 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 71 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
68 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); | 72 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); |
73 | set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); | ||
74 | sched_clock_stable = 1; | ||
69 | } | 75 | } |
70 | 76 | ||
71 | /* | 77 | /* |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index c471eb1a389c..483eda96e102 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -159,7 +159,7 @@ struct _cpuid4_info_regs { | |||
159 | unsigned long can_disable; | 159 | unsigned long can_disable; |
160 | }; | 160 | }; |
161 | 161 | ||
162 | #ifdef CONFIG_PCI | 162 | #if defined(CONFIG_PCI) && defined(CONFIG_SYSFS) |
163 | static struct pci_device_id k8_nb_id[] = { | 163 | static struct pci_device_id k8_nb_id[] = { |
164 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, | 164 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, |
165 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) }, | 165 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) }, |
@@ -324,15 +324,6 @@ __cpuinit cpuid4_cache_lookup_regs(int index, | |||
324 | return 0; | 324 | return 0; |
325 | } | 325 | } |
326 | 326 | ||
327 | static int | ||
328 | __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | ||
329 | { | ||
330 | struct _cpuid4_info_regs *leaf_regs = | ||
331 | (struct _cpuid4_info_regs *)this_leaf; | ||
332 | |||
333 | return cpuid4_cache_lookup_regs(index, leaf_regs); | ||
334 | } | ||
335 | |||
336 | static int __cpuinit find_num_cache_leaves(void) | 327 | static int __cpuinit find_num_cache_leaves(void) |
337 | { | 328 | { |
338 | unsigned int eax, ebx, ecx, edx; | 329 | unsigned int eax, ebx, ecx, edx; |
@@ -508,6 +499,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
508 | return l2; | 499 | return l2; |
509 | } | 500 | } |
510 | 501 | ||
502 | #ifdef CONFIG_SYSFS | ||
503 | |||
511 | /* pointer to _cpuid4_info array (for each cache leaf) */ | 504 | /* pointer to _cpuid4_info array (for each cache leaf) */ |
512 | static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info); | 505 | static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info); |
513 | #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y])) | 506 | #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y])) |
@@ -571,6 +564,15 @@ static void __cpuinit free_cache_attributes(unsigned int cpu) | |||
571 | per_cpu(cpuid4_info, cpu) = NULL; | 564 | per_cpu(cpuid4_info, cpu) = NULL; |
572 | } | 565 | } |
573 | 566 | ||
567 | static int | ||
568 | __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | ||
569 | { | ||
570 | struct _cpuid4_info_regs *leaf_regs = | ||
571 | (struct _cpuid4_info_regs *)this_leaf; | ||
572 | |||
573 | return cpuid4_cache_lookup_regs(index, leaf_regs); | ||
574 | } | ||
575 | |||
574 | static void __cpuinit get_cpu_leaves(void *_retval) | 576 | static void __cpuinit get_cpu_leaves(void *_retval) |
575 | { | 577 | { |
576 | int j, *retval = _retval, cpu = smp_processor_id(); | 578 | int j, *retval = _retval, cpu = smp_processor_id(); |
@@ -612,8 +614,6 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) | |||
612 | return retval; | 614 | return retval; |
613 | } | 615 | } |
614 | 616 | ||
615 | #ifdef CONFIG_SYSFS | ||
616 | |||
617 | #include <linux/kobject.h> | 617 | #include <linux/kobject.h> |
618 | #include <linux/sysfs.h> | 618 | #include <linux/sysfs.h> |
619 | 619 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index ca14604611ec..863f89568b1a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -990,7 +990,7 @@ static struct sysdev_attribute *mce_attributes[] = { | |||
990 | NULL | 990 | NULL |
991 | }; | 991 | }; |
992 | 992 | ||
993 | static cpumask_t mce_device_initialized = CPU_MASK_NONE; | 993 | static cpumask_var_t mce_device_initialized; |
994 | 994 | ||
995 | /* Per cpu sysdev init. All of the cpus still share the same ctl bank */ | 995 | /* Per cpu sysdev init. All of the cpus still share the same ctl bank */ |
996 | static __cpuinit int mce_create_device(unsigned int cpu) | 996 | static __cpuinit int mce_create_device(unsigned int cpu) |
@@ -1021,7 +1021,7 @@ static __cpuinit int mce_create_device(unsigned int cpu) | |||
1021 | if (err) | 1021 | if (err) |
1022 | goto error2; | 1022 | goto error2; |
1023 | } | 1023 | } |
1024 | cpu_set(cpu, mce_device_initialized); | 1024 | cpumask_set_cpu(cpu, mce_device_initialized); |
1025 | 1025 | ||
1026 | return 0; | 1026 | return 0; |
1027 | error2: | 1027 | error2: |
@@ -1043,7 +1043,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) | |||
1043 | { | 1043 | { |
1044 | int i; | 1044 | int i; |
1045 | 1045 | ||
1046 | if (!cpu_isset(cpu, mce_device_initialized)) | 1046 | if (!cpumask_test_cpu(cpu, mce_device_initialized)) |
1047 | return; | 1047 | return; |
1048 | 1048 | ||
1049 | for (i = 0; mce_attributes[i]; i++) | 1049 | for (i = 0; mce_attributes[i]; i++) |
@@ -1053,7 +1053,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) | |||
1053 | sysdev_remove_file(&per_cpu(device_mce, cpu), | 1053 | sysdev_remove_file(&per_cpu(device_mce, cpu), |
1054 | &bank_attrs[i]); | 1054 | &bank_attrs[i]); |
1055 | sysdev_unregister(&per_cpu(device_mce,cpu)); | 1055 | sysdev_unregister(&per_cpu(device_mce,cpu)); |
1056 | cpu_clear(cpu, mce_device_initialized); | 1056 | cpumask_clear_cpu(cpu, mce_device_initialized); |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | /* Make sure there are no machine checks on offlined CPUs. */ | 1059 | /* Make sure there are no machine checks on offlined CPUs. */ |
@@ -1162,6 +1162,8 @@ static __init int mce_init_device(void) | |||
1162 | if (!mce_available(&boot_cpu_data)) | 1162 | if (!mce_available(&boot_cpu_data)) |
1163 | return -EIO; | 1163 | return -EIO; |
1164 | 1164 | ||
1165 | alloc_cpumask_var(&mce_device_initialized, GFP_KERNEL); | ||
1166 | |||
1165 | err = mce_init_banks(); | 1167 | err = mce_init_banks(); |
1166 | if (err) | 1168 | if (err) |
1167 | return err; | 1169 | return err; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 7d01be868870..56dde9c4bc96 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -485,7 +485,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
485 | 485 | ||
486 | #ifdef CONFIG_SMP | 486 | #ifdef CONFIG_SMP |
487 | if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ | 487 | if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ |
488 | i = cpumask_first(&per_cpu(cpu_core_map, cpu)); | 488 | i = cpumask_first(cpu_core_mask(cpu)); |
489 | 489 | ||
490 | /* first core not up yet */ | 490 | /* first core not up yet */ |
491 | if (cpu_data(i).cpu_core_id) | 491 | if (cpu_data(i).cpu_core_id) |
@@ -505,7 +505,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
505 | if (err) | 505 | if (err) |
506 | goto out; | 506 | goto out; |
507 | 507 | ||
508 | cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu)); | 508 | cpumask_copy(b->cpus, cpu_core_mask(cpu)); |
509 | per_cpu(threshold_banks, cpu)[bank] = b; | 509 | per_cpu(threshold_banks, cpu)[bank] = b; |
510 | goto out; | 510 | goto out; |
511 | } | 511 | } |
@@ -529,7 +529,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
529 | #ifndef CONFIG_SMP | 529 | #ifndef CONFIG_SMP |
530 | cpumask_setall(b->cpus); | 530 | cpumask_setall(b->cpus); |
531 | #else | 531 | #else |
532 | cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu)); | 532 | cpumask_copy(b->cpus, cpu_core_mask(cpu)); |
533 | #endif | 533 | #endif |
534 | 534 | ||
535 | per_cpu(threshold_banks, cpu)[bank] = b; | 535 | per_cpu(threshold_banks, cpu)[bank] = b; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 57df3d383470..d6b72df89d69 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c | |||
@@ -249,7 +249,7 @@ void cmci_rediscover(int dying) | |||
249 | for_each_online_cpu (cpu) { | 249 | for_each_online_cpu (cpu) { |
250 | if (cpu == dying) | 250 | if (cpu == dying) |
251 | continue; | 251 | continue; |
252 | if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu))) | 252 | if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) |
253 | continue; | 253 | continue; |
254 | /* Recheck banks in case CPUs don't all have the same */ | 254 | /* Recheck banks in case CPUs don't all have the same */ |
255 | if (cmci_supported(&banks)) | 255 | if (cmci_supported(&banks)) |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 37f28fc7cf95..0b776c09aff3 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -462,9 +462,6 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
462 | *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; | 462 | *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; |
463 | *type = base_lo & 0xff; | 463 | *type = base_lo & 0xff; |
464 | 464 | ||
465 | printk(KERN_DEBUG " get_mtrr: cpu%d reg%02d base=%010lx size=%010lx %s\n", | ||
466 | cpu, reg, *base, *size, | ||
467 | mtrr_attrib_to_str(*type & 0xff)); | ||
468 | out_put_cpu: | 465 | out_put_cpu: |
469 | put_cpu(); | 466 | put_cpu(); |
470 | } | 467 | } |
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index 4c4214690dd1..fb73a52913a4 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c | |||
@@ -377,10 +377,6 @@ static const struct file_operations mtrr_fops = { | |||
377 | .release = mtrr_close, | 377 | .release = mtrr_close, |
378 | }; | 378 | }; |
379 | 379 | ||
380 | |||
381 | static struct proc_dir_entry *proc_root_mtrr; | ||
382 | |||
383 | |||
384 | static int mtrr_seq_show(struct seq_file *seq, void *offset) | 380 | static int mtrr_seq_show(struct seq_file *seq, void *offset) |
385 | { | 381 | { |
386 | char factor; | 382 | char factor; |
@@ -423,11 +419,7 @@ static int __init mtrr_if_init(void) | |||
423 | (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) | 419 | (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) |
424 | return -ENODEV; | 420 | return -ENODEV; |
425 | 421 | ||
426 | proc_root_mtrr = | 422 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); |
427 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); | ||
428 | |||
429 | if (proc_root_mtrr) | ||
430 | proc_root_mtrr->owner = THIS_MODULE; | ||
431 | return 0; | 423 | return 0; |
432 | } | 424 | } |
433 | 425 | ||
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index d67e0e48bc2d..f93047fed791 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
@@ -14,7 +14,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | |||
14 | if (c->x86_max_cores * smp_num_siblings > 1) { | 14 | if (c->x86_max_cores * smp_num_siblings > 1) { |
15 | seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); | 15 | seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); |
16 | seq_printf(m, "siblings\t: %d\n", | 16 | seq_printf(m, "siblings\t: %d\n", |
17 | cpus_weight(per_cpu(cpu_core_map, cpu))); | 17 | cpumask_weight(cpu_sibling_mask(cpu))); |
18 | seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); | 18 | seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); |
19 | seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); | 19 | seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); |
20 | seq_printf(m, "apicid\t\t: %d\n", c->apicid); | 20 | seq_printf(m, "apicid\t\t: %d\n", c->apicid); |
@@ -143,9 +143,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
143 | static void *c_start(struct seq_file *m, loff_t *pos) | 143 | static void *c_start(struct seq_file *m, loff_t *pos) |
144 | { | 144 | { |
145 | if (*pos == 0) /* just in case, cpu 0 is not the first */ | 145 | if (*pos == 0) /* just in case, cpu 0 is not the first */ |
146 | *pos = first_cpu(cpu_online_map); | 146 | *pos = cpumask_first(cpu_online_mask); |
147 | else | 147 | else |
148 | *pos = next_cpu_nr(*pos - 1, cpu_online_map); | 148 | *pos = cpumask_next(*pos - 1, cpu_online_mask); |
149 | if ((*pos) < nr_cpu_ids) | 149 | if ((*pos) < nr_cpu_ids) |
150 | return &cpu_data(*pos); | 150 | return &cpu_data(*pos); |
151 | return NULL; | 151 | return NULL; |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 87d103ded1c3..95ea5fa7d444 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -10,10 +10,12 @@ | |||
10 | #include <linux/kdebug.h> | 10 | #include <linux/kdebug.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/ptrace.h> | 12 | #include <linux/ptrace.h> |
13 | #include <linux/ftrace.h> | ||
13 | #include <linux/kexec.h> | 14 | #include <linux/kexec.h> |
14 | #include <linux/bug.h> | 15 | #include <linux/bug.h> |
15 | #include <linux/nmi.h> | 16 | #include <linux/nmi.h> |
16 | #include <linux/sysfs.h> | 17 | #include <linux/sysfs.h> |
18 | #include <linux/ftrace.h> | ||
17 | 19 | ||
18 | #include <asm/stacktrace.h> | 20 | #include <asm/stacktrace.h> |
19 | 21 | ||
@@ -195,6 +197,11 @@ unsigned __kprobes long oops_begin(void) | |||
195 | int cpu; | 197 | int cpu; |
196 | unsigned long flags; | 198 | unsigned long flags; |
197 | 199 | ||
200 | /* notify the hw-branch tracer so it may disable tracing and | ||
201 | add the last trace to the trace buffer - | ||
202 | the earlier this happens, the more useful the trace. */ | ||
203 | trace_hw_branch_oops(); | ||
204 | |||
198 | oops_enter(); | 205 | oops_enter(); |
199 | 206 | ||
200 | /* racy, but better than risking deadlock. */ | 207 | /* racy, but better than risking deadlock. */ |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index fb638d9ce6d2..ef2c3563357d 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -233,7 +233,7 @@ void __init e820_print_map(char *who) | |||
233 | */ | 233 | */ |
234 | 234 | ||
235 | int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, | 235 | int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, |
236 | int *pnr_map) | 236 | u32 *pnr_map) |
237 | { | 237 | { |
238 | struct change_member { | 238 | struct change_member { |
239 | struct e820entry *pbios; /* pointer to original bios entry */ | 239 | struct e820entry *pbios; /* pointer to original bios entry */ |
@@ -552,7 +552,7 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, | |||
552 | 552 | ||
553 | void __init update_e820(void) | 553 | void __init update_e820(void) |
554 | { | 554 | { |
555 | int nr_map; | 555 | u32 nr_map; |
556 | 556 | ||
557 | nr_map = e820.nr_map; | 557 | nr_map = e820.nr_map; |
558 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map)) | 558 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map)) |
@@ -563,7 +563,7 @@ void __init update_e820(void) | |||
563 | } | 563 | } |
564 | static void __init update_e820_saved(void) | 564 | static void __init update_e820_saved(void) |
565 | { | 565 | { |
566 | int nr_map; | 566 | u32 nr_map; |
567 | 567 | ||
568 | nr_map = e820_saved.nr_map; | 568 | nr_map = e820_saved.nr_map; |
569 | if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map)) | 569 | if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map)) |
@@ -1303,7 +1303,7 @@ early_param("memmap", parse_memmap_opt); | |||
1303 | void __init finish_e820_parsing(void) | 1303 | void __init finish_e820_parsing(void) |
1304 | { | 1304 | { |
1305 | if (userdef) { | 1305 | if (userdef) { |
1306 | int nr = e820.nr_map; | 1306 | u32 nr = e820.nr_map; |
1307 | 1307 | ||
1308 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0) | 1308 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0) |
1309 | early_panic("Invalid user supplied memory map"); | 1309 | early_panic("Invalid user supplied memory map"); |
@@ -1386,7 +1386,7 @@ void __init e820_reserve_resources_late(void) | |||
1386 | char *__init default_machine_specific_memory_setup(void) | 1386 | char *__init default_machine_specific_memory_setup(void) |
1387 | { | 1387 | { |
1388 | char *who = "BIOS-e820"; | 1388 | char *who = "BIOS-e820"; |
1389 | int new_nr; | 1389 | u32 new_nr; |
1390 | /* | 1390 | /* |
1391 | * Try to copy the BIOS-supplied E820-map. | 1391 | * Try to copy the BIOS-supplied E820-map. |
1392 | * | 1392 | * |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 231bdd3c5b1c..18dfa30795c9 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -18,14 +18,28 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | 20 | ||
21 | #include <trace/syscall.h> | ||
22 | |||
23 | #include <asm/cacheflush.h> | ||
21 | #include <asm/ftrace.h> | 24 | #include <asm/ftrace.h> |
22 | #include <linux/ftrace.h> | ||
23 | #include <asm/nops.h> | 25 | #include <asm/nops.h> |
24 | #include <asm/nmi.h> | 26 | #include <asm/nmi.h> |
25 | 27 | ||
26 | 28 | ||
27 | #ifdef CONFIG_DYNAMIC_FTRACE | 29 | #ifdef CONFIG_DYNAMIC_FTRACE |
28 | 30 | ||
31 | int ftrace_arch_code_modify_prepare(void) | ||
32 | { | ||
33 | set_kernel_text_rw(); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | int ftrace_arch_code_modify_post_process(void) | ||
38 | { | ||
39 | set_kernel_text_ro(); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
29 | union ftrace_code_union { | 43 | union ftrace_code_union { |
30 | char code[MCOUNT_INSN_SIZE]; | 44 | char code[MCOUNT_INSN_SIZE]; |
31 | struct { | 45 | struct { |
@@ -66,11 +80,11 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | |||
66 | * | 80 | * |
67 | * 1) Put the instruction pointer into the IP buffer | 81 | * 1) Put the instruction pointer into the IP buffer |
68 | * and the new code into the "code" buffer. | 82 | * and the new code into the "code" buffer. |
69 | * 2) Set a flag that says we are modifying code | 83 | * 2) Wait for any running NMIs to finish and set a flag that says |
70 | * 3) Wait for any running NMIs to finish. | 84 | * we are modifying code, it is done in an atomic operation. |
71 | * 4) Write the code | 85 | * 3) Write the code |
72 | * 5) clear the flag. | 86 | * 4) clear the flag. |
73 | * 6) Wait for any running NMIs to finish. | 87 | * 5) Wait for any running NMIs to finish. |
74 | * | 88 | * |
75 | * If an NMI is executed, the first thing it does is to call | 89 | * If an NMI is executed, the first thing it does is to call |
76 | * "ftrace_nmi_enter". This will check if the flag is set to write | 90 | * "ftrace_nmi_enter". This will check if the flag is set to write |
@@ -82,9 +96,9 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | |||
82 | * are the same as what exists. | 96 | * are the same as what exists. |
83 | */ | 97 | */ |
84 | 98 | ||
85 | static atomic_t in_nmi = ATOMIC_INIT(0); | 99 | #define MOD_CODE_WRITE_FLAG (1 << 31) /* set when NMI should do the write */ |
100 | static atomic_t nmi_running = ATOMIC_INIT(0); | ||
86 | static int mod_code_status; /* holds return value of text write */ | 101 | static int mod_code_status; /* holds return value of text write */ |
87 | static int mod_code_write; /* set when NMI should do the write */ | ||
88 | static void *mod_code_ip; /* holds the IP to write to */ | 102 | static void *mod_code_ip; /* holds the IP to write to */ |
89 | static void *mod_code_newcode; /* holds the text to write to the IP */ | 103 | static void *mod_code_newcode; /* holds the text to write to the IP */ |
90 | 104 | ||
@@ -101,6 +115,20 @@ int ftrace_arch_read_dyn_info(char *buf, int size) | |||
101 | return r; | 115 | return r; |
102 | } | 116 | } |
103 | 117 | ||
118 | static void clear_mod_flag(void) | ||
119 | { | ||
120 | int old = atomic_read(&nmi_running); | ||
121 | |||
122 | for (;;) { | ||
123 | int new = old & ~MOD_CODE_WRITE_FLAG; | ||
124 | |||
125 | if (old == new) | ||
126 | break; | ||
127 | |||
128 | old = atomic_cmpxchg(&nmi_running, old, new); | ||
129 | } | ||
130 | } | ||
131 | |||
104 | static void ftrace_mod_code(void) | 132 | static void ftrace_mod_code(void) |
105 | { | 133 | { |
106 | /* | 134 | /* |
@@ -111,37 +139,52 @@ static void ftrace_mod_code(void) | |||
111 | */ | 139 | */ |
112 | mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, | 140 | mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, |
113 | MCOUNT_INSN_SIZE); | 141 | MCOUNT_INSN_SIZE); |
142 | |||
143 | /* if we fail, then kill any new writers */ | ||
144 | if (mod_code_status) | ||
145 | clear_mod_flag(); | ||
114 | } | 146 | } |
115 | 147 | ||
116 | void ftrace_nmi_enter(void) | 148 | void ftrace_nmi_enter(void) |
117 | { | 149 | { |
118 | atomic_inc(&in_nmi); | 150 | if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) { |
119 | /* Must have in_nmi seen before reading write flag */ | 151 | smp_rmb(); |
120 | smp_mb(); | ||
121 | if (mod_code_write) { | ||
122 | ftrace_mod_code(); | 152 | ftrace_mod_code(); |
123 | atomic_inc(&nmi_update_count); | 153 | atomic_inc(&nmi_update_count); |
124 | } | 154 | } |
155 | /* Must have previous changes seen before executions */ | ||
156 | smp_mb(); | ||
125 | } | 157 | } |
126 | 158 | ||
127 | void ftrace_nmi_exit(void) | 159 | void ftrace_nmi_exit(void) |
128 | { | 160 | { |
129 | /* Finish all executions before clearing in_nmi */ | 161 | /* Finish all executions before clearing nmi_running */ |
130 | smp_wmb(); | 162 | smp_mb(); |
131 | atomic_dec(&in_nmi); | 163 | atomic_dec(&nmi_running); |
164 | } | ||
165 | |||
166 | static void wait_for_nmi_and_set_mod_flag(void) | ||
167 | { | ||
168 | if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG)) | ||
169 | return; | ||
170 | |||
171 | do { | ||
172 | cpu_relax(); | ||
173 | } while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG)); | ||
174 | |||
175 | nmi_wait_count++; | ||
132 | } | 176 | } |
133 | 177 | ||
134 | static void wait_for_nmi(void) | 178 | static void wait_for_nmi(void) |
135 | { | 179 | { |
136 | int waited = 0; | 180 | if (!atomic_read(&nmi_running)) |
181 | return; | ||
137 | 182 | ||
138 | while (atomic_read(&in_nmi)) { | 183 | do { |
139 | waited = 1; | ||
140 | cpu_relax(); | 184 | cpu_relax(); |
141 | } | 185 | } while (atomic_read(&nmi_running)); |
142 | 186 | ||
143 | if (waited) | 187 | nmi_wait_count++; |
144 | nmi_wait_count++; | ||
145 | } | 188 | } |
146 | 189 | ||
147 | static int | 190 | static int |
@@ -151,14 +194,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code) | |||
151 | mod_code_newcode = new_code; | 194 | mod_code_newcode = new_code; |
152 | 195 | ||
153 | /* The buffers need to be visible before we let NMIs write them */ | 196 | /* The buffers need to be visible before we let NMIs write them */ |
154 | smp_wmb(); | ||
155 | |||
156 | mod_code_write = 1; | ||
157 | |||
158 | /* Make sure write bit is visible before we wait on NMIs */ | ||
159 | smp_mb(); | 197 | smp_mb(); |
160 | 198 | ||
161 | wait_for_nmi(); | 199 | wait_for_nmi_and_set_mod_flag(); |
162 | 200 | ||
163 | /* Make sure all running NMIs have finished before we write the code */ | 201 | /* Make sure all running NMIs have finished before we write the code */ |
164 | smp_mb(); | 202 | smp_mb(); |
@@ -166,13 +204,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code) | |||
166 | ftrace_mod_code(); | 204 | ftrace_mod_code(); |
167 | 205 | ||
168 | /* Make sure the write happens before clearing the bit */ | 206 | /* Make sure the write happens before clearing the bit */ |
169 | smp_wmb(); | ||
170 | |||
171 | mod_code_write = 0; | ||
172 | |||
173 | /* make sure NMIs see the cleared bit */ | ||
174 | smp_mb(); | 207 | smp_mb(); |
175 | 208 | ||
209 | clear_mod_flag(); | ||
176 | wait_for_nmi(); | 210 | wait_for_nmi(); |
177 | 211 | ||
178 | return mod_code_status; | 212 | return mod_code_status; |
@@ -368,100 +402,8 @@ int ftrace_disable_ftrace_graph_caller(void) | |||
368 | return ftrace_mod_jmp(ip, old_offset, new_offset); | 402 | return ftrace_mod_jmp(ip, old_offset, new_offset); |
369 | } | 403 | } |
370 | 404 | ||
371 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
372 | |||
373 | /* | ||
374 | * These functions are picked from those used on | ||
375 | * this page for dynamic ftrace. They have been | ||
376 | * simplified to ignore all traces in NMI context. | ||
377 | */ | ||
378 | static atomic_t in_nmi; | ||
379 | |||
380 | void ftrace_nmi_enter(void) | ||
381 | { | ||
382 | atomic_inc(&in_nmi); | ||
383 | } | ||
384 | |||
385 | void ftrace_nmi_exit(void) | ||
386 | { | ||
387 | atomic_dec(&in_nmi); | ||
388 | } | ||
389 | |||
390 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | 405 | #endif /* !CONFIG_DYNAMIC_FTRACE */ |
391 | 406 | ||
392 | /* Add a function return address to the trace stack on thread info.*/ | ||
393 | static int push_return_trace(unsigned long ret, unsigned long long time, | ||
394 | unsigned long func, int *depth) | ||
395 | { | ||
396 | int index; | ||
397 | |||
398 | if (!current->ret_stack) | ||
399 | return -EBUSY; | ||
400 | |||
401 | /* The return trace stack is full */ | ||
402 | if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { | ||
403 | atomic_inc(¤t->trace_overrun); | ||
404 | return -EBUSY; | ||
405 | } | ||
406 | |||
407 | index = ++current->curr_ret_stack; | ||
408 | barrier(); | ||
409 | current->ret_stack[index].ret = ret; | ||
410 | current->ret_stack[index].func = func; | ||
411 | current->ret_stack[index].calltime = time; | ||
412 | *depth = index; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | /* Retrieve a function return address to the trace stack on thread info.*/ | ||
418 | static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret) | ||
419 | { | ||
420 | int index; | ||
421 | |||
422 | index = current->curr_ret_stack; | ||
423 | |||
424 | if (unlikely(index < 0)) { | ||
425 | ftrace_graph_stop(); | ||
426 | WARN_ON(1); | ||
427 | /* Might as well panic, otherwise we have no where to go */ | ||
428 | *ret = (unsigned long)panic; | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | *ret = current->ret_stack[index].ret; | ||
433 | trace->func = current->ret_stack[index].func; | ||
434 | trace->calltime = current->ret_stack[index].calltime; | ||
435 | trace->overrun = atomic_read(¤t->trace_overrun); | ||
436 | trace->depth = index; | ||
437 | barrier(); | ||
438 | current->curr_ret_stack--; | ||
439 | |||
440 | } | ||
441 | |||
442 | /* | ||
443 | * Send the trace to the ring-buffer. | ||
444 | * @return the original return address. | ||
445 | */ | ||
446 | unsigned long ftrace_return_to_handler(void) | ||
447 | { | ||
448 | struct ftrace_graph_ret trace; | ||
449 | unsigned long ret; | ||
450 | |||
451 | pop_return_trace(&trace, &ret); | ||
452 | trace.rettime = cpu_clock(raw_smp_processor_id()); | ||
453 | ftrace_graph_return(&trace); | ||
454 | |||
455 | if (unlikely(!ret)) { | ||
456 | ftrace_graph_stop(); | ||
457 | WARN_ON(1); | ||
458 | /* Might as well panic. What else to do? */ | ||
459 | ret = (unsigned long)panic; | ||
460 | } | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* | 407 | /* |
466 | * Hook the return address and push it in the stack of return addrs | 408 | * Hook the return address and push it in the stack of return addrs |
467 | * in current thread info. | 409 | * in current thread info. |
@@ -469,14 +411,13 @@ unsigned long ftrace_return_to_handler(void) | |||
469 | void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | 411 | void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) |
470 | { | 412 | { |
471 | unsigned long old; | 413 | unsigned long old; |
472 | unsigned long long calltime; | ||
473 | int faulted; | 414 | int faulted; |
474 | struct ftrace_graph_ent trace; | 415 | struct ftrace_graph_ent trace; |
475 | unsigned long return_hooker = (unsigned long) | 416 | unsigned long return_hooker = (unsigned long) |
476 | &return_to_handler; | 417 | &return_to_handler; |
477 | 418 | ||
478 | /* Nmi's are currently unsupported */ | 419 | /* Nmi's are currently unsupported */ |
479 | if (unlikely(atomic_read(&in_nmi))) | 420 | if (unlikely(in_nmi())) |
480 | return; | 421 | return; |
481 | 422 | ||
482 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | 423 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
@@ -512,17 +453,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
512 | return; | 453 | return; |
513 | } | 454 | } |
514 | 455 | ||
515 | if (unlikely(!__kernel_text_address(old))) { | 456 | if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) { |
516 | ftrace_graph_stop(); | ||
517 | *parent = old; | ||
518 | WARN_ON(1); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | calltime = cpu_clock(raw_smp_processor_id()); | ||
523 | |||
524 | if (push_return_trace(old, calltime, | ||
525 | self_addr, &trace.depth) == -EBUSY) { | ||
526 | *parent = old; | 457 | *parent = old; |
527 | return; | 458 | return; |
528 | } | 459 | } |
@@ -536,3 +467,66 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
536 | } | 467 | } |
537 | } | 468 | } |
538 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 469 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
470 | |||
471 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
472 | |||
473 | extern unsigned long __start_syscalls_metadata[]; | ||
474 | extern unsigned long __stop_syscalls_metadata[]; | ||
475 | extern unsigned long *sys_call_table; | ||
476 | |||
477 | static struct syscall_metadata **syscalls_metadata; | ||
478 | |||
479 | static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) | ||
480 | { | ||
481 | struct syscall_metadata *start; | ||
482 | struct syscall_metadata *stop; | ||
483 | char str[KSYM_SYMBOL_LEN]; | ||
484 | |||
485 | |||
486 | start = (struct syscall_metadata *)__start_syscalls_metadata; | ||
487 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | ||
488 | kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str); | ||
489 | |||
490 | for ( ; start < stop; start++) { | ||
491 | if (start->name && !strcmp(start->name, str)) | ||
492 | return start; | ||
493 | } | ||
494 | return NULL; | ||
495 | } | ||
496 | |||
497 | struct syscall_metadata *syscall_nr_to_meta(int nr) | ||
498 | { | ||
499 | if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0) | ||
500 | return NULL; | ||
501 | |||
502 | return syscalls_metadata[nr]; | ||
503 | } | ||
504 | |||
505 | void arch_init_ftrace_syscalls(void) | ||
506 | { | ||
507 | int i; | ||
508 | struct syscall_metadata *meta; | ||
509 | unsigned long **psys_syscall_table = &sys_call_table; | ||
510 | static atomic_t refs; | ||
511 | |||
512 | if (atomic_inc_return(&refs) != 1) | ||
513 | goto end; | ||
514 | |||
515 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * | ||
516 | FTRACE_SYSCALL_MAX, GFP_KERNEL); | ||
517 | if (!syscalls_metadata) { | ||
518 | WARN_ON(1); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { | ||
523 | meta = find_syscall_meta(psys_syscall_table[i]); | ||
524 | syscalls_metadata[i] = meta; | ||
525 | } | ||
526 | return; | ||
527 | |||
528 | /* Paranoid: avoid overflow */ | ||
529 | end: | ||
530 | atomic_dec(&refs); | ||
531 | } | ||
532 | #endif | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index a00545fe5cdd..648b3a2a3a44 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -80,6 +80,7 @@ static inline void hpet_clear_mapping(void) | |||
80 | */ | 80 | */ |
81 | static int boot_hpet_disable; | 81 | static int boot_hpet_disable; |
82 | int hpet_force_user; | 82 | int hpet_force_user; |
83 | static int hpet_verbose; | ||
83 | 84 | ||
84 | static int __init hpet_setup(char *str) | 85 | static int __init hpet_setup(char *str) |
85 | { | 86 | { |
@@ -88,6 +89,8 @@ static int __init hpet_setup(char *str) | |||
88 | boot_hpet_disable = 1; | 89 | boot_hpet_disable = 1; |
89 | if (!strncmp("force", str, 5)) | 90 | if (!strncmp("force", str, 5)) |
90 | hpet_force_user = 1; | 91 | hpet_force_user = 1; |
92 | if (!strncmp("verbose", str, 7)) | ||
93 | hpet_verbose = 1; | ||
91 | } | 94 | } |
92 | return 1; | 95 | return 1; |
93 | } | 96 | } |
@@ -119,6 +122,43 @@ int is_hpet_enabled(void) | |||
119 | } | 122 | } |
120 | EXPORT_SYMBOL_GPL(is_hpet_enabled); | 123 | EXPORT_SYMBOL_GPL(is_hpet_enabled); |
121 | 124 | ||
125 | static void _hpet_print_config(const char *function, int line) | ||
126 | { | ||
127 | u32 i, timers, l, h; | ||
128 | printk(KERN_INFO "hpet: %s(%d):\n", function, line); | ||
129 | l = hpet_readl(HPET_ID); | ||
130 | h = hpet_readl(HPET_PERIOD); | ||
131 | timers = ((l & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1; | ||
132 | printk(KERN_INFO "hpet: ID: 0x%x, PERIOD: 0x%x\n", l, h); | ||
133 | l = hpet_readl(HPET_CFG); | ||
134 | h = hpet_readl(HPET_STATUS); | ||
135 | printk(KERN_INFO "hpet: CFG: 0x%x, STATUS: 0x%x\n", l, h); | ||
136 | l = hpet_readl(HPET_COUNTER); | ||
137 | h = hpet_readl(HPET_COUNTER+4); | ||
138 | printk(KERN_INFO "hpet: COUNTER_l: 0x%x, COUNTER_h: 0x%x\n", l, h); | ||
139 | |||
140 | for (i = 0; i < timers; i++) { | ||
141 | l = hpet_readl(HPET_Tn_CFG(i)); | ||
142 | h = hpet_readl(HPET_Tn_CFG(i)+4); | ||
143 | printk(KERN_INFO "hpet: T%d: CFG_l: 0x%x, CFG_h: 0x%x\n", | ||
144 | i, l, h); | ||
145 | l = hpet_readl(HPET_Tn_CMP(i)); | ||
146 | h = hpet_readl(HPET_Tn_CMP(i)+4); | ||
147 | printk(KERN_INFO "hpet: T%d: CMP_l: 0x%x, CMP_h: 0x%x\n", | ||
148 | i, l, h); | ||
149 | l = hpet_readl(HPET_Tn_ROUTE(i)); | ||
150 | h = hpet_readl(HPET_Tn_ROUTE(i)+4); | ||
151 | printk(KERN_INFO "hpet: T%d ROUTE_l: 0x%x, ROUTE_h: 0x%x\n", | ||
152 | i, l, h); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | #define hpet_print_config() \ | ||
157 | do { \ | ||
158 | if (hpet_verbose) \ | ||
159 | _hpet_print_config(__FUNCTION__, __LINE__); \ | ||
160 | } while (0) | ||
161 | |||
122 | /* | 162 | /* |
123 | * When the hpet driver (/dev/hpet) is enabled, we need to reserve | 163 | * When the hpet driver (/dev/hpet) is enabled, we need to reserve |
124 | * timer 0 and timer 1 in case of RTC emulation. | 164 | * timer 0 and timer 1 in case of RTC emulation. |
@@ -191,27 +231,37 @@ static struct clock_event_device hpet_clockevent = { | |||
191 | .rating = 50, | 231 | .rating = 50, |
192 | }; | 232 | }; |
193 | 233 | ||
194 | static void hpet_start_counter(void) | 234 | static void hpet_stop_counter(void) |
195 | { | 235 | { |
196 | unsigned long cfg = hpet_readl(HPET_CFG); | 236 | unsigned long cfg = hpet_readl(HPET_CFG); |
197 | |||
198 | cfg &= ~HPET_CFG_ENABLE; | 237 | cfg &= ~HPET_CFG_ENABLE; |
199 | hpet_writel(cfg, HPET_CFG); | 238 | hpet_writel(cfg, HPET_CFG); |
200 | hpet_writel(0, HPET_COUNTER); | 239 | hpet_writel(0, HPET_COUNTER); |
201 | hpet_writel(0, HPET_COUNTER + 4); | 240 | hpet_writel(0, HPET_COUNTER + 4); |
241 | } | ||
242 | |||
243 | static void hpet_start_counter(void) | ||
244 | { | ||
245 | unsigned long cfg = hpet_readl(HPET_CFG); | ||
202 | cfg |= HPET_CFG_ENABLE; | 246 | cfg |= HPET_CFG_ENABLE; |
203 | hpet_writel(cfg, HPET_CFG); | 247 | hpet_writel(cfg, HPET_CFG); |
204 | } | 248 | } |
205 | 249 | ||
250 | static void hpet_restart_counter(void) | ||
251 | { | ||
252 | hpet_stop_counter(); | ||
253 | hpet_start_counter(); | ||
254 | } | ||
255 | |||
206 | static void hpet_resume_device(void) | 256 | static void hpet_resume_device(void) |
207 | { | 257 | { |
208 | force_hpet_resume(); | 258 | force_hpet_resume(); |
209 | } | 259 | } |
210 | 260 | ||
211 | static void hpet_restart_counter(void) | 261 | static void hpet_resume_counter(void) |
212 | { | 262 | { |
213 | hpet_resume_device(); | 263 | hpet_resume_device(); |
214 | hpet_start_counter(); | 264 | hpet_restart_counter(); |
215 | } | 265 | } |
216 | 266 | ||
217 | static void hpet_enable_legacy_int(void) | 267 | static void hpet_enable_legacy_int(void) |
@@ -259,29 +309,23 @@ static int hpet_setup_msi_irq(unsigned int irq); | |||
259 | static void hpet_set_mode(enum clock_event_mode mode, | 309 | static void hpet_set_mode(enum clock_event_mode mode, |
260 | struct clock_event_device *evt, int timer) | 310 | struct clock_event_device *evt, int timer) |
261 | { | 311 | { |
262 | unsigned long cfg, cmp, now; | 312 | unsigned long cfg; |
263 | uint64_t delta; | 313 | uint64_t delta; |
264 | 314 | ||
265 | switch (mode) { | 315 | switch (mode) { |
266 | case CLOCK_EVT_MODE_PERIODIC: | 316 | case CLOCK_EVT_MODE_PERIODIC: |
317 | hpet_stop_counter(); | ||
267 | delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult; | 318 | delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult; |
268 | delta >>= evt->shift; | 319 | delta >>= evt->shift; |
269 | now = hpet_readl(HPET_COUNTER); | ||
270 | cmp = now + (unsigned long) delta; | ||
271 | cfg = hpet_readl(HPET_Tn_CFG(timer)); | 320 | cfg = hpet_readl(HPET_Tn_CFG(timer)); |
272 | /* Make sure we use edge triggered interrupts */ | 321 | /* Make sure we use edge triggered interrupts */ |
273 | cfg &= ~HPET_TN_LEVEL; | 322 | cfg &= ~HPET_TN_LEVEL; |
274 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | | 323 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | |
275 | HPET_TN_SETVAL | HPET_TN_32BIT; | 324 | HPET_TN_SETVAL | HPET_TN_32BIT; |
276 | hpet_writel(cfg, HPET_Tn_CFG(timer)); | 325 | hpet_writel(cfg, HPET_Tn_CFG(timer)); |
277 | /* | ||
278 | * The first write after writing TN_SETVAL to the | ||
279 | * config register sets the counter value, the second | ||
280 | * write sets the period. | ||
281 | */ | ||
282 | hpet_writel(cmp, HPET_Tn_CMP(timer)); | ||
283 | udelay(1); | ||
284 | hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer)); | 326 | hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer)); |
327 | hpet_start_counter(); | ||
328 | hpet_print_config(); | ||
285 | break; | 329 | break; |
286 | 330 | ||
287 | case CLOCK_EVT_MODE_ONESHOT: | 331 | case CLOCK_EVT_MODE_ONESHOT: |
@@ -308,6 +352,7 @@ static void hpet_set_mode(enum clock_event_mode mode, | |||
308 | irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu)); | 352 | irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu)); |
309 | enable_irq(hdev->irq); | 353 | enable_irq(hdev->irq); |
310 | } | 354 | } |
355 | hpet_print_config(); | ||
311 | break; | 356 | break; |
312 | } | 357 | } |
313 | } | 358 | } |
@@ -526,6 +571,7 @@ static void hpet_msi_capability_lookup(unsigned int start_timer) | |||
526 | 571 | ||
527 | num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); | 572 | num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); |
528 | num_timers++; /* Value read out starts from 0 */ | 573 | num_timers++; /* Value read out starts from 0 */ |
574 | hpet_print_config(); | ||
529 | 575 | ||
530 | hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL); | 576 | hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL); |
531 | if (!hpet_devs) | 577 | if (!hpet_devs) |
@@ -695,7 +741,7 @@ static struct clocksource clocksource_hpet = { | |||
695 | .mask = HPET_MASK, | 741 | .mask = HPET_MASK, |
696 | .shift = HPET_SHIFT, | 742 | .shift = HPET_SHIFT, |
697 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 743 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
698 | .resume = hpet_restart_counter, | 744 | .resume = hpet_resume_counter, |
699 | #ifdef CONFIG_X86_64 | 745 | #ifdef CONFIG_X86_64 |
700 | .vread = vread_hpet, | 746 | .vread = vread_hpet, |
701 | #endif | 747 | #endif |
@@ -707,7 +753,7 @@ static int hpet_clocksource_register(void) | |||
707 | cycle_t t1; | 753 | cycle_t t1; |
708 | 754 | ||
709 | /* Start the counter */ | 755 | /* Start the counter */ |
710 | hpet_start_counter(); | 756 | hpet_restart_counter(); |
711 | 757 | ||
712 | /* Verify whether hpet counter works */ | 758 | /* Verify whether hpet counter works */ |
713 | t1 = read_hpet(); | 759 | t1 = read_hpet(); |
@@ -793,6 +839,7 @@ int __init hpet_enable(void) | |||
793 | * information and the number of channels | 839 | * information and the number of channels |
794 | */ | 840 | */ |
795 | id = hpet_readl(HPET_ID); | 841 | id = hpet_readl(HPET_ID); |
842 | hpet_print_config(); | ||
796 | 843 | ||
797 | #ifdef CONFIG_HPET_EMULATE_RTC | 844 | #ifdef CONFIG_HPET_EMULATE_RTC |
798 | /* | 845 | /* |
@@ -845,6 +892,7 @@ static __init int hpet_late_init(void) | |||
845 | return -ENODEV; | 892 | return -ENODEV; |
846 | 893 | ||
847 | hpet_reserve_platform_timers(hpet_readl(HPET_ID)); | 894 | hpet_reserve_platform_timers(hpet_readl(HPET_ID)); |
895 | hpet_print_config(); | ||
848 | 896 | ||
849 | for_each_online_cpu(cpu) { | 897 | for_each_online_cpu(cpu) { |
850 | hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu); | 898 | hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu); |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index b8ac3b6cf776..c3fe010d74c8 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -58,9 +58,14 @@ static int show_other_interrupts(struct seq_file *p, int prec) | |||
58 | for_each_online_cpu(j) | 58 | for_each_online_cpu(j) |
59 | seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); | 59 | seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); |
60 | seq_printf(p, " Local timer interrupts\n"); | 60 | seq_printf(p, " Local timer interrupts\n"); |
61 | |||
62 | seq_printf(p, "%*s: ", prec, "SPU"); | ||
63 | for_each_online_cpu(j) | ||
64 | seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); | ||
65 | seq_printf(p, " Spurious interrupts\n"); | ||
61 | #endif | 66 | #endif |
62 | if (generic_interrupt_extension) { | 67 | if (generic_interrupt_extension) { |
63 | seq_printf(p, "PLT: "); | 68 | seq_printf(p, "%*s: ", prec, "PLT"); |
64 | for_each_online_cpu(j) | 69 | for_each_online_cpu(j) |
65 | seq_printf(p, "%10u ", irq_stats(j)->generic_irqs); | 70 | seq_printf(p, "%10u ", irq_stats(j)->generic_irqs); |
66 | seq_printf(p, " Platform interrupts\n"); | 71 | seq_printf(p, " Platform interrupts\n"); |
@@ -91,12 +96,6 @@ static int show_other_interrupts(struct seq_file *p, int prec) | |||
91 | seq_printf(p, " Threshold APIC interrupts\n"); | 96 | seq_printf(p, " Threshold APIC interrupts\n"); |
92 | # endif | 97 | # endif |
93 | #endif | 98 | #endif |
94 | #ifdef CONFIG_X86_LOCAL_APIC | ||
95 | seq_printf(p, "%*s: ", prec, "SPU"); | ||
96 | for_each_online_cpu(j) | ||
97 | seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); | ||
98 | seq_printf(p, " Spurious interrupts\n"); | ||
99 | #endif | ||
100 | seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); | 99 | seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); |
101 | #if defined(CONFIG_X86_IO_APIC) | 100 | #if defined(CONFIG_X86_IO_APIC) |
102 | seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); | 101 | seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); |
@@ -133,23 +132,15 @@ int show_interrupts(struct seq_file *p, void *v) | |||
133 | return 0; | 132 | return 0; |
134 | 133 | ||
135 | spin_lock_irqsave(&desc->lock, flags); | 134 | spin_lock_irqsave(&desc->lock, flags); |
136 | #ifndef CONFIG_SMP | ||
137 | any_count = kstat_irqs(i); | ||
138 | #else | ||
139 | for_each_online_cpu(j) | 135 | for_each_online_cpu(j) |
140 | any_count |= kstat_irqs_cpu(i, j); | 136 | any_count |= kstat_irqs_cpu(i, j); |
141 | #endif | ||
142 | action = desc->action; | 137 | action = desc->action; |
143 | if (!action && !any_count) | 138 | if (!action && !any_count) |
144 | goto out; | 139 | goto out; |
145 | 140 | ||
146 | seq_printf(p, "%*d: ", prec, i); | 141 | seq_printf(p, "%*d: ", prec, i); |
147 | #ifndef CONFIG_SMP | ||
148 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
149 | #else | ||
150 | for_each_online_cpu(j) | 142 | for_each_online_cpu(j) |
151 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | 143 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
152 | #endif | ||
153 | seq_printf(p, " %8s", desc->chip->name); | 144 | seq_printf(p, " %8s", desc->chip->name); |
154 | seq_printf(p, "-%-8s", desc->name); | 145 | seq_printf(p, "-%-8s", desc->name); |
155 | 146 | ||
@@ -174,6 +165,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) | |||
174 | 165 | ||
175 | #ifdef CONFIG_X86_LOCAL_APIC | 166 | #ifdef CONFIG_X86_LOCAL_APIC |
176 | sum += irq_stats(cpu)->apic_timer_irqs; | 167 | sum += irq_stats(cpu)->apic_timer_irqs; |
168 | sum += irq_stats(cpu)->irq_spurious_count; | ||
177 | #endif | 169 | #endif |
178 | if (generic_interrupt_extension) | 170 | if (generic_interrupt_extension) |
179 | sum += irq_stats(cpu)->generic_irqs; | 171 | sum += irq_stats(cpu)->generic_irqs; |
@@ -188,9 +180,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu) | |||
188 | sum += irq_stats(cpu)->irq_threshold_count; | 180 | sum += irq_stats(cpu)->irq_threshold_count; |
189 | #endif | 181 | #endif |
190 | #endif | 182 | #endif |
191 | #ifdef CONFIG_X86_LOCAL_APIC | ||
192 | sum += irq_stats(cpu)->irq_spurious_count; | ||
193 | #endif | ||
194 | return sum; | 183 | return sum; |
195 | } | 184 | } |
196 | 185 | ||
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index bc1326105448..368b0a8836f9 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
@@ -50,7 +50,6 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) | |||
50 | */ | 50 | */ |
51 | static struct irqaction fpu_irq = { | 51 | static struct irqaction fpu_irq = { |
52 | .handler = math_error_irq, | 52 | .handler = math_error_irq, |
53 | .mask = CPU_MASK_NONE, | ||
54 | .name = "fpu", | 53 | .name = "fpu", |
55 | }; | 54 | }; |
56 | 55 | ||
@@ -83,7 +82,6 @@ void __init init_ISA_irqs(void) | |||
83 | */ | 82 | */ |
84 | static struct irqaction irq2 = { | 83 | static struct irqaction irq2 = { |
85 | .handler = no_action, | 84 | .handler = no_action, |
86 | .mask = CPU_MASK_NONE, | ||
87 | .name = "cascade", | 85 | .name = "cascade", |
88 | }; | 86 | }; |
89 | 87 | ||
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index c7a49e0ffbfb..8cd10537fd46 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c | |||
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | static struct irqaction irq2 = { | 46 | static struct irqaction irq2 = { |
47 | .handler = no_action, | 47 | .handler = no_action, |
48 | .mask = CPU_MASK_NONE, | ||
49 | .name = "cascade", | 48 | .name = "cascade", |
50 | }; | 49 | }; |
51 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 50 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 55b94614e348..7b5169d2b000 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -638,13 +638,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
638 | #else | 638 | #else |
639 | " pushf\n" | 639 | " pushf\n" |
640 | /* | 640 | /* |
641 | * Skip cs, ip, orig_ax. | 641 | * Skip cs, ip, orig_ax and gs. |
642 | * trampoline_handler() will plug in these values | 642 | * trampoline_handler() will plug in these values |
643 | */ | 643 | */ |
644 | " subl $12, %esp\n" | 644 | " subl $16, %esp\n" |
645 | " pushl %fs\n" | 645 | " pushl %fs\n" |
646 | " pushl %ds\n" | ||
647 | " pushl %es\n" | 646 | " pushl %es\n" |
647 | " pushl %ds\n" | ||
648 | " pushl %eax\n" | 648 | " pushl %eax\n" |
649 | " pushl %ebp\n" | 649 | " pushl %ebp\n" |
650 | " pushl %edi\n" | 650 | " pushl %edi\n" |
@@ -655,10 +655,10 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
655 | " movl %esp, %eax\n" | 655 | " movl %esp, %eax\n" |
656 | " call trampoline_handler\n" | 656 | " call trampoline_handler\n" |
657 | /* Move flags to cs */ | 657 | /* Move flags to cs */ |
658 | " movl 52(%esp), %edx\n" | 658 | " movl 56(%esp), %edx\n" |
659 | " movl %edx, 48(%esp)\n" | 659 | " movl %edx, 52(%esp)\n" |
660 | /* Replace saved flags with true return address. */ | 660 | /* Replace saved flags with true return address. */ |
661 | " movl %eax, 52(%esp)\n" | 661 | " movl %eax, 56(%esp)\n" |
662 | " popl %ebx\n" | 662 | " popl %ebx\n" |
663 | " popl %ecx\n" | 663 | " popl %ecx\n" |
664 | " popl %edx\n" | 664 | " popl %edx\n" |
@@ -666,8 +666,8 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
666 | " popl %edi\n" | 666 | " popl %edi\n" |
667 | " popl %ebp\n" | 667 | " popl %ebp\n" |
668 | " popl %eax\n" | 668 | " popl %eax\n" |
669 | /* Skip ip, orig_ax, es, ds, fs */ | 669 | /* Skip ds, es, fs, gs, orig_ax and ip */ |
670 | " addl $20, %esp\n" | 670 | " addl $24, %esp\n" |
671 | " popf\n" | 671 | " popf\n" |
672 | #endif | 672 | #endif |
673 | " ret\n"); | 673 | " ret\n"); |
@@ -691,6 +691,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
691 | regs->cs = __KERNEL_CS; | 691 | regs->cs = __KERNEL_CS; |
692 | #else | 692 | #else |
693 | regs->cs = __KERNEL_CS | get_kernel_rpl(); | 693 | regs->cs = __KERNEL_CS | get_kernel_rpl(); |
694 | regs->gs = 0; | ||
694 | #endif | 695 | #endif |
695 | regs->ip = trampoline_address; | 696 | regs->ip = trampoline_address; |
696 | regs->orig_ax = ~0UL; | 697 | regs->orig_ax = ~0UL; |
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index 8815f3c7fec7..846510b78a09 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c | |||
@@ -348,7 +348,6 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) | |||
348 | static struct irqaction mfgptirq = { | 348 | static struct irqaction mfgptirq = { |
349 | .handler = mfgpt_tick, | 349 | .handler = mfgpt_tick, |
350 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, | 350 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, |
351 | .mask = CPU_MASK_NONE, | ||
352 | .name = "mfgpt-timer" | 351 | .name = "mfgpt-timer" |
353 | }; | 352 | }; |
354 | 353 | ||
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index c25fdb382292..453b5795a5c6 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -12,31 +12,30 @@ | |||
12 | * | 12 | * |
13 | * Licensed under the terms of the GNU General Public | 13 | * Licensed under the terms of the GNU General Public |
14 | * License version 2. See file COPYING for details. | 14 | * License version 2. See file COPYING for details. |
15 | */ | 15 | */ |
16 | 16 | #include <linux/platform_device.h> | |
17 | #include <linux/capability.h> | 17 | #include <linux/capability.h> |
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/cpumask.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/vmalloc.h> | ||
25 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
19 | #include <linux/firmware.h> | ||
26 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
27 | #include <linux/mm.h> | 21 | #include <linux/cpumask.h> |
28 | #include <linux/fs.h> | 22 | #include <linux/pci_ids.h> |
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/vmalloc.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
29 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/sched.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/slab.h> | ||
30 | #include <linux/cpu.h> | 31 | #include <linux/cpu.h> |
31 | #include <linux/firmware.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
34 | #include <linux/pci_ids.h> | 33 | #include <linux/fs.h> |
35 | #include <linux/uaccess.h> | 34 | #include <linux/mm.h> |
36 | 35 | ||
37 | #include <asm/msr.h> | ||
38 | #include <asm/processor.h> | ||
39 | #include <asm/microcode.h> | 36 | #include <asm/microcode.h> |
37 | #include <asm/processor.h> | ||
38 | #include <asm/msr.h> | ||
40 | 39 | ||
41 | MODULE_DESCRIPTION("AMD Microcode Update Driver"); | 40 | MODULE_DESCRIPTION("AMD Microcode Update Driver"); |
42 | MODULE_AUTHOR("Peter Oruba"); | 41 | MODULE_AUTHOR("Peter Oruba"); |
@@ -72,8 +71,8 @@ struct microcode_header_amd { | |||
72 | } __attribute__((packed)); | 71 | } __attribute__((packed)); |
73 | 72 | ||
74 | struct microcode_amd { | 73 | struct microcode_amd { |
75 | struct microcode_header_amd hdr; | 74 | struct microcode_header_amd hdr; |
76 | unsigned int mpb[0]; | 75 | unsigned int mpb[0]; |
77 | }; | 76 | }; |
78 | 77 | ||
79 | #define UCODE_MAX_SIZE 2048 | 78 | #define UCODE_MAX_SIZE 2048 |
@@ -184,8 +183,8 @@ static int get_ucode_data(void *to, const u8 *from, size_t n) | |||
184 | return 0; | 183 | return 0; |
185 | } | 184 | } |
186 | 185 | ||
187 | static void *get_next_ucode(const u8 *buf, unsigned int size, | 186 | static void * |
188 | unsigned int *mc_size) | 187 | get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) |
189 | { | 188 | { |
190 | unsigned int total_size; | 189 | unsigned int total_size; |
191 | u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; | 190 | u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; |
@@ -223,7 +222,6 @@ static void *get_next_ucode(const u8 *buf, unsigned int size, | |||
223 | return mc; | 222 | return mc; |
224 | } | 223 | } |
225 | 224 | ||
226 | |||
227 | static int install_equiv_cpu_table(const u8 *buf) | 225 | static int install_equiv_cpu_table(const u8 *buf) |
228 | { | 226 | { |
229 | u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE]; | 227 | u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE]; |
@@ -372,4 +370,3 @@ struct microcode_ops * __init init_amd_microcode(void) | |||
372 | { | 370 | { |
373 | return µcode_amd_ops; | 371 | return µcode_amd_ops; |
374 | } | 372 | } |
375 | |||
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index c9b721ba968c..98c470c069d1 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -70,41 +70,41 @@ | |||
70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
72 | */ | 72 | */ |
73 | #include <linux/platform_device.h> | ||
73 | #include <linux/capability.h> | 74 | #include <linux/capability.h> |
74 | #include <linux/kernel.h> | 75 | #include <linux/miscdevice.h> |
75 | #include <linux/init.h> | 76 | #include <linux/firmware.h> |
76 | #include <linux/sched.h> | ||
77 | #include <linux/smp_lock.h> | 77 | #include <linux/smp_lock.h> |
78 | #include <linux/spinlock.h> | ||
78 | #include <linux/cpumask.h> | 79 | #include <linux/cpumask.h> |
79 | #include <linux/module.h> | 80 | #include <linux/uaccess.h> |
80 | #include <linux/slab.h> | ||
81 | #include <linux/vmalloc.h> | 81 | #include <linux/vmalloc.h> |
82 | #include <linux/miscdevice.h> | 82 | #include <linux/kernel.h> |
83 | #include <linux/spinlock.h> | 83 | #include <linux/module.h> |
84 | #include <linux/mm.h> | ||
85 | #include <linux/fs.h> | ||
86 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
85 | #include <linux/sched.h> | ||
86 | #include <linux/init.h> | ||
87 | #include <linux/slab.h> | ||
87 | #include <linux/cpu.h> | 88 | #include <linux/cpu.h> |
88 | #include <linux/firmware.h> | 89 | #include <linux/fs.h> |
89 | #include <linux/platform_device.h> | 90 | #include <linux/mm.h> |
90 | 91 | ||
91 | #include <asm/msr.h> | ||
92 | #include <asm/uaccess.h> | ||
93 | #include <asm/processor.h> | ||
94 | #include <asm/microcode.h> | 92 | #include <asm/microcode.h> |
93 | #include <asm/processor.h> | ||
94 | #include <asm/msr.h> | ||
95 | 95 | ||
96 | MODULE_DESCRIPTION("Microcode Update Driver"); | 96 | MODULE_DESCRIPTION("Microcode Update Driver"); |
97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | 97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); |
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
99 | 99 | ||
100 | #define MICROCODE_VERSION "2.00" | 100 | #define MICROCODE_VERSION "2.00" |
101 | 101 | ||
102 | static struct microcode_ops *microcode_ops; | 102 | static struct microcode_ops *microcode_ops; |
103 | 103 | ||
104 | /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ | 104 | /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ |
105 | static DEFINE_MUTEX(microcode_mutex); | 105 | static DEFINE_MUTEX(microcode_mutex); |
106 | 106 | ||
107 | struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; | 107 | struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; |
108 | EXPORT_SYMBOL_GPL(ucode_cpu_info); | 108 | EXPORT_SYMBOL_GPL(ucode_cpu_info); |
109 | 109 | ||
110 | #ifdef CONFIG_MICROCODE_OLD_INTERFACE | 110 | #ifdef CONFIG_MICROCODE_OLD_INTERFACE |
@@ -198,18 +198,33 @@ static void microcode_dev_exit(void) | |||
198 | 198 | ||
199 | MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); | 199 | MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); |
200 | #else | 200 | #else |
201 | #define microcode_dev_init() 0 | 201 | #define microcode_dev_init() 0 |
202 | #define microcode_dev_exit() do { } while (0) | 202 | #define microcode_dev_exit() do { } while (0) |
203 | #endif | 203 | #endif |
204 | 204 | ||
205 | /* fake device for request_firmware */ | 205 | /* fake device for request_firmware */ |
206 | static struct platform_device *microcode_pdev; | 206 | static struct platform_device *microcode_pdev; |
207 | |||
208 | static long reload_for_cpu(void *unused) | ||
209 | { | ||
210 | struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id(); | ||
211 | int err = 0; | ||
212 | |||
213 | mutex_lock(µcode_mutex); | ||
214 | if (uci->valid) { | ||
215 | err = microcode_ops->request_microcode_fw(smp_processor_id(), | ||
216 | µcode_pdev->dev); | ||
217 | if (!err) | ||
218 | microcode_ops->apply_microcode(smp_processor_id()); | ||
219 | } | ||
220 | mutex_unlock(µcode_mutex); | ||
221 | return err; | ||
222 | } | ||
207 | 223 | ||
208 | static ssize_t reload_store(struct sys_device *dev, | 224 | static ssize_t reload_store(struct sys_device *dev, |
209 | struct sysdev_attribute *attr, | 225 | struct sysdev_attribute *attr, |
210 | const char *buf, size_t sz) | 226 | const char *buf, size_t sz) |
211 | { | 227 | { |
212 | struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; | ||
213 | char *end; | 228 | char *end; |
214 | unsigned long val = simple_strtoul(buf, &end, 0); | 229 | unsigned long val = simple_strtoul(buf, &end, 0); |
215 | int err = 0; | 230 | int err = 0; |
@@ -218,21 +233,9 @@ static ssize_t reload_store(struct sys_device *dev, | |||
218 | if (end == buf) | 233 | if (end == buf) |
219 | return -EINVAL; | 234 | return -EINVAL; |
220 | if (val == 1) { | 235 | if (val == 1) { |
221 | cpumask_t old = current->cpus_allowed; | ||
222 | |||
223 | get_online_cpus(); | 236 | get_online_cpus(); |
224 | if (cpu_online(cpu)) { | 237 | if (cpu_online(cpu)) |
225 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); | 238 | err = work_on_cpu(cpu, reload_for_cpu, NULL); |
226 | mutex_lock(µcode_mutex); | ||
227 | if (uci->valid) { | ||
228 | err = microcode_ops->request_microcode_fw(cpu, | ||
229 | µcode_pdev->dev); | ||
230 | if (!err) | ||
231 | microcode_ops->apply_microcode(cpu); | ||
232 | } | ||
233 | mutex_unlock(µcode_mutex); | ||
234 | set_cpus_allowed_ptr(current, &old); | ||
235 | } | ||
236 | put_online_cpus(); | 239 | put_online_cpus(); |
237 | } | 240 | } |
238 | if (err) | 241 | if (err) |
@@ -268,8 +271,8 @@ static struct attribute *mc_default_attrs[] = { | |||
268 | }; | 271 | }; |
269 | 272 | ||
270 | static struct attribute_group mc_attr_group = { | 273 | static struct attribute_group mc_attr_group = { |
271 | .attrs = mc_default_attrs, | 274 | .attrs = mc_default_attrs, |
272 | .name = "microcode", | 275 | .name = "microcode", |
273 | }; | 276 | }; |
274 | 277 | ||
275 | static void __microcode_fini_cpu(int cpu) | 278 | static void __microcode_fini_cpu(int cpu) |
@@ -328,9 +331,9 @@ static int microcode_resume_cpu(int cpu) | |||
328 | return 0; | 331 | return 0; |
329 | } | 332 | } |
330 | 333 | ||
331 | static void microcode_update_cpu(int cpu) | 334 | static long microcode_update_cpu(void *unused) |
332 | { | 335 | { |
333 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 336 | struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id(); |
334 | int err = 0; | 337 | int err = 0; |
335 | 338 | ||
336 | /* | 339 | /* |
@@ -338,30 +341,27 @@ static void microcode_update_cpu(int cpu) | |||
338 | * otherwise just request a firmware: | 341 | * otherwise just request a firmware: |
339 | */ | 342 | */ |
340 | if (uci->valid) { | 343 | if (uci->valid) { |
341 | err = microcode_resume_cpu(cpu); | 344 | err = microcode_resume_cpu(smp_processor_id()); |
342 | } else { | 345 | } else { |
343 | collect_cpu_info(cpu); | 346 | collect_cpu_info(smp_processor_id()); |
344 | if (uci->valid && system_state == SYSTEM_RUNNING) | 347 | if (uci->valid && system_state == SYSTEM_RUNNING) |
345 | err = microcode_ops->request_microcode_fw(cpu, | 348 | err = microcode_ops->request_microcode_fw( |
349 | smp_processor_id(), | ||
346 | µcode_pdev->dev); | 350 | µcode_pdev->dev); |
347 | } | 351 | } |
348 | if (!err) | 352 | if (!err) |
349 | microcode_ops->apply_microcode(cpu); | 353 | microcode_ops->apply_microcode(smp_processor_id()); |
354 | return err; | ||
350 | } | 355 | } |
351 | 356 | ||
352 | static void microcode_init_cpu(int cpu) | 357 | static int microcode_init_cpu(int cpu) |
353 | { | 358 | { |
354 | cpumask_t old = current->cpus_allowed; | 359 | int err; |
355 | |||
356 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); | ||
357 | /* We should bind the task to the CPU */ | ||
358 | BUG_ON(raw_smp_processor_id() != cpu); | ||
359 | |||
360 | mutex_lock(µcode_mutex); | 360 | mutex_lock(µcode_mutex); |
361 | microcode_update_cpu(cpu); | 361 | err = work_on_cpu(cpu, microcode_update_cpu, NULL); |
362 | mutex_unlock(µcode_mutex); | 362 | mutex_unlock(µcode_mutex); |
363 | 363 | ||
364 | set_cpus_allowed_ptr(current, &old); | 364 | return err; |
365 | } | 365 | } |
366 | 366 | ||
367 | static int mc_sysdev_add(struct sys_device *sys_dev) | 367 | static int mc_sysdev_add(struct sys_device *sys_dev) |
@@ -379,8 +379,9 @@ static int mc_sysdev_add(struct sys_device *sys_dev) | |||
379 | if (err) | 379 | if (err) |
380 | return err; | 380 | return err; |
381 | 381 | ||
382 | microcode_init_cpu(cpu); | 382 | err = microcode_init_cpu(cpu); |
383 | return 0; | 383 | |
384 | return err; | ||
384 | } | 385 | } |
385 | 386 | ||
386 | static int mc_sysdev_remove(struct sys_device *sys_dev) | 387 | static int mc_sysdev_remove(struct sys_device *sys_dev) |
@@ -404,14 +405,14 @@ static int mc_sysdev_resume(struct sys_device *dev) | |||
404 | return 0; | 405 | return 0; |
405 | 406 | ||
406 | /* only CPU 0 will apply ucode here */ | 407 | /* only CPU 0 will apply ucode here */ |
407 | microcode_update_cpu(0); | 408 | microcode_update_cpu(NULL); |
408 | return 0; | 409 | return 0; |
409 | } | 410 | } |
410 | 411 | ||
411 | static struct sysdev_driver mc_sysdev_driver = { | 412 | static struct sysdev_driver mc_sysdev_driver = { |
412 | .add = mc_sysdev_add, | 413 | .add = mc_sysdev_add, |
413 | .remove = mc_sysdev_remove, | 414 | .remove = mc_sysdev_remove, |
414 | .resume = mc_sysdev_resume, | 415 | .resume = mc_sysdev_resume, |
415 | }; | 416 | }; |
416 | 417 | ||
417 | static __cpuinit int | 418 | static __cpuinit int |
@@ -424,7 +425,9 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
424 | switch (action) { | 425 | switch (action) { |
425 | case CPU_ONLINE: | 426 | case CPU_ONLINE: |
426 | case CPU_ONLINE_FROZEN: | 427 | case CPU_ONLINE_FROZEN: |
427 | microcode_init_cpu(cpu); | 428 | if (microcode_init_cpu(cpu)) |
429 | printk(KERN_ERR "microcode: failed to init CPU%d\n", | ||
430 | cpu); | ||
428 | case CPU_DOWN_FAILED: | 431 | case CPU_DOWN_FAILED: |
429 | case CPU_DOWN_FAILED_FROZEN: | 432 | case CPU_DOWN_FAILED_FROZEN: |
430 | pr_debug("microcode: CPU%d added\n", cpu); | 433 | pr_debug("microcode: CPU%d added\n", cpu); |
@@ -448,7 +451,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
448 | } | 451 | } |
449 | 452 | ||
450 | static struct notifier_block __refdata mc_cpu_notifier = { | 453 | static struct notifier_block __refdata mc_cpu_notifier = { |
451 | .notifier_call = mc_cpu_callback, | 454 | .notifier_call = mc_cpu_callback, |
452 | }; | 455 | }; |
453 | 456 | ||
454 | static int __init microcode_init(void) | 457 | static int __init microcode_init(void) |
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 5e9f4fc51385..149b9ec7c1ab 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
@@ -70,28 +70,28 @@ | |||
70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
72 | */ | 72 | */ |
73 | #include <linux/platform_device.h> | ||
73 | #include <linux/capability.h> | 74 | #include <linux/capability.h> |
74 | #include <linux/kernel.h> | 75 | #include <linux/miscdevice.h> |
75 | #include <linux/init.h> | 76 | #include <linux/firmware.h> |
76 | #include <linux/sched.h> | ||
77 | #include <linux/smp_lock.h> | 77 | #include <linux/smp_lock.h> |
78 | #include <linux/spinlock.h> | ||
78 | #include <linux/cpumask.h> | 79 | #include <linux/cpumask.h> |
79 | #include <linux/module.h> | 80 | #include <linux/uaccess.h> |
80 | #include <linux/slab.h> | ||
81 | #include <linux/vmalloc.h> | 81 | #include <linux/vmalloc.h> |
82 | #include <linux/miscdevice.h> | 82 | #include <linux/kernel.h> |
83 | #include <linux/spinlock.h> | 83 | #include <linux/module.h> |
84 | #include <linux/mm.h> | ||
85 | #include <linux/fs.h> | ||
86 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
85 | #include <linux/sched.h> | ||
86 | #include <linux/init.h> | ||
87 | #include <linux/slab.h> | ||
87 | #include <linux/cpu.h> | 88 | #include <linux/cpu.h> |
88 | #include <linux/firmware.h> | 89 | #include <linux/fs.h> |
89 | #include <linux/platform_device.h> | 90 | #include <linux/mm.h> |
90 | #include <linux/uaccess.h> | ||
91 | 91 | ||
92 | #include <asm/msr.h> | ||
93 | #include <asm/processor.h> | ||
94 | #include <asm/microcode.h> | 92 | #include <asm/microcode.h> |
93 | #include <asm/processor.h> | ||
94 | #include <asm/msr.h> | ||
95 | 95 | ||
96 | MODULE_DESCRIPTION("Microcode Update Driver"); | 96 | MODULE_DESCRIPTION("Microcode Update Driver"); |
97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | 97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); |
@@ -129,12 +129,13 @@ struct extended_sigtable { | |||
129 | struct extended_signature sigs[0]; | 129 | struct extended_signature sigs[0]; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #define DEFAULT_UCODE_DATASIZE (2000) | 132 | #define DEFAULT_UCODE_DATASIZE (2000) |
133 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) | 133 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) |
134 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) | 134 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) |
135 | #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) | 135 | #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) |
136 | #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) | 136 | #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) |
137 | #define DWSIZE (sizeof(u32)) | 137 | #define DWSIZE (sizeof(u32)) |
138 | |||
138 | #define get_totalsize(mc) \ | 139 | #define get_totalsize(mc) \ |
139 | (((struct microcode_intel *)mc)->hdr.totalsize ? \ | 140 | (((struct microcode_intel *)mc)->hdr.totalsize ? \ |
140 | ((struct microcode_intel *)mc)->hdr.totalsize : \ | 141 | ((struct microcode_intel *)mc)->hdr.totalsize : \ |
@@ -197,30 +198,31 @@ static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf) | |||
197 | } | 198 | } |
198 | 199 | ||
199 | static inline int | 200 | static inline int |
200 | update_match_revision(struct microcode_header_intel *mc_header, int rev) | 201 | update_match_revision(struct microcode_header_intel *mc_header, int rev) |
201 | { | 202 | { |
202 | return (mc_header->rev <= rev) ? 0 : 1; | 203 | return (mc_header->rev <= rev) ? 0 : 1; |
203 | } | 204 | } |
204 | 205 | ||
205 | static int microcode_sanity_check(void *mc) | 206 | static int microcode_sanity_check(void *mc) |
206 | { | 207 | { |
208 | unsigned long total_size, data_size, ext_table_size; | ||
207 | struct microcode_header_intel *mc_header = mc; | 209 | struct microcode_header_intel *mc_header = mc; |
208 | struct extended_sigtable *ext_header = NULL; | 210 | struct extended_sigtable *ext_header = NULL; |
209 | struct extended_signature *ext_sig; | ||
210 | unsigned long total_size, data_size, ext_table_size; | ||
211 | int sum, orig_sum, ext_sigcount = 0, i; | 211 | int sum, orig_sum, ext_sigcount = 0, i; |
212 | struct extended_signature *ext_sig; | ||
212 | 213 | ||
213 | total_size = get_totalsize(mc_header); | 214 | total_size = get_totalsize(mc_header); |
214 | data_size = get_datasize(mc_header); | 215 | data_size = get_datasize(mc_header); |
216 | |||
215 | if (data_size + MC_HEADER_SIZE > total_size) { | 217 | if (data_size + MC_HEADER_SIZE > total_size) { |
216 | printk(KERN_ERR "microcode: error! " | 218 | printk(KERN_ERR "microcode: error! " |
217 | "Bad data size in microcode data file\n"); | 219 | "Bad data size in microcode data file\n"); |
218 | return -EINVAL; | 220 | return -EINVAL; |
219 | } | 221 | } |
220 | 222 | ||
221 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { | 223 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { |
222 | printk(KERN_ERR "microcode: error! " | 224 | printk(KERN_ERR "microcode: error! " |
223 | "Unknown microcode update format\n"); | 225 | "Unknown microcode update format\n"); |
224 | return -EINVAL; | 226 | return -EINVAL; |
225 | } | 227 | } |
226 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); | 228 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); |
@@ -318,11 +320,15 @@ get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev) | |||
318 | 320 | ||
319 | static void apply_microcode(int cpu) | 321 | static void apply_microcode(int cpu) |
320 | { | 322 | { |
323 | struct microcode_intel *mc_intel; | ||
324 | struct ucode_cpu_info *uci; | ||
321 | unsigned long flags; | 325 | unsigned long flags; |
322 | unsigned int val[2]; | 326 | unsigned int val[2]; |
323 | int cpu_num = raw_smp_processor_id(); | 327 | int cpu_num; |
324 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 328 | |
325 | struct microcode_intel *mc_intel = uci->mc; | 329 | cpu_num = raw_smp_processor_id(); |
330 | uci = ucode_cpu_info + cpu; | ||
331 | mc_intel = uci->mc; | ||
326 | 332 | ||
327 | /* We should bind the task to the CPU */ | 333 | /* We should bind the task to the CPU */ |
328 | BUG_ON(cpu_num != cpu); | 334 | BUG_ON(cpu_num != cpu); |
@@ -348,15 +354,17 @@ static void apply_microcode(int cpu) | |||
348 | spin_unlock_irqrestore(µcode_update_lock, flags); | 354 | spin_unlock_irqrestore(µcode_update_lock, flags); |
349 | if (val[1] != mc_intel->hdr.rev) { | 355 | if (val[1] != mc_intel->hdr.rev) { |
350 | printk(KERN_ERR "microcode: CPU%d update from revision " | 356 | printk(KERN_ERR "microcode: CPU%d update from revision " |
351 | "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); | 357 | "0x%x to 0x%x failed\n", |
358 | cpu_num, uci->cpu_sig.rev, val[1]); | ||
352 | return; | 359 | return; |
353 | } | 360 | } |
354 | printk(KERN_INFO "microcode: CPU%d updated from revision " | 361 | printk(KERN_INFO "microcode: CPU%d updated from revision " |
355 | "0x%x to 0x%x, date = %04x-%02x-%02x \n", | 362 | "0x%x to 0x%x, date = %04x-%02x-%02x \n", |
356 | cpu_num, uci->cpu_sig.rev, val[1], | 363 | cpu_num, uci->cpu_sig.rev, val[1], |
357 | mc_intel->hdr.date & 0xffff, | 364 | mc_intel->hdr.date & 0xffff, |
358 | mc_intel->hdr.date >> 24, | 365 | mc_intel->hdr.date >> 24, |
359 | (mc_intel->hdr.date >> 16) & 0xff); | 366 | (mc_intel->hdr.date >> 16) & 0xff); |
367 | |||
360 | uci->cpu_sig.rev = val[1]; | 368 | uci->cpu_sig.rev = val[1]; |
361 | } | 369 | } |
362 | 370 | ||
@@ -404,18 +412,23 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
404 | leftover -= mc_size; | 412 | leftover -= mc_size; |
405 | } | 413 | } |
406 | 414 | ||
407 | if (new_mc) { | 415 | if (!new_mc) |
408 | if (!leftover) { | 416 | goto out; |
409 | if (uci->mc) | 417 | |
410 | vfree(uci->mc); | 418 | if (leftover) { |
411 | uci->mc = (struct microcode_intel *)new_mc; | 419 | vfree(new_mc); |
412 | pr_debug("microcode: CPU%d found a matching microcode update with" | 420 | goto out; |
413 | " version 0x%x (current=0x%x)\n", | ||
414 | cpu, new_rev, uci->cpu_sig.rev); | ||
415 | } else | ||
416 | vfree(new_mc); | ||
417 | } | 421 | } |
418 | 422 | ||
423 | if (uci->mc) | ||
424 | vfree(uci->mc); | ||
425 | uci->mc = (struct microcode_intel *)new_mc; | ||
426 | |||
427 | pr_debug("microcode: CPU%d found a matching microcode update with" | ||
428 | " version 0x%x (current=0x%x)\n", | ||
429 | cpu, new_rev, uci->cpu_sig.rev); | ||
430 | |||
431 | out: | ||
419 | return (int)leftover; | 432 | return (int)leftover; |
420 | } | 433 | } |
421 | 434 | ||
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index dce99dca6cf8..70fd7e414c15 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -679,7 +679,7 @@ void __init get_smp_config(void) | |||
679 | __get_smp_config(0); | 679 | __get_smp_config(0); |
680 | } | 680 | } |
681 | 681 | ||
682 | static void smp_reserve_bootmem(struct mpf_intel *mpf) | 682 | static void __init smp_reserve_bootmem(struct mpf_intel *mpf) |
683 | { | 683 | { |
684 | unsigned long size = get_mpc_size(mpf->physptr); | 684 | unsigned long size = get_mpc_size(mpf->physptr); |
685 | #ifdef CONFIG_X86_32 | 685 | #ifdef CONFIG_X86_32 |
@@ -838,7 +838,7 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) | |||
838 | 838 | ||
839 | static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; | 839 | static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; |
840 | 840 | ||
841 | static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) | 841 | static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) |
842 | { | 842 | { |
843 | int i; | 843 | int i; |
844 | 844 | ||
@@ -866,7 +866,8 @@ static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) | |||
866 | } | 866 | } |
867 | } | 867 | } |
868 | #else /* CONFIG_X86_IO_APIC */ | 868 | #else /* CONFIG_X86_IO_APIC */ |
869 | static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | 869 | static |
870 | inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | ||
870 | #endif /* CONFIG_X86_IO_APIC */ | 871 | #endif /* CONFIG_X86_IO_APIC */ |
871 | 872 | ||
872 | static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, | 873 | static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index d28bbdc35e4e..755c21e906f3 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -380,8 +380,9 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) | |||
380 | return tbl; | 380 | return tbl; |
381 | } | 381 | } |
382 | 382 | ||
383 | static void calgary_unmap_sg(struct device *dev, | 383 | static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, |
384 | struct scatterlist *sglist, int nelems, int direction) | 384 | int nelems,enum dma_data_direction dir, |
385 | struct dma_attrs *attrs) | ||
385 | { | 386 | { |
386 | struct iommu_table *tbl = find_iommu_table(dev); | 387 | struct iommu_table *tbl = find_iommu_table(dev); |
387 | struct scatterlist *s; | 388 | struct scatterlist *s; |
@@ -404,7 +405,8 @@ static void calgary_unmap_sg(struct device *dev, | |||
404 | } | 405 | } |
405 | 406 | ||
406 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | 407 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, |
407 | int nelems, int direction) | 408 | int nelems, enum dma_data_direction dir, |
409 | struct dma_attrs *attrs) | ||
408 | { | 410 | { |
409 | struct iommu_table *tbl = find_iommu_table(dev); | 411 | struct iommu_table *tbl = find_iommu_table(dev); |
410 | struct scatterlist *s; | 412 | struct scatterlist *s; |
@@ -429,15 +431,14 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
429 | s->dma_address = (entry << PAGE_SHIFT) | s->offset; | 431 | s->dma_address = (entry << PAGE_SHIFT) | s->offset; |
430 | 432 | ||
431 | /* insert into HW table */ | 433 | /* insert into HW table */ |
432 | tce_build(tbl, entry, npages, vaddr & PAGE_MASK, | 434 | tce_build(tbl, entry, npages, vaddr & PAGE_MASK, dir); |
433 | direction); | ||
434 | 435 | ||
435 | s->dma_length = s->length; | 436 | s->dma_length = s->length; |
436 | } | 437 | } |
437 | 438 | ||
438 | return nelems; | 439 | return nelems; |
439 | error: | 440 | error: |
440 | calgary_unmap_sg(dev, sg, nelems, direction); | 441 | calgary_unmap_sg(dev, sg, nelems, dir, NULL); |
441 | for_each_sg(sg, s, nelems, i) { | 442 | for_each_sg(sg, s, nelems, i) { |
442 | sg->dma_address = bad_dma_address; | 443 | sg->dma_address = bad_dma_address; |
443 | sg->dma_length = 0; | 444 | sg->dma_length = 0; |
@@ -445,10 +446,12 @@ error: | |||
445 | return 0; | 446 | return 0; |
446 | } | 447 | } |
447 | 448 | ||
448 | static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | 449 | static dma_addr_t calgary_map_page(struct device *dev, struct page *page, |
449 | size_t size, int direction) | 450 | unsigned long offset, size_t size, |
451 | enum dma_data_direction dir, | ||
452 | struct dma_attrs *attrs) | ||
450 | { | 453 | { |
451 | void *vaddr = phys_to_virt(paddr); | 454 | void *vaddr = page_address(page) + offset; |
452 | unsigned long uaddr; | 455 | unsigned long uaddr; |
453 | unsigned int npages; | 456 | unsigned int npages; |
454 | struct iommu_table *tbl = find_iommu_table(dev); | 457 | struct iommu_table *tbl = find_iommu_table(dev); |
@@ -456,17 +459,18 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | |||
456 | uaddr = (unsigned long)vaddr; | 459 | uaddr = (unsigned long)vaddr; |
457 | npages = iommu_num_pages(uaddr, size, PAGE_SIZE); | 460 | npages = iommu_num_pages(uaddr, size, PAGE_SIZE); |
458 | 461 | ||
459 | return iommu_alloc(dev, tbl, vaddr, npages, direction); | 462 | return iommu_alloc(dev, tbl, vaddr, npages, dir); |
460 | } | 463 | } |
461 | 464 | ||
462 | static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, | 465 | static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr, |
463 | size_t size, int direction) | 466 | size_t size, enum dma_data_direction dir, |
467 | struct dma_attrs *attrs) | ||
464 | { | 468 | { |
465 | struct iommu_table *tbl = find_iommu_table(dev); | 469 | struct iommu_table *tbl = find_iommu_table(dev); |
466 | unsigned int npages; | 470 | unsigned int npages; |
467 | 471 | ||
468 | npages = iommu_num_pages(dma_handle, size, PAGE_SIZE); | 472 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
469 | iommu_free(tbl, dma_handle, npages); | 473 | iommu_free(tbl, dma_addr, npages); |
470 | } | 474 | } |
471 | 475 | ||
472 | static void* calgary_alloc_coherent(struct device *dev, size_t size, | 476 | static void* calgary_alloc_coherent(struct device *dev, size_t size, |
@@ -515,13 +519,13 @@ static void calgary_free_coherent(struct device *dev, size_t size, | |||
515 | free_pages((unsigned long)vaddr, get_order(size)); | 519 | free_pages((unsigned long)vaddr, get_order(size)); |
516 | } | 520 | } |
517 | 521 | ||
518 | static struct dma_mapping_ops calgary_dma_ops = { | 522 | static struct dma_map_ops calgary_dma_ops = { |
519 | .alloc_coherent = calgary_alloc_coherent, | 523 | .alloc_coherent = calgary_alloc_coherent, |
520 | .free_coherent = calgary_free_coherent, | 524 | .free_coherent = calgary_free_coherent, |
521 | .map_single = calgary_map_single, | ||
522 | .unmap_single = calgary_unmap_single, | ||
523 | .map_sg = calgary_map_sg, | 525 | .map_sg = calgary_map_sg, |
524 | .unmap_sg = calgary_unmap_sg, | 526 | .unmap_sg = calgary_unmap_sg, |
527 | .map_page = calgary_map_page, | ||
528 | .unmap_page = calgary_unmap_page, | ||
525 | }; | 529 | }; |
526 | 530 | ||
527 | static inline void __iomem * busno_to_bbar(unsigned char num) | 531 | static inline void __iomem * busno_to_bbar(unsigned char num) |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index b25428533141..745579bc8256 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/dma-mapping.h> | 1 | #include <linux/dma-mapping.h> |
2 | #include <linux/dma-debug.h> | ||
2 | #include <linux/dmar.h> | 3 | #include <linux/dmar.h> |
3 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
4 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
@@ -12,7 +13,7 @@ | |||
12 | 13 | ||
13 | static int forbid_dac __read_mostly; | 14 | static int forbid_dac __read_mostly; |
14 | 15 | ||
15 | struct dma_mapping_ops *dma_ops; | 16 | struct dma_map_ops *dma_ops; |
16 | EXPORT_SYMBOL(dma_ops); | 17 | EXPORT_SYMBOL(dma_ops); |
17 | 18 | ||
18 | static int iommu_sac_force __read_mostly; | 19 | static int iommu_sac_force __read_mostly; |
@@ -39,11 +40,14 @@ EXPORT_SYMBOL(bad_dma_address); | |||
39 | to older i386. */ | 40 | to older i386. */ |
40 | struct device x86_dma_fallback_dev = { | 41 | struct device x86_dma_fallback_dev = { |
41 | .init_name = "fallback device", | 42 | .init_name = "fallback device", |
42 | .coherent_dma_mask = DMA_32BIT_MASK, | 43 | .coherent_dma_mask = DMA_BIT_MASK(32), |
43 | .dma_mask = &x86_dma_fallback_dev.coherent_dma_mask, | 44 | .dma_mask = &x86_dma_fallback_dev.coherent_dma_mask, |
44 | }; | 45 | }; |
45 | EXPORT_SYMBOL(x86_dma_fallback_dev); | 46 | EXPORT_SYMBOL(x86_dma_fallback_dev); |
46 | 47 | ||
48 | /* Number of entries preallocated for DMA-API debugging */ | ||
49 | #define PREALLOC_DMA_DEBUG_ENTRIES 32768 | ||
50 | |||
47 | int dma_set_mask(struct device *dev, u64 mask) | 51 | int dma_set_mask(struct device *dev, u64 mask) |
48 | { | 52 | { |
49 | if (!dev->dma_mask || !dma_supported(dev, mask)) | 53 | if (!dev->dma_mask || !dma_supported(dev, mask)) |
@@ -144,7 +148,7 @@ again: | |||
144 | if (!is_buffer_dma_capable(dma_mask, addr, size)) { | 148 | if (!is_buffer_dma_capable(dma_mask, addr, size)) { |
145 | __free_pages(page, get_order(size)); | 149 | __free_pages(page, get_order(size)); |
146 | 150 | ||
147 | if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) { | 151 | if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) { |
148 | flag = (flag & ~GFP_DMA32) | GFP_DMA; | 152 | flag = (flag & ~GFP_DMA32) | GFP_DMA; |
149 | goto again; | 153 | goto again; |
150 | } | 154 | } |
@@ -224,7 +228,7 @@ early_param("iommu", iommu_setup); | |||
224 | 228 | ||
225 | int dma_supported(struct device *dev, u64 mask) | 229 | int dma_supported(struct device *dev, u64 mask) |
226 | { | 230 | { |
227 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 231 | struct dma_map_ops *ops = get_dma_ops(dev); |
228 | 232 | ||
229 | #ifdef CONFIG_PCI | 233 | #ifdef CONFIG_PCI |
230 | if (mask > 0xffffffff && forbid_dac > 0) { | 234 | if (mask > 0xffffffff && forbid_dac > 0) { |
@@ -239,7 +243,7 @@ int dma_supported(struct device *dev, u64 mask) | |||
239 | /* Copied from i386. Doesn't make much sense, because it will | 243 | /* Copied from i386. Doesn't make much sense, because it will |
240 | only work for pci_alloc_coherent. | 244 | only work for pci_alloc_coherent. |
241 | The caller just has to use GFP_DMA in this case. */ | 245 | The caller just has to use GFP_DMA in this case. */ |
242 | if (mask < DMA_24BIT_MASK) | 246 | if (mask < DMA_BIT_MASK(24)) |
243 | return 0; | 247 | return 0; |
244 | 248 | ||
245 | /* Tell the device to use SAC when IOMMU force is on. This | 249 | /* Tell the device to use SAC when IOMMU force is on. This |
@@ -254,7 +258,7 @@ int dma_supported(struct device *dev, u64 mask) | |||
254 | SAC for these. Assume all masks <= 40 bits are of this | 258 | SAC for these. Assume all masks <= 40 bits are of this |
255 | type. Normally this doesn't make any difference, but gives | 259 | type. Normally this doesn't make any difference, but gives |
256 | more gentle handling of IOMMU overflow. */ | 260 | more gentle handling of IOMMU overflow. */ |
257 | if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { | 261 | if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) { |
258 | dev_info(dev, "Force SAC with mask %Lx\n", mask); | 262 | dev_info(dev, "Force SAC with mask %Lx\n", mask); |
259 | return 0; | 263 | return 0; |
260 | } | 264 | } |
@@ -265,6 +269,12 @@ EXPORT_SYMBOL(dma_supported); | |||
265 | 269 | ||
266 | static int __init pci_iommu_init(void) | 270 | static int __init pci_iommu_init(void) |
267 | { | 271 | { |
272 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | ||
273 | |||
274 | #ifdef CONFIG_PCI | ||
275 | dma_debug_add_bus(&pci_bus_type); | ||
276 | #endif | ||
277 | |||
268 | calgary_iommu_init(); | 278 | calgary_iommu_init(); |
269 | 279 | ||
270 | intel_iommu_init(); | 280 | intel_iommu_init(); |
@@ -290,8 +300,7 @@ fs_initcall(pci_iommu_init); | |||
290 | static __devinit void via_no_dac(struct pci_dev *dev) | 300 | static __devinit void via_no_dac(struct pci_dev *dev) |
291 | { | 301 | { |
292 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | 302 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { |
293 | printk(KERN_INFO | 303 | dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); |
294 | "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | ||
295 | forbid_dac = 1; | 304 | forbid_dac = 1; |
296 | } | 305 | } |
297 | } | 306 | } |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d5768b1af080..b284b58c035c 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -255,10 +255,13 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* Map a single area into the IOMMU */ | 257 | /* Map a single area into the IOMMU */ |
258 | static dma_addr_t | 258 | static dma_addr_t gart_map_page(struct device *dev, struct page *page, |
259 | gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) | 259 | unsigned long offset, size_t size, |
260 | enum dma_data_direction dir, | ||
261 | struct dma_attrs *attrs) | ||
260 | { | 262 | { |
261 | unsigned long bus; | 263 | unsigned long bus; |
264 | phys_addr_t paddr = page_to_phys(page) + offset; | ||
262 | 265 | ||
263 | if (!dev) | 266 | if (!dev) |
264 | dev = &x86_dma_fallback_dev; | 267 | dev = &x86_dma_fallback_dev; |
@@ -275,8 +278,9 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) | |||
275 | /* | 278 | /* |
276 | * Free a DMA mapping. | 279 | * Free a DMA mapping. |
277 | */ | 280 | */ |
278 | static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | 281 | static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, |
279 | size_t size, int direction) | 282 | size_t size, enum dma_data_direction dir, |
283 | struct dma_attrs *attrs) | ||
280 | { | 284 | { |
281 | unsigned long iommu_page; | 285 | unsigned long iommu_page; |
282 | int npages; | 286 | int npages; |
@@ -298,8 +302,8 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
298 | /* | 302 | /* |
299 | * Wrapper for pci_unmap_single working with scatterlists. | 303 | * Wrapper for pci_unmap_single working with scatterlists. |
300 | */ | 304 | */ |
301 | static void | 305 | static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, |
302 | gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | 306 | enum dma_data_direction dir, struct dma_attrs *attrs) |
303 | { | 307 | { |
304 | struct scatterlist *s; | 308 | struct scatterlist *s; |
305 | int i; | 309 | int i; |
@@ -307,7 +311,7 @@ gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
307 | for_each_sg(sg, s, nents, i) { | 311 | for_each_sg(sg, s, nents, i) { |
308 | if (!s->dma_length || !s->length) | 312 | if (!s->dma_length || !s->length) |
309 | break; | 313 | break; |
310 | gart_unmap_single(dev, s->dma_address, s->dma_length, dir); | 314 | gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL); |
311 | } | 315 | } |
312 | } | 316 | } |
313 | 317 | ||
@@ -329,7 +333,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, | |||
329 | addr = dma_map_area(dev, addr, s->length, dir, 0); | 333 | addr = dma_map_area(dev, addr, s->length, dir, 0); |
330 | if (addr == bad_dma_address) { | 334 | if (addr == bad_dma_address) { |
331 | if (i > 0) | 335 | if (i > 0) |
332 | gart_unmap_sg(dev, sg, i, dir); | 336 | gart_unmap_sg(dev, sg, i, dir, NULL); |
333 | nents = 0; | 337 | nents = 0; |
334 | sg[0].dma_length = 0; | 338 | sg[0].dma_length = 0; |
335 | break; | 339 | break; |
@@ -400,8 +404,8 @@ dma_map_cont(struct device *dev, struct scatterlist *start, int nelems, | |||
400 | * DMA map all entries in a scatterlist. | 404 | * DMA map all entries in a scatterlist. |
401 | * Merge chunks that have page aligned sizes into a continuous mapping. | 405 | * Merge chunks that have page aligned sizes into a continuous mapping. |
402 | */ | 406 | */ |
403 | static int | 407 | static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, |
404 | gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | 408 | enum dma_data_direction dir, struct dma_attrs *attrs) |
405 | { | 409 | { |
406 | struct scatterlist *s, *ps, *start_sg, *sgmap; | 410 | struct scatterlist *s, *ps, *start_sg, *sgmap; |
407 | int need = 0, nextneed, i, out, start; | 411 | int need = 0, nextneed, i, out, start; |
@@ -468,7 +472,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
468 | 472 | ||
469 | error: | 473 | error: |
470 | flush_gart(); | 474 | flush_gart(); |
471 | gart_unmap_sg(dev, sg, out, dir); | 475 | gart_unmap_sg(dev, sg, out, dir, NULL); |
472 | 476 | ||
473 | /* When it was forced or merged try again in a dumb way */ | 477 | /* When it was forced or merged try again in a dumb way */ |
474 | if (force_iommu || iommu_merge) { | 478 | if (force_iommu || iommu_merge) { |
@@ -521,7 +525,7 @@ static void | |||
521 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, | 525 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, |
522 | dma_addr_t dma_addr) | 526 | dma_addr_t dma_addr) |
523 | { | 527 | { |
524 | gart_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL); | 528 | gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); |
525 | free_pages((unsigned long)vaddr, get_order(size)); | 529 | free_pages((unsigned long)vaddr, get_order(size)); |
526 | } | 530 | } |
527 | 531 | ||
@@ -707,11 +711,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
707 | return -1; | 711 | return -1; |
708 | } | 712 | } |
709 | 713 | ||
710 | static struct dma_mapping_ops gart_dma_ops = { | 714 | static struct dma_map_ops gart_dma_ops = { |
711 | .map_single = gart_map_single, | ||
712 | .unmap_single = gart_unmap_single, | ||
713 | .map_sg = gart_map_sg, | 715 | .map_sg = gart_map_sg, |
714 | .unmap_sg = gart_unmap_sg, | 716 | .unmap_sg = gart_unmap_sg, |
717 | .map_page = gart_map_page, | ||
718 | .unmap_page = gart_unmap_page, | ||
715 | .alloc_coherent = gart_alloc_coherent, | 719 | .alloc_coherent = gart_alloc_coherent, |
716 | .free_coherent = gart_free_coherent, | 720 | .free_coherent = gart_free_coherent, |
717 | }; | 721 | }; |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 8b02a3936d42..71d412a09f30 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -15,7 +15,7 @@ static int | |||
15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | 15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) |
16 | { | 16 | { |
17 | if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) { | 17 | if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) { |
18 | if (*hwdev->dma_mask >= DMA_32BIT_MASK) | 18 | if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) |
19 | printk(KERN_ERR | 19 | printk(KERN_ERR |
20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", | 20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", |
21 | name, (long long)bus, size, | 21 | name, (long long)bus, size, |
@@ -25,19 +25,19 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | |||
25 | return 1; | 25 | return 1; |
26 | } | 26 | } |
27 | 27 | ||
28 | static dma_addr_t | 28 | static dma_addr_t nommu_map_page(struct device *dev, struct page *page, |
29 | nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, | 29 | unsigned long offset, size_t size, |
30 | int direction) | 30 | enum dma_data_direction dir, |
31 | struct dma_attrs *attrs) | ||
31 | { | 32 | { |
32 | dma_addr_t bus = paddr; | 33 | dma_addr_t bus = page_to_phys(page) + offset; |
33 | WARN_ON(size == 0); | 34 | WARN_ON(size == 0); |
34 | if (!check_addr("map_single", hwdev, bus, size)) | 35 | if (!check_addr("map_single", dev, bus, size)) |
35 | return bad_dma_address; | 36 | return bad_dma_address; |
36 | flush_write_buffers(); | 37 | flush_write_buffers(); |
37 | return bus; | 38 | return bus; |
38 | } | 39 | } |
39 | 40 | ||
40 | |||
41 | /* Map a set of buffers described by scatterlist in streaming | 41 | /* Map a set of buffers described by scatterlist in streaming |
42 | * mode for DMA. This is the scatter-gather version of the | 42 | * mode for DMA. This is the scatter-gather version of the |
43 | * above pci_map_single interface. Here the scatter gather list | 43 | * above pci_map_single interface. Here the scatter gather list |
@@ -54,7 +54,8 @@ nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, | |||
54 | * the same here. | 54 | * the same here. |
55 | */ | 55 | */ |
56 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | 56 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, |
57 | int nents, int direction) | 57 | int nents, enum dma_data_direction dir, |
58 | struct dma_attrs *attrs) | ||
58 | { | 59 | { |
59 | struct scatterlist *s; | 60 | struct scatterlist *s; |
60 | int i; | 61 | int i; |
@@ -78,11 +79,11 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, | |||
78 | free_pages((unsigned long)vaddr, get_order(size)); | 79 | free_pages((unsigned long)vaddr, get_order(size)); |
79 | } | 80 | } |
80 | 81 | ||
81 | struct dma_mapping_ops nommu_dma_ops = { | 82 | struct dma_map_ops nommu_dma_ops = { |
82 | .alloc_coherent = dma_generic_alloc_coherent, | 83 | .alloc_coherent = dma_generic_alloc_coherent, |
83 | .free_coherent = nommu_free_coherent, | 84 | .free_coherent = nommu_free_coherent, |
84 | .map_single = nommu_map_single, | ||
85 | .map_sg = nommu_map_sg, | 85 | .map_sg = nommu_map_sg, |
86 | .map_page = nommu_map_page, | ||
86 | .is_phys = 1, | 87 | .is_phys = 1, |
87 | }; | 88 | }; |
88 | 89 | ||
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb.c index d59c91747665..221a3853e268 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
@@ -33,18 +33,11 @@ phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr) | |||
33 | return baddr; | 33 | return baddr; |
34 | } | 34 | } |
35 | 35 | ||
36 | int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size) | 36 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) |
37 | { | 37 | { |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
41 | static dma_addr_t | ||
42 | swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, | ||
43 | int direction) | ||
44 | { | ||
45 | return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); | ||
46 | } | ||
47 | |||
48 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 41 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
49 | dma_addr_t *dma_handle, gfp_t flags) | 42 | dma_addr_t *dma_handle, gfp_t flags) |
50 | { | 43 | { |
@@ -57,20 +50,20 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
57 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); | 50 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); |
58 | } | 51 | } |
59 | 52 | ||
60 | struct dma_mapping_ops swiotlb_dma_ops = { | 53 | static struct dma_map_ops swiotlb_dma_ops = { |
61 | .mapping_error = swiotlb_dma_mapping_error, | 54 | .mapping_error = swiotlb_dma_mapping_error, |
62 | .alloc_coherent = x86_swiotlb_alloc_coherent, | 55 | .alloc_coherent = x86_swiotlb_alloc_coherent, |
63 | .free_coherent = swiotlb_free_coherent, | 56 | .free_coherent = swiotlb_free_coherent, |
64 | .map_single = swiotlb_map_single_phys, | ||
65 | .unmap_single = swiotlb_unmap_single, | ||
66 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, | 57 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, |
67 | .sync_single_for_device = swiotlb_sync_single_for_device, | 58 | .sync_single_for_device = swiotlb_sync_single_for_device, |
68 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, | 59 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, |
69 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, | 60 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, |
70 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, | 61 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, |
71 | .sync_sg_for_device = swiotlb_sync_sg_for_device, | 62 | .sync_sg_for_device = swiotlb_sync_sg_for_device, |
72 | .map_sg = swiotlb_map_sg, | 63 | .map_sg = swiotlb_map_sg_attrs, |
73 | .unmap_sg = swiotlb_unmap_sg, | 64 | .unmap_sg = swiotlb_unmap_sg_attrs, |
65 | .map_page = swiotlb_map_page, | ||
66 | .unmap_page = swiotlb_unmap_page, | ||
74 | .dma_supported = NULL, | 67 | .dma_supported = NULL, |
75 | }; | 68 | }; |
76 | 69 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 156f87582c6c..ca989158e847 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/pm.h> | 9 | #include <linux/pm.h> |
10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
11 | #include <linux/ftrace.h> | 11 | #include <trace/power.h> |
12 | #include <asm/system.h> | 12 | #include <asm/system.h> |
13 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
14 | #include <asm/idle.h> | 14 | #include <asm/idle.h> |
@@ -22,6 +22,9 @@ EXPORT_SYMBOL(idle_nomwait); | |||
22 | 22 | ||
23 | struct kmem_cache *task_xstate_cachep; | 23 | struct kmem_cache *task_xstate_cachep; |
24 | 24 | ||
25 | DEFINE_TRACE(power_start); | ||
26 | DEFINE_TRACE(power_end); | ||
27 | |||
25 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 28 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
26 | { | 29 | { |
27 | *dst = *src; | 30 | *dst = *src; |
@@ -325,7 +328,7 @@ void stop_this_cpu(void *dummy) | |||
325 | /* | 328 | /* |
326 | * Remove this CPU: | 329 | * Remove this CPU: |
327 | */ | 330 | */ |
328 | cpu_clear(smp_processor_id(), cpu_online_map); | 331 | set_cpu_online(smp_processor_id(), false); |
329 | disable_local_APIC(); | 332 | disable_local_APIC(); |
330 | 333 | ||
331 | for (;;) { | 334 | for (;;) { |
@@ -475,12 +478,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | |||
475 | return 1; | 478 | return 1; |
476 | } | 479 | } |
477 | 480 | ||
478 | static cpumask_t c1e_mask = CPU_MASK_NONE; | 481 | static cpumask_var_t c1e_mask; |
479 | static int c1e_detected; | 482 | static int c1e_detected; |
480 | 483 | ||
481 | void c1e_remove_cpu(int cpu) | 484 | void c1e_remove_cpu(int cpu) |
482 | { | 485 | { |
483 | cpu_clear(cpu, c1e_mask); | 486 | if (c1e_mask != NULL) |
487 | cpumask_clear_cpu(cpu, c1e_mask); | ||
484 | } | 488 | } |
485 | 489 | ||
486 | /* | 490 | /* |
@@ -509,8 +513,8 @@ static void c1e_idle(void) | |||
509 | if (c1e_detected) { | 513 | if (c1e_detected) { |
510 | int cpu = smp_processor_id(); | 514 | int cpu = smp_processor_id(); |
511 | 515 | ||
512 | if (!cpu_isset(cpu, c1e_mask)) { | 516 | if (!cpumask_test_cpu(cpu, c1e_mask)) { |
513 | cpu_set(cpu, c1e_mask); | 517 | cpumask_set_cpu(cpu, c1e_mask); |
514 | /* | 518 | /* |
515 | * Force broadcast so ACPI can not interfere. Needs | 519 | * Force broadcast so ACPI can not interfere. Needs |
516 | * to run with interrupts enabled as it uses | 520 | * to run with interrupts enabled as it uses |
@@ -562,6 +566,15 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | |||
562 | pm_idle = default_idle; | 566 | pm_idle = default_idle; |
563 | } | 567 | } |
564 | 568 | ||
569 | void __init init_c1e_mask(void) | ||
570 | { | ||
571 | /* If we're using c1e_idle, we need to allocate c1e_mask. */ | ||
572 | if (pm_idle == c1e_idle) { | ||
573 | alloc_cpumask_var(&c1e_mask, GFP_KERNEL); | ||
574 | cpumask_clear(c1e_mask); | ||
575 | } | ||
576 | } | ||
577 | |||
565 | static int __init idle_setup(char *str) | 578 | static int __init idle_setup(char *str) |
566 | { | 579 | { |
567 | if (!str) | 580 | if (!str) |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 14014d766cad..76f8f84043a2 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -245,7 +245,7 @@ void prepare_to_copy(struct task_struct *tsk) | |||
245 | unlazy_fpu(tsk); | 245 | unlazy_fpu(tsk); |
246 | } | 246 | } |
247 | 247 | ||
248 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 248 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
249 | unsigned long unused, | 249 | unsigned long unused, |
250 | struct task_struct *p, struct pt_regs *regs) | 250 | struct task_struct *p, struct pt_regs *regs) |
251 | { | 251 | { |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index abb7e6a7f0c6..b751a41392b1 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -278,7 +278,7 @@ void prepare_to_copy(struct task_struct *tsk) | |||
278 | unlazy_fpu(tsk); | 278 | unlazy_fpu(tsk); |
279 | } | 279 | } |
280 | 280 | ||
281 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 281 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
282 | unsigned long unused, | 282 | unsigned long unused, |
283 | struct task_struct *p, struct pt_regs *regs) | 283 | struct task_struct *p, struct pt_regs *regs) |
284 | { | 284 | { |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 19378715f415..23b7c8f017e2 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
35 | #include <asm/ds.h> | 35 | #include <asm/ds.h> |
36 | 36 | ||
37 | #include <trace/syscall.h> | ||
38 | |||
37 | #include "tls.h" | 39 | #include "tls.h" |
38 | 40 | ||
39 | enum x86_regset { | 41 | enum x86_regset { |
@@ -1415,6 +1417,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) | |||
1415 | tracehook_report_syscall_entry(regs)) | 1417 | tracehook_report_syscall_entry(regs)) |
1416 | ret = -1L; | 1418 | ret = -1L; |
1417 | 1419 | ||
1420 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | ||
1421 | ftrace_syscall_enter(regs); | ||
1422 | |||
1418 | if (unlikely(current->audit_context)) { | 1423 | if (unlikely(current->audit_context)) { |
1419 | if (IS_IA32) | 1424 | if (IS_IA32) |
1420 | audit_syscall_entry(AUDIT_ARCH_I386, | 1425 | audit_syscall_entry(AUDIT_ARCH_I386, |
@@ -1438,6 +1443,9 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) | |||
1438 | if (unlikely(current->audit_context)) | 1443 | if (unlikely(current->audit_context)) |
1439 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); | 1444 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); |
1440 | 1445 | ||
1446 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | ||
1447 | ftrace_syscall_exit(regs); | ||
1448 | |||
1441 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1449 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1442 | tracehook_report_syscall_exit(regs, 0); | 1450 | tracehook_report_syscall_exit(regs, 0); |
1443 | 1451 | ||
@@ -1455,6 +1463,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) | |||
1455 | * system call instruction. | 1463 | * system call instruction. |
1456 | */ | 1464 | */ |
1457 | if (test_thread_flag(TIF_SINGLESTEP) && | 1465 | if (test_thread_flag(TIF_SINGLESTEP) && |
1458 | tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) | 1466 | tracehook_consider_fatal_signal(current, SIGTRAP)) |
1459 | send_sigtrap(current, regs, 0, TRAP_BRKPT); | 1467 | send_sigtrap(current, regs, 0, TRAP_BRKPT); |
1460 | } | 1468 | } |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 6a5a2970f4c5..e95022e4f5d5 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -171,7 +171,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, | |||
171 | ich_force_enable_hpet); | 171 | ich_force_enable_hpet); |
172 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, | 172 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, |
173 | ich_force_enable_hpet); | 173 | ich_force_enable_hpet); |
174 | 174 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x3a16, /* ICH10 */ | |
175 | ich_force_enable_hpet); | ||
175 | 176 | ||
176 | static struct pci_dev *cached_dev; | 177 | static struct pci_dev *cached_dev; |
177 | 178 | ||
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2aef36d8aca2..1340dad417f4 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -224,6 +224,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
224 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), | 224 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), |
225 | }, | 225 | }, |
226 | }, | 226 | }, |
227 | { /* Handle problems with rebooting on Dell DXP061 */ | ||
228 | .callback = set_bios_reboot, | ||
229 | .ident = "Dell DXP061", | ||
230 | .matches = { | ||
231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
232 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), | ||
233 | }, | ||
234 | }, | ||
227 | { } | 235 | { } |
228 | }; | 236 | }; |
229 | 237 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a0d26237d7cf..b4158439bf63 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1049,7 +1049,6 @@ void __init x86_quirk_trap_init(void) | |||
1049 | static struct irqaction irq0 = { | 1049 | static struct irqaction irq0 = { |
1050 | .handler = timer_interrupt, | 1050 | .handler = timer_interrupt, |
1051 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, | 1051 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, |
1052 | .mask = CPU_MASK_NONE, | ||
1053 | .name = "timer" | 1052 | .name = "timer" |
1054 | }; | 1053 | }; |
1055 | 1054 | ||
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 400331b50a53..3a97a4cf1872 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -153,7 +153,6 @@ static struct page * __init pcpur_get_page(unsigned int cpu, int pageno) | |||
153 | static ssize_t __init setup_pcpu_remap(size_t static_size) | 153 | static ssize_t __init setup_pcpu_remap(size_t static_size) |
154 | { | 154 | { |
155 | static struct vm_struct vm; | 155 | static struct vm_struct vm; |
156 | pg_data_t *last; | ||
157 | size_t ptrs_size, dyn_size; | 156 | size_t ptrs_size, dyn_size; |
158 | unsigned int cpu; | 157 | unsigned int cpu; |
159 | ssize_t ret; | 158 | ssize_t ret; |
@@ -162,22 +161,9 @@ static ssize_t __init setup_pcpu_remap(size_t static_size) | |||
162 | * If large page isn't supported, there's no benefit in doing | 161 | * If large page isn't supported, there's no benefit in doing |
163 | * this. Also, on non-NUMA, embedding is better. | 162 | * this. Also, on non-NUMA, embedding is better. |
164 | */ | 163 | */ |
165 | if (!cpu_has_pse || pcpu_need_numa()) | 164 | if (!cpu_has_pse || !pcpu_need_numa()) |
166 | return -EINVAL; | 165 | return -EINVAL; |
167 | 166 | ||
168 | last = NULL; | ||
169 | for_each_possible_cpu(cpu) { | ||
170 | int node = early_cpu_to_node(cpu); | ||
171 | |||
172 | if (node_online(node) && NODE_DATA(node) && | ||
173 | last && last != NODE_DATA(node)) | ||
174 | goto proceed; | ||
175 | |||
176 | last = NODE_DATA(node); | ||
177 | } | ||
178 | return -EINVAL; | ||
179 | |||
180 | proceed: | ||
181 | /* | 167 | /* |
182 | * Currently supports only single page. Supporting multiple | 168 | * Currently supports only single page. Supporting multiple |
183 | * pages won't be too difficult if it ever becomes necessary. | 169 | * pages won't be too difficult if it ever becomes necessary. |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index dfcc74ab0ab6..14425166b8e3 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -221,7 +221,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | |||
221 | if (!onsigstack) { | 221 | if (!onsigstack) { |
222 | /* This is the X/Open sanctioned signal stack switching. */ | 222 | /* This is the X/Open sanctioned signal stack switching. */ |
223 | if (ka->sa.sa_flags & SA_ONSTACK) { | 223 | if (ka->sa.sa_flags & SA_ONSTACK) { |
224 | if (sas_ss_flags(sp) == 0) | 224 | if (current->sas_ss_size) |
225 | sp = current->sas_ss_sp + current->sas_ss_size; | 225 | sp = current->sas_ss_sp + current->sas_ss_size; |
226 | } else { | 226 | } else { |
227 | #ifdef CONFIG_X86_32 | 227 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index ef7d10170c30..58d24ef917d8 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -101,11 +101,11 @@ EXPORT_SYMBOL(smp_num_siblings); | |||
101 | DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID; | 101 | DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID; |
102 | 102 | ||
103 | /* representing HT siblings of each logical CPU */ | 103 | /* representing HT siblings of each logical CPU */ |
104 | DEFINE_PER_CPU(cpumask_t, cpu_sibling_map); | 104 | DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); |
105 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | 105 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); |
106 | 106 | ||
107 | /* representing HT and core siblings of each logical CPU */ | 107 | /* representing HT and core siblings of each logical CPU */ |
108 | DEFINE_PER_CPU(cpumask_t, cpu_core_map); | 108 | DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); |
109 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); | 109 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); |
110 | 110 | ||
111 | /* Per CPU bogomips and other parameters */ | 111 | /* Per CPU bogomips and other parameters */ |
@@ -115,11 +115,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); | |||
115 | atomic_t init_deasserted; | 115 | atomic_t init_deasserted; |
116 | 116 | ||
117 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) | 117 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) |
118 | |||
119 | /* which logical CPUs are on which nodes */ | ||
120 | cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly = | ||
121 | { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; | ||
122 | EXPORT_SYMBOL(node_to_cpumask_map); | ||
123 | /* which node each logical CPU is on */ | 118 | /* which node each logical CPU is on */ |
124 | int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; | 119 | int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; |
125 | EXPORT_SYMBOL(cpu_to_node_map); | 120 | EXPORT_SYMBOL(cpu_to_node_map); |
@@ -128,7 +123,7 @@ EXPORT_SYMBOL(cpu_to_node_map); | |||
128 | static void map_cpu_to_node(int cpu, int node) | 123 | static void map_cpu_to_node(int cpu, int node) |
129 | { | 124 | { |
130 | printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node); | 125 | printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node); |
131 | cpumask_set_cpu(cpu, &node_to_cpumask_map[node]); | 126 | cpumask_set_cpu(cpu, node_to_cpumask_map[node]); |
132 | cpu_to_node_map[cpu] = node; | 127 | cpu_to_node_map[cpu] = node; |
133 | } | 128 | } |
134 | 129 | ||
@@ -139,7 +134,7 @@ static void unmap_cpu_to_node(int cpu) | |||
139 | 134 | ||
140 | printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu); | 135 | printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu); |
141 | for (node = 0; node < MAX_NUMNODES; node++) | 136 | for (node = 0; node < MAX_NUMNODES; node++) |
142 | cpumask_clear_cpu(cpu, &node_to_cpumask_map[node]); | 137 | cpumask_clear_cpu(cpu, node_to_cpumask_map[node]); |
143 | cpu_to_node_map[cpu] = 0; | 138 | cpu_to_node_map[cpu] = 0; |
144 | } | 139 | } |
145 | #else /* !(CONFIG_NUMA && CONFIG_X86_32) */ | 140 | #else /* !(CONFIG_NUMA && CONFIG_X86_32) */ |
@@ -301,7 +296,7 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
301 | __flush_tlb_all(); | 296 | __flush_tlb_all(); |
302 | #endif | 297 | #endif |
303 | 298 | ||
304 | /* This must be done before setting cpu_online_map */ | 299 | /* This must be done before setting cpu_online_mask */ |
305 | set_cpu_sibling_map(raw_smp_processor_id()); | 300 | set_cpu_sibling_map(raw_smp_processor_id()); |
306 | wmb(); | 301 | wmb(); |
307 | 302 | ||
@@ -334,6 +329,23 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
334 | cpu_idle(); | 329 | cpu_idle(); |
335 | } | 330 | } |
336 | 331 | ||
332 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
333 | /* In this case, llc_shared_map is a pointer to a cpumask. */ | ||
334 | static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst, | ||
335 | const struct cpuinfo_x86 *src) | ||
336 | { | ||
337 | struct cpumask *llc = dst->llc_shared_map; | ||
338 | *dst = *src; | ||
339 | dst->llc_shared_map = llc; | ||
340 | } | ||
341 | #else | ||
342 | static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst, | ||
343 | const struct cpuinfo_x86 *src) | ||
344 | { | ||
345 | *dst = *src; | ||
346 | } | ||
347 | #endif /* CONFIG_CPUMASK_OFFSTACK */ | ||
348 | |||
337 | /* | 349 | /* |
338 | * The bootstrap kernel entry code has set these up. Save them for | 350 | * The bootstrap kernel entry code has set these up. Save them for |
339 | * a given CPU | 351 | * a given CPU |
@@ -343,7 +355,7 @@ void __cpuinit smp_store_cpu_info(int id) | |||
343 | { | 355 | { |
344 | struct cpuinfo_x86 *c = &cpu_data(id); | 356 | struct cpuinfo_x86 *c = &cpu_data(id); |
345 | 357 | ||
346 | *c = boot_cpu_data; | 358 | copy_cpuinfo_x86(c, &boot_cpu_data); |
347 | c->cpu_index = id; | 359 | c->cpu_index = id; |
348 | if (id != 0) | 360 | if (id != 0) |
349 | identify_secondary_cpu(c); | 361 | identify_secondary_cpu(c); |
@@ -367,15 +379,15 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
367 | cpumask_set_cpu(cpu, cpu_sibling_mask(i)); | 379 | cpumask_set_cpu(cpu, cpu_sibling_mask(i)); |
368 | cpumask_set_cpu(i, cpu_core_mask(cpu)); | 380 | cpumask_set_cpu(i, cpu_core_mask(cpu)); |
369 | cpumask_set_cpu(cpu, cpu_core_mask(i)); | 381 | cpumask_set_cpu(cpu, cpu_core_mask(i)); |
370 | cpumask_set_cpu(i, &c->llc_shared_map); | 382 | cpumask_set_cpu(i, c->llc_shared_map); |
371 | cpumask_set_cpu(cpu, &o->llc_shared_map); | 383 | cpumask_set_cpu(cpu, o->llc_shared_map); |
372 | } | 384 | } |
373 | } | 385 | } |
374 | } else { | 386 | } else { |
375 | cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); | 387 | cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); |
376 | } | 388 | } |
377 | 389 | ||
378 | cpumask_set_cpu(cpu, &c->llc_shared_map); | 390 | cpumask_set_cpu(cpu, c->llc_shared_map); |
379 | 391 | ||
380 | if (current_cpu_data.x86_max_cores == 1) { | 392 | if (current_cpu_data.x86_max_cores == 1) { |
381 | cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu)); | 393 | cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu)); |
@@ -386,8 +398,8 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
386 | for_each_cpu(i, cpu_sibling_setup_mask) { | 398 | for_each_cpu(i, cpu_sibling_setup_mask) { |
387 | if (per_cpu(cpu_llc_id, cpu) != BAD_APICID && | 399 | if (per_cpu(cpu_llc_id, cpu) != BAD_APICID && |
388 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { | 400 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { |
389 | cpumask_set_cpu(i, &c->llc_shared_map); | 401 | cpumask_set_cpu(i, c->llc_shared_map); |
390 | cpumask_set_cpu(cpu, &cpu_data(i).llc_shared_map); | 402 | cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map); |
391 | } | 403 | } |
392 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { | 404 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { |
393 | cpumask_set_cpu(i, cpu_core_mask(cpu)); | 405 | cpumask_set_cpu(i, cpu_core_mask(cpu)); |
@@ -425,12 +437,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu) | |||
425 | if (sched_mc_power_savings || sched_smt_power_savings) | 437 | if (sched_mc_power_savings || sched_smt_power_savings) |
426 | return cpu_core_mask(cpu); | 438 | return cpu_core_mask(cpu); |
427 | else | 439 | else |
428 | return &c->llc_shared_map; | 440 | return c->llc_shared_map; |
429 | } | ||
430 | |||
431 | cpumask_t cpu_coregroup_map(int cpu) | ||
432 | { | ||
433 | return *cpu_coregroup_mask(cpu); | ||
434 | } | 441 | } |
435 | 442 | ||
436 | static void impress_friends(void) | 443 | static void impress_friends(void) |
@@ -897,9 +904,8 @@ int __cpuinit native_cpu_up(unsigned int cpu) | |||
897 | */ | 904 | */ |
898 | static __init void disable_smp(void) | 905 | static __init void disable_smp(void) |
899 | { | 906 | { |
900 | /* use the read/write pointers to the present and possible maps */ | 907 | init_cpu_present(cpumask_of(0)); |
901 | cpumask_copy(&cpu_present_map, cpumask_of(0)); | 908 | init_cpu_possible(cpumask_of(0)); |
902 | cpumask_copy(&cpu_possible_map, cpumask_of(0)); | ||
903 | smpboot_clear_io_apic_irqs(); | 909 | smpboot_clear_io_apic_irqs(); |
904 | 910 | ||
905 | if (smp_found_config) | 911 | if (smp_found_config) |
@@ -1031,6 +1037,8 @@ static void __init smp_cpu_index_default(void) | |||
1031 | */ | 1037 | */ |
1032 | void __init native_smp_prepare_cpus(unsigned int max_cpus) | 1038 | void __init native_smp_prepare_cpus(unsigned int max_cpus) |
1033 | { | 1039 | { |
1040 | unsigned int i; | ||
1041 | |||
1034 | preempt_disable(); | 1042 | preempt_disable(); |
1035 | smp_cpu_index_default(); | 1043 | smp_cpu_index_default(); |
1036 | current_cpu_data = boot_cpu_data; | 1044 | current_cpu_data = boot_cpu_data; |
@@ -1044,6 +1052,14 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1044 | boot_cpu_logical_apicid = logical_smp_processor_id(); | 1052 | boot_cpu_logical_apicid = logical_smp_processor_id(); |
1045 | #endif | 1053 | #endif |
1046 | current_thread_info()->cpu = 0; /* needed? */ | 1054 | current_thread_info()->cpu = 0; /* needed? */ |
1055 | for_each_possible_cpu(i) { | ||
1056 | alloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); | ||
1057 | alloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); | ||
1058 | alloc_cpumask_var(&cpu_data(i).llc_shared_map, GFP_KERNEL); | ||
1059 | cpumask_clear(per_cpu(cpu_core_map, i)); | ||
1060 | cpumask_clear(per_cpu(cpu_sibling_map, i)); | ||
1061 | cpumask_clear(cpu_data(i).llc_shared_map); | ||
1062 | } | ||
1047 | set_cpu_sibling_map(0); | 1063 | set_cpu_sibling_map(0); |
1048 | 1064 | ||
1049 | enable_IR_x2apic(); | 1065 | enable_IR_x2apic(); |
@@ -1132,11 +1148,11 @@ early_param("possible_cpus", _setup_possible_cpus); | |||
1132 | 1148 | ||
1133 | 1149 | ||
1134 | /* | 1150 | /* |
1135 | * cpu_possible_map should be static, it cannot change as cpu's | 1151 | * cpu_possible_mask should be static, it cannot change as cpu's |
1136 | * are onlined, or offlined. The reason is per-cpu data-structures | 1152 | * are onlined, or offlined. The reason is per-cpu data-structures |
1137 | * are allocated by some modules at init time, and dont expect to | 1153 | * are allocated by some modules at init time, and dont expect to |
1138 | * do this dynamically on cpu arrival/departure. | 1154 | * do this dynamically on cpu arrival/departure. |
1139 | * cpu_present_map on the other hand can change dynamically. | 1155 | * cpu_present_mask on the other hand can change dynamically. |
1140 | * In case when cpu_hotplug is not compiled, then we resort to current | 1156 | * In case when cpu_hotplug is not compiled, then we resort to current |
1141 | * behaviour, which is cpu_possible == cpu_present. | 1157 | * behaviour, which is cpu_possible == cpu_present. |
1142 | * - Ashok Raj | 1158 | * - Ashok Raj |
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index 3bdb64829b82..ff5c8736b491 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S | |||
@@ -332,3 +332,5 @@ ENTRY(sys_call_table) | |||
332 | .long sys_dup3 /* 330 */ | 332 | .long sys_dup3 /* 330 */ |
333 | .long sys_pipe2 | 333 | .long sys_pipe2 |
334 | .long sys_inotify_init1 | 334 | .long sys_inotify_init1 |
335 | .long sys_preadv | ||
336 | .long sys_pwritev | ||
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index 241ec3923f61..5ba343e61844 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c | |||
@@ -116,7 +116,6 @@ unsigned long __init calibrate_cpu(void) | |||
116 | static struct irqaction irq0 = { | 116 | static struct irqaction irq0 = { |
117 | .handler = timer_interrupt, | 117 | .handler = timer_interrupt, |
118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, | 118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, |
119 | .mask = CPU_MASK_NONE, | ||
120 | .name = "timer" | 119 | .name = "timer" |
121 | }; | 120 | }; |
122 | 121 | ||
@@ -125,7 +124,6 @@ void __init hpet_time_init(void) | |||
125 | if (!hpet_enable()) | 124 | if (!hpet_enable()) |
126 | setup_pit_timer(); | 125 | setup_pit_timer(); |
127 | 126 | ||
128 | irq0.mask = cpumask_of_cpu(0); | ||
129 | setup_irq(0, &irq0); | 127 | setup_irq(0, &irq0); |
130 | } | 128 | } |
131 | 129 | ||
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 79c073247284..ed0c33761e6d 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
@@ -25,6 +25,8 @@ static int uv_bau_retry_limit __read_mostly; | |||
25 | 25 | ||
26 | /* position of pnode (which is nasid>>1): */ | 26 | /* position of pnode (which is nasid>>1): */ |
27 | static int uv_nshift __read_mostly; | 27 | static int uv_nshift __read_mostly; |
28 | /* base pnode in this partition */ | ||
29 | static int uv_partition_base_pnode __read_mostly; | ||
28 | 30 | ||
29 | static unsigned long uv_mmask __read_mostly; | 31 | static unsigned long uv_mmask __read_mostly; |
30 | 32 | ||
@@ -32,6 +34,34 @@ static DEFINE_PER_CPU(struct ptc_stats, ptcstats); | |||
32 | static DEFINE_PER_CPU(struct bau_control, bau_control); | 34 | static DEFINE_PER_CPU(struct bau_control, bau_control); |
33 | 35 | ||
34 | /* | 36 | /* |
37 | * Determine the first node on a blade. | ||
38 | */ | ||
39 | static int __init blade_to_first_node(int blade) | ||
40 | { | ||
41 | int node, b; | ||
42 | |||
43 | for_each_online_node(node) { | ||
44 | b = uv_node_to_blade_id(node); | ||
45 | if (blade == b) | ||
46 | return node; | ||
47 | } | ||
48 | return -1; /* shouldn't happen */ | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Determine the apicid of the first cpu on a blade. | ||
53 | */ | ||
54 | static int __init blade_to_first_apicid(int blade) | ||
55 | { | ||
56 | int cpu; | ||
57 | |||
58 | for_each_present_cpu(cpu) | ||
59 | if (blade == uv_cpu_to_blade_id(cpu)) | ||
60 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
61 | return -1; | ||
62 | } | ||
63 | |||
64 | /* | ||
35 | * Free a software acknowledge hardware resource by clearing its Pending | 65 | * Free a software acknowledge hardware resource by clearing its Pending |
36 | * bit. This will return a reply to the sender. | 66 | * bit. This will return a reply to the sender. |
37 | * If the message has timed out, a reply has already been sent by the | 67 | * If the message has timed out, a reply has already been sent by the |
@@ -67,7 +97,7 @@ static void uv_bau_process_message(struct bau_payload_queue_entry *msg, | |||
67 | msp = __get_cpu_var(bau_control).msg_statuses + msg_slot; | 97 | msp = __get_cpu_var(bau_control).msg_statuses + msg_slot; |
68 | cpu = uv_blade_processor_id(); | 98 | cpu = uv_blade_processor_id(); |
69 | msg->number_of_cpus = | 99 | msg->number_of_cpus = |
70 | uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id())); | 100 | uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id())); |
71 | this_cpu_mask = 1UL << cpu; | 101 | this_cpu_mask = 1UL << cpu; |
72 | if (msp->seen_by.bits & this_cpu_mask) | 102 | if (msp->seen_by.bits & this_cpu_mask) |
73 | return; | 103 | return; |
@@ -215,14 +245,14 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
215 | * Returns @flush_mask if some remote flushing remains to be done. The | 245 | * Returns @flush_mask if some remote flushing remains to be done. The |
216 | * mask will have some bits still set. | 246 | * mask will have some bits still set. |
217 | */ | 247 | */ |
218 | const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade, | 248 | const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode, |
219 | struct bau_desc *bau_desc, | 249 | struct bau_desc *bau_desc, |
220 | struct cpumask *flush_mask) | 250 | struct cpumask *flush_mask) |
221 | { | 251 | { |
222 | int completion_status = 0; | 252 | int completion_status = 0; |
223 | int right_shift; | 253 | int right_shift; |
224 | int tries = 0; | 254 | int tries = 0; |
225 | int blade; | 255 | int pnode; |
226 | int bit; | 256 | int bit; |
227 | unsigned long mmr_offset; | 257 | unsigned long mmr_offset; |
228 | unsigned long index; | 258 | unsigned long index; |
@@ -265,8 +295,8 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade, | |||
265 | * use the IPI method of shootdown on them. | 295 | * use the IPI method of shootdown on them. |
266 | */ | 296 | */ |
267 | for_each_cpu(bit, flush_mask) { | 297 | for_each_cpu(bit, flush_mask) { |
268 | blade = uv_cpu_to_blade_id(bit); | 298 | pnode = uv_cpu_to_pnode(bit); |
269 | if (blade == this_blade) | 299 | if (pnode == this_pnode) |
270 | continue; | 300 | continue; |
271 | cpumask_clear_cpu(bit, flush_mask); | 301 | cpumask_clear_cpu(bit, flush_mask); |
272 | } | 302 | } |
@@ -275,6 +305,8 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade, | |||
275 | return NULL; | 305 | return NULL; |
276 | } | 306 | } |
277 | 307 | ||
308 | static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); | ||
309 | |||
278 | /** | 310 | /** |
279 | * uv_flush_tlb_others - globally purge translation cache of a virtual | 311 | * uv_flush_tlb_others - globally purge translation cache of a virtual |
280 | * address or all TLB's | 312 | * address or all TLB's |
@@ -304,20 +336,19 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
304 | struct mm_struct *mm, | 336 | struct mm_struct *mm, |
305 | unsigned long va, unsigned int cpu) | 337 | unsigned long va, unsigned int cpu) |
306 | { | 338 | { |
307 | static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask); | 339 | struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask); |
308 | struct cpumask *flush_mask = &__get_cpu_var(flush_tlb_mask); | ||
309 | int i; | 340 | int i; |
310 | int bit; | 341 | int bit; |
311 | int blade; | 342 | int pnode; |
312 | int uv_cpu; | 343 | int uv_cpu; |
313 | int this_blade; | 344 | int this_pnode; |
314 | int locals = 0; | 345 | int locals = 0; |
315 | struct bau_desc *bau_desc; | 346 | struct bau_desc *bau_desc; |
316 | 347 | ||
317 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); | 348 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); |
318 | 349 | ||
319 | uv_cpu = uv_blade_processor_id(); | 350 | uv_cpu = uv_blade_processor_id(); |
320 | this_blade = uv_numa_blade_id(); | 351 | this_pnode = uv_hub_info->pnode; |
321 | bau_desc = __get_cpu_var(bau_control).descriptor_base; | 352 | bau_desc = __get_cpu_var(bau_control).descriptor_base; |
322 | bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu; | 353 | bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu; |
323 | 354 | ||
@@ -325,13 +356,14 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
325 | 356 | ||
326 | i = 0; | 357 | i = 0; |
327 | for_each_cpu(bit, flush_mask) { | 358 | for_each_cpu(bit, flush_mask) { |
328 | blade = uv_cpu_to_blade_id(bit); | 359 | pnode = uv_cpu_to_pnode(bit); |
329 | BUG_ON(blade > (UV_DISTRIBUTION_SIZE - 1)); | 360 | BUG_ON(pnode > (UV_DISTRIBUTION_SIZE - 1)); |
330 | if (blade == this_blade) { | 361 | if (pnode == this_pnode) { |
331 | locals++; | 362 | locals++; |
332 | continue; | 363 | continue; |
333 | } | 364 | } |
334 | bau_node_set(blade, &bau_desc->distribution); | 365 | bau_node_set(pnode - uv_partition_base_pnode, |
366 | &bau_desc->distribution); | ||
335 | i++; | 367 | i++; |
336 | } | 368 | } |
337 | if (i == 0) { | 369 | if (i == 0) { |
@@ -349,7 +381,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
349 | bau_desc->payload.address = va; | 381 | bau_desc->payload.address = va; |
350 | bau_desc->payload.sending_cpu = cpu; | 382 | bau_desc->payload.sending_cpu = cpu; |
351 | 383 | ||
352 | return uv_flush_send_and_wait(uv_cpu, this_blade, bau_desc, flush_mask); | 384 | return uv_flush_send_and_wait(uv_cpu, this_pnode, bau_desc, flush_mask); |
353 | } | 385 | } |
354 | 386 | ||
355 | /* | 387 | /* |
@@ -417,24 +449,58 @@ void uv_bau_message_interrupt(struct pt_regs *regs) | |||
417 | set_irq_regs(old_regs); | 449 | set_irq_regs(old_regs); |
418 | } | 450 | } |
419 | 451 | ||
452 | /* | ||
453 | * uv_enable_timeouts | ||
454 | * | ||
455 | * Each target blade (i.e. blades that have cpu's) needs to have | ||
456 | * shootdown message timeouts enabled. The timeout does not cause | ||
457 | * an interrupt, but causes an error message to be returned to | ||
458 | * the sender. | ||
459 | */ | ||
420 | static void uv_enable_timeouts(void) | 460 | static void uv_enable_timeouts(void) |
421 | { | 461 | { |
422 | int i; | ||
423 | int blade; | 462 | int blade; |
424 | int last_blade; | 463 | int nblades; |
425 | int pnode; | 464 | int pnode; |
426 | int cur_cpu = 0; | 465 | unsigned long mmr_image; |
427 | unsigned long apicid; | ||
428 | 466 | ||
429 | last_blade = -1; | 467 | nblades = uv_num_possible_blades(); |
430 | for_each_online_node(i) { | 468 | |
431 | blade = uv_node_to_blade_id(i); | 469 | for (blade = 0; blade < nblades; blade++) { |
432 | if (blade == last_blade) | 470 | if (!uv_blade_nr_possible_cpus(blade)) |
433 | continue; | 471 | continue; |
434 | last_blade = blade; | 472 | |
435 | apicid = per_cpu(x86_cpu_to_apicid, cur_cpu); | ||
436 | pnode = uv_blade_to_pnode(blade); | 473 | pnode = uv_blade_to_pnode(blade); |
437 | cur_cpu += uv_blade_nr_possible_cpus(i); | 474 | mmr_image = |
475 | uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
476 | /* | ||
477 | * Set the timeout period and then lock it in, in three | ||
478 | * steps; captures and locks in the period. | ||
479 | * | ||
480 | * To program the period, the SOFT_ACK_MODE must be off. | ||
481 | */ | ||
482 | mmr_image &= ~((unsigned long)1 << | ||
483 | UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT); | ||
484 | uv_write_global_mmr64 | ||
485 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
486 | /* | ||
487 | * Set the 4-bit period. | ||
488 | */ | ||
489 | mmr_image &= ~((unsigned long)0xf << | ||
490 | UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT); | ||
491 | mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD << | ||
492 | UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT); | ||
493 | uv_write_global_mmr64 | ||
494 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
495 | /* | ||
496 | * Subsequent reversals of the timebase bit (3) cause an | ||
497 | * immediate timeout of one or all INTD resources as | ||
498 | * indicated in bits 2:0 (7 causes all of them to timeout). | ||
499 | */ | ||
500 | mmr_image |= ((unsigned long)1 << | ||
501 | UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT); | ||
502 | uv_write_global_mmr64 | ||
503 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
438 | } | 504 | } |
439 | } | 505 | } |
440 | 506 | ||
@@ -481,8 +547,7 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
481 | stat->requestee, stat->onetlb, stat->alltlb, | 547 | stat->requestee, stat->onetlb, stat->alltlb, |
482 | stat->s_retry, stat->d_retry, stat->ptc_i); | 548 | stat->s_retry, stat->d_retry, stat->ptc_i); |
483 | seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n", | 549 | seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n", |
484 | uv_read_global_mmr64(uv_blade_to_pnode | 550 | uv_read_global_mmr64(uv_cpu_to_pnode(cpu), |
485 | (uv_cpu_to_blade_id(cpu)), | ||
486 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE), | 551 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE), |
487 | stat->sflush, stat->dflush, | 552 | stat->sflush, stat->dflush, |
488 | stat->retriesok, stat->nomsg, | 553 | stat->retriesok, stat->nomsg, |
@@ -616,16 +681,18 @@ static struct bau_control * __init uv_table_bases_init(int blade, int node) | |||
616 | * finish the initialization of the per-blade control structures | 681 | * finish the initialization of the per-blade control structures |
617 | */ | 682 | */ |
618 | static void __init | 683 | static void __init |
619 | uv_table_bases_finish(int blade, int node, int cur_cpu, | 684 | uv_table_bases_finish(int blade, |
620 | struct bau_control *bau_tablesp, | 685 | struct bau_control *bau_tablesp, |
621 | struct bau_desc *adp) | 686 | struct bau_desc *adp) |
622 | { | 687 | { |
623 | struct bau_control *bcp; | 688 | struct bau_control *bcp; |
624 | int i; | 689 | int cpu; |
625 | 690 | ||
626 | for (i = cur_cpu; i < cur_cpu + uv_blade_nr_possible_cpus(blade); i++) { | 691 | for_each_present_cpu(cpu) { |
627 | bcp = (struct bau_control *)&per_cpu(bau_control, i); | 692 | if (blade != uv_cpu_to_blade_id(cpu)) |
693 | continue; | ||
628 | 694 | ||
695 | bcp = (struct bau_control *)&per_cpu(bau_control, cpu); | ||
629 | bcp->bau_msg_head = bau_tablesp->va_queue_first; | 696 | bcp->bau_msg_head = bau_tablesp->va_queue_first; |
630 | bcp->va_queue_first = bau_tablesp->va_queue_first; | 697 | bcp->va_queue_first = bau_tablesp->va_queue_first; |
631 | bcp->va_queue_last = bau_tablesp->va_queue_last; | 698 | bcp->va_queue_last = bau_tablesp->va_queue_last; |
@@ -648,11 +715,10 @@ uv_activation_descriptor_init(int node, int pnode) | |||
648 | struct bau_desc *adp; | 715 | struct bau_desc *adp; |
649 | struct bau_desc *ad2; | 716 | struct bau_desc *ad2; |
650 | 717 | ||
651 | adp = (struct bau_desc *) | 718 | adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node); |
652 | kmalloc_node(16384, GFP_KERNEL, node); | ||
653 | BUG_ON(!adp); | 719 | BUG_ON(!adp); |
654 | 720 | ||
655 | pa = __pa((unsigned long)adp); | 721 | pa = uv_gpa(adp); /* need the real nasid*/ |
656 | n = pa >> uv_nshift; | 722 | n = pa >> uv_nshift; |
657 | m = pa & uv_mmask; | 723 | m = pa & uv_mmask; |
658 | 724 | ||
@@ -666,8 +732,12 @@ uv_activation_descriptor_init(int node, int pnode) | |||
666 | for (i = 0, ad2 = adp; i < UV_ACTIVATION_DESCRIPTOR_SIZE; i++, ad2++) { | 732 | for (i = 0, ad2 = adp; i < UV_ACTIVATION_DESCRIPTOR_SIZE; i++, ad2++) { |
667 | memset(ad2, 0, sizeof(struct bau_desc)); | 733 | memset(ad2, 0, sizeof(struct bau_desc)); |
668 | ad2->header.sw_ack_flag = 1; | 734 | ad2->header.sw_ack_flag = 1; |
669 | ad2->header.base_dest_nodeid = | 735 | /* |
670 | uv_blade_to_pnode(uv_cpu_to_blade_id(0)); | 736 | * base_dest_nodeid is the first node in the partition, so |
737 | * the bit map will indicate partition-relative node numbers. | ||
738 | * note that base_dest_nodeid is actually a nasid. | ||
739 | */ | ||
740 | ad2->header.base_dest_nodeid = uv_partition_base_pnode << 1; | ||
671 | ad2->header.command = UV_NET_ENDPOINT_INTD; | 741 | ad2->header.command = UV_NET_ENDPOINT_INTD; |
672 | ad2->header.int_both = 1; | 742 | ad2->header.int_both = 1; |
673 | /* | 743 | /* |
@@ -685,6 +755,8 @@ static struct bau_payload_queue_entry * __init | |||
685 | uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) | 755 | uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) |
686 | { | 756 | { |
687 | struct bau_payload_queue_entry *pqp; | 757 | struct bau_payload_queue_entry *pqp; |
758 | unsigned long pa; | ||
759 | int pn; | ||
688 | char *cp; | 760 | char *cp; |
689 | 761 | ||
690 | pqp = (struct bau_payload_queue_entry *) kmalloc_node( | 762 | pqp = (struct bau_payload_queue_entry *) kmalloc_node( |
@@ -695,10 +767,14 @@ uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) | |||
695 | cp = (char *)pqp + 31; | 767 | cp = (char *)pqp + 31; |
696 | pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); | 768 | pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); |
697 | bau_tablesp->va_queue_first = pqp; | 769 | bau_tablesp->va_queue_first = pqp; |
770 | /* | ||
771 | * need the pnode of where the memory was really allocated | ||
772 | */ | ||
773 | pa = uv_gpa(pqp); | ||
774 | pn = pa >> uv_nshift; | ||
698 | uv_write_global_mmr64(pnode, | 775 | uv_write_global_mmr64(pnode, |
699 | UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, | 776 | UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, |
700 | ((unsigned long)pnode << | 777 | ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | |
701 | UV_PAYLOADQ_PNODE_SHIFT) | | ||
702 | uv_physnodeaddr(pqp)); | 778 | uv_physnodeaddr(pqp)); |
703 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, | 779 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, |
704 | uv_physnodeaddr(pqp)); | 780 | uv_physnodeaddr(pqp)); |
@@ -714,8 +790,9 @@ uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) | |||
714 | /* | 790 | /* |
715 | * Initialization of each UV blade's structures | 791 | * Initialization of each UV blade's structures |
716 | */ | 792 | */ |
717 | static int __init uv_init_blade(int blade, int node, int cur_cpu) | 793 | static int __init uv_init_blade(int blade) |
718 | { | 794 | { |
795 | int node; | ||
719 | int pnode; | 796 | int pnode; |
720 | unsigned long pa; | 797 | unsigned long pa; |
721 | unsigned long apicid; | 798 | unsigned long apicid; |
@@ -723,16 +800,17 @@ static int __init uv_init_blade(int blade, int node, int cur_cpu) | |||
723 | struct bau_payload_queue_entry *pqp; | 800 | struct bau_payload_queue_entry *pqp; |
724 | struct bau_control *bau_tablesp; | 801 | struct bau_control *bau_tablesp; |
725 | 802 | ||
803 | node = blade_to_first_node(blade); | ||
726 | bau_tablesp = uv_table_bases_init(blade, node); | 804 | bau_tablesp = uv_table_bases_init(blade, node); |
727 | pnode = uv_blade_to_pnode(blade); | 805 | pnode = uv_blade_to_pnode(blade); |
728 | adp = uv_activation_descriptor_init(node, pnode); | 806 | adp = uv_activation_descriptor_init(node, pnode); |
729 | pqp = uv_payload_queue_init(node, pnode, bau_tablesp); | 807 | pqp = uv_payload_queue_init(node, pnode, bau_tablesp); |
730 | uv_table_bases_finish(blade, node, cur_cpu, bau_tablesp, adp); | 808 | uv_table_bases_finish(blade, bau_tablesp, adp); |
731 | /* | 809 | /* |
732 | * the below initialization can't be in firmware because the | 810 | * the below initialization can't be in firmware because the |
733 | * messaging IRQ will be determined by the OS | 811 | * messaging IRQ will be determined by the OS |
734 | */ | 812 | */ |
735 | apicid = per_cpu(x86_cpu_to_apicid, cur_cpu); | 813 | apicid = blade_to_first_apicid(blade); |
736 | pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG); | 814 | pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG); |
737 | if ((pa & 0xff) != UV_BAU_MESSAGE) { | 815 | if ((pa & 0xff) != UV_BAU_MESSAGE) { |
738 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, | 816 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, |
@@ -747,40 +825,34 @@ static int __init uv_init_blade(int blade, int node, int cur_cpu) | |||
747 | static int __init uv_bau_init(void) | 825 | static int __init uv_bau_init(void) |
748 | { | 826 | { |
749 | int blade; | 827 | int blade; |
750 | int node; | ||
751 | int nblades; | 828 | int nblades; |
752 | int last_blade; | ||
753 | int cur_cpu; | 829 | int cur_cpu; |
754 | 830 | ||
755 | if (!is_uv_system()) | 831 | if (!is_uv_system()) |
756 | return 0; | 832 | return 0; |
757 | 833 | ||
834 | for_each_possible_cpu(cur_cpu) | ||
835 | alloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), | ||
836 | GFP_KERNEL, cpu_to_node(cur_cpu)); | ||
837 | |||
758 | uv_bau_retry_limit = 1; | 838 | uv_bau_retry_limit = 1; |
759 | uv_nshift = uv_hub_info->n_val; | 839 | uv_nshift = uv_hub_info->n_val; |
760 | uv_mmask = (1UL << uv_hub_info->n_val) - 1; | 840 | uv_mmask = (1UL << uv_hub_info->n_val) - 1; |
761 | nblades = 0; | 841 | nblades = uv_num_possible_blades(); |
762 | last_blade = -1; | 842 | |
763 | cur_cpu = 0; | ||
764 | for_each_online_node(node) { | ||
765 | blade = uv_node_to_blade_id(node); | ||
766 | if (blade == last_blade) | ||
767 | continue; | ||
768 | last_blade = blade; | ||
769 | nblades++; | ||
770 | } | ||
771 | uv_bau_table_bases = (struct bau_control **) | 843 | uv_bau_table_bases = (struct bau_control **) |
772 | kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL); | 844 | kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL); |
773 | BUG_ON(!uv_bau_table_bases); | 845 | BUG_ON(!uv_bau_table_bases); |
774 | 846 | ||
775 | last_blade = -1; | 847 | uv_partition_base_pnode = 0x7fffffff; |
776 | for_each_online_node(node) { | 848 | for (blade = 0; blade < nblades; blade++) |
777 | blade = uv_node_to_blade_id(node); | 849 | if (uv_blade_nr_possible_cpus(blade) && |
778 | if (blade == last_blade) | 850 | (uv_blade_to_pnode(blade) < uv_partition_base_pnode)) |
779 | continue; | 851 | uv_partition_base_pnode = uv_blade_to_pnode(blade); |
780 | last_blade = blade; | 852 | for (blade = 0; blade < nblades; blade++) |
781 | uv_init_blade(blade, node, cur_cpu); | 853 | if (uv_blade_nr_possible_cpus(blade)) |
782 | cur_cpu += uv_blade_nr_possible_cpus(blade); | 854 | uv_init_blade(blade); |
783 | } | 855 | |
784 | alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1); | 856 | alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1); |
785 | uv_enable_timeouts(); | 857 | uv_enable_timeouts(); |
786 | 858 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 462b9ba67e92..7a567ebe6361 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -17,20 +17,21 @@ | |||
17 | #include <asm/delay.h> | 17 | #include <asm/delay.h> |
18 | #include <asm/hypervisor.h> | 18 | #include <asm/hypervisor.h> |
19 | 19 | ||
20 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ | 20 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ |
21 | EXPORT_SYMBOL(cpu_khz); | 21 | EXPORT_SYMBOL(cpu_khz); |
22 | unsigned int tsc_khz; | 22 | |
23 | unsigned int __read_mostly tsc_khz; | ||
23 | EXPORT_SYMBOL(tsc_khz); | 24 | EXPORT_SYMBOL(tsc_khz); |
24 | 25 | ||
25 | /* | 26 | /* |
26 | * TSC can be unstable due to cpufreq or due to unsynced TSCs | 27 | * TSC can be unstable due to cpufreq or due to unsynced TSCs |
27 | */ | 28 | */ |
28 | static int tsc_unstable; | 29 | static int __read_mostly tsc_unstable; |
29 | 30 | ||
30 | /* native_sched_clock() is called before tsc_init(), so | 31 | /* native_sched_clock() is called before tsc_init(), so |
31 | we must start with the TSC soft disabled to prevent | 32 | we must start with the TSC soft disabled to prevent |
32 | erroneous rdtsc usage on !cpu_has_tsc processors */ | 33 | erroneous rdtsc usage on !cpu_has_tsc processors */ |
33 | static int tsc_disabled = -1; | 34 | static int __read_mostly tsc_disabled = -1; |
34 | 35 | ||
35 | static int tsc_clocksource_reliable; | 36 | static int tsc_clocksource_reliable; |
36 | /* | 37 | /* |
@@ -543,8 +544,6 @@ unsigned long native_calibrate_tsc(void) | |||
543 | return tsc_pit_min; | 544 | return tsc_pit_min; |
544 | } | 545 | } |
545 | 546 | ||
546 | #ifdef CONFIG_X86_32 | ||
547 | /* Only called from the Powernow K7 cpu freq driver */ | ||
548 | int recalibrate_cpu_khz(void) | 547 | int recalibrate_cpu_khz(void) |
549 | { | 548 | { |
550 | #ifndef CONFIG_SMP | 549 | #ifndef CONFIG_SMP |
@@ -566,7 +565,6 @@ int recalibrate_cpu_khz(void) | |||
566 | 565 | ||
567 | EXPORT_SYMBOL(recalibrate_cpu_khz); | 566 | EXPORT_SYMBOL(recalibrate_cpu_khz); |
568 | 567 | ||
569 | #endif /* CONFIG_X86_32 */ | ||
570 | 568 | ||
571 | /* Accelerators for sched_clock() | 569 | /* Accelerators for sched_clock() |
572 | * convert from cycles(64bits) => nanoseconds (64bits) | 570 | * convert from cycles(64bits) => nanoseconds (64bits) |
diff --git a/arch/x86/kernel/uv_sysfs.c b/arch/x86/kernel/uv_sysfs.c index 67f9b9dbf800..36afb98675a4 100644 --- a/arch/x86/kernel/uv_sysfs.c +++ b/arch/x86/kernel/uv_sysfs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/sysdev.h> | 22 | #include <linux/sysdev.h> |
23 | #include <asm/uv/bios.h> | 23 | #include <asm/uv/bios.h> |
24 | #include <asm/uv/uv.h> | ||
24 | 25 | ||
25 | struct kobject *sgi_uv_kobj; | 26 | struct kobject *sgi_uv_kobj; |
26 | 27 | ||
@@ -47,6 +48,9 @@ static int __init sgi_uv_sysfs_init(void) | |||
47 | { | 48 | { |
48 | unsigned long ret; | 49 | unsigned long ret; |
49 | 50 | ||
51 | if (!is_uv_system()) | ||
52 | return -ENODEV; | ||
53 | |||
50 | if (!sgi_uv_kobj) | 54 | if (!sgi_uv_kobj) |
51 | sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj); | 55 | sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj); |
52 | if (!sgi_uv_kobj) { | 56 | if (!sgi_uv_kobj) { |
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 33a788d5879c..d303369a7bad 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c | |||
@@ -202,7 +202,6 @@ static struct irqaction vmi_clock_action = { | |||
202 | .name = "vmi-timer", | 202 | .name = "vmi-timer", |
203 | .handler = vmi_timer_interrupt, | 203 | .handler = vmi_timer_interrupt, |
204 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, | 204 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, |
205 | .mask = CPU_MASK_ALL, | ||
206 | }; | 205 | }; |
207 | 206 | ||
208 | static void __devinit vmi_time_init_clockevent(void) | 207 | static void __devinit vmi_time_init_clockevent(void) |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 74de562812cc..a1d804bcd483 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/paravirt.h> | 22 | #include <asm/paravirt.h> |
23 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
24 | 24 | ||
25 | #ifdef CONFIG_PARAVIRT | 25 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT |
26 | /* | 26 | /* |
27 | * Interrupt control on vSMPowered systems: | 27 | * Interrupt control on vSMPowered systems: |
28 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' | 28 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' |
@@ -114,6 +114,7 @@ static void __init set_vsmp_pv_ops(void) | |||
114 | } | 114 | } |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | #ifdef CONFIG_PCI | ||
117 | static int is_vsmp = -1; | 118 | static int is_vsmp = -1; |
118 | 119 | ||
119 | static void __init detect_vsmp_box(void) | 120 | static void __init detect_vsmp_box(void) |
@@ -139,6 +140,15 @@ int is_vsmp_box(void) | |||
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
143 | #else | ||
144 | static void __init detect_vsmp_box(void) | ||
145 | { | ||
146 | } | ||
147 | int is_vsmp_box(void) | ||
148 | { | ||
149 | return 0; | ||
150 | } | ||
151 | #endif | ||
142 | void __init vsmp_init(void) | 152 | void __init vsmp_init(void) |
143 | { | 153 | { |
144 | detect_vsmp_box(); | 154 | detect_vsmp_box(); |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 2b54fe002e94..0a5b04aa98f1 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -324,7 +324,7 @@ void __ref xsave_cntxt_init(void) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * for now OS knows only about FP/SSE | 327 | * Support only the state known to OS. |
328 | */ | 328 | */ |
329 | pcntxt_mask = pcntxt_mask & XCNTXT_MASK; | 329 | pcntxt_mask = pcntxt_mask & XCNTXT_MASK; |
330 | xsave_init(); | 330 | xsave_init(); |