aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 14:26:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 14:26:33 -0400
commitec73adba51b4dae11134f7e6ffc84feade9f15fa (patch)
tree59b1d2c90f960d69fd247289fcd59fc213484a70 /arch
parentcc556c5c92a45763e23015a31efb27005a6132fa (diff)
parent2a61812af2e564cba2c8170cf96e1c823210f619 (diff)
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: add X86_FEATURE_XMM4_2 definitions x86: fix cpufreq + sched_clock() regression x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3 x86: do not enable TSC notifier if we don't need it x86 MCE: Fix CPU hotplug problem with multiple multicore AMD CPUs x86: fix: make PCI ECS for AMD CPUs hotplug capable x86: fix: do not run code in amd_bus.c on non-AMD CPUs
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c5
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c18
-rw-r--r--arch/x86/kernel/tsc.c6
-rw-r--r--arch/x86/pci/amd_bus.c52
-rw-r--r--arch/x86/pci/i386.c78
5 files changed, 139 insertions, 20 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 65a339678ece..726a5fcdf341 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = {
759}; 759};
760 760
761DEFINE_PER_CPU(struct sys_device, device_mce); 761DEFINE_PER_CPU(struct sys_device, device_mce);
762void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinitdata;
762 763
763/* Why are there no generic functions for this? */ 764/* Why are there no generic functions for this? */
764#define ACCESSOR(name, var, start) \ 765#define ACCESSOR(name, var, start) \
@@ -883,9 +884,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
883 case CPU_ONLINE: 884 case CPU_ONLINE:
884 case CPU_ONLINE_FROZEN: 885 case CPU_ONLINE_FROZEN:
885 mce_create_device(cpu); 886 mce_create_device(cpu);
887 if (threshold_cpu_callback)
888 threshold_cpu_callback(action, cpu);
886 break; 889 break;
887 case CPU_DEAD: 890 case CPU_DEAD:
888 case CPU_DEAD_FROZEN: 891 case CPU_DEAD_FROZEN:
892 if (threshold_cpu_callback)
893 threshold_cpu_callback(action, cpu);
889 mce_remove_device(cpu); 894 mce_remove_device(cpu);
890 break; 895 break;
891 } 896 }
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index 88736cadbaa6..5eb390a4b2e9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
628 deallocate_threshold_block(cpu, bank); 628 deallocate_threshold_block(cpu, bank);
629 629
630free_out: 630free_out:
631 kobject_del(b->kobj);
631 kobject_put(b->kobj); 632 kobject_put(b->kobj);
632 kfree(b); 633 kfree(b);
633 per_cpu(threshold_banks, cpu)[bank] = NULL; 634 per_cpu(threshold_banks, cpu)[bank] = NULL;
@@ -645,14 +646,11 @@ static void threshold_remove_device(unsigned int cpu)
645} 646}
646 647
647/* get notified when a cpu comes on/off */ 648/* get notified when a cpu comes on/off */
648static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, 649static void __cpuinit amd_64_threshold_cpu_callback(unsigned long action,
649 unsigned long action, void *hcpu) 650 unsigned int cpu)
650{ 651{
651 /* cpu was unsigned int to begin with */
652 unsigned int cpu = (unsigned long)hcpu;
653
654 if (cpu >= NR_CPUS) 652 if (cpu >= NR_CPUS)
655 goto out; 653 return;
656 654
657 switch (action) { 655 switch (action) {
658 case CPU_ONLINE: 656 case CPU_ONLINE:
@@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
666 default: 664 default:
667 break; 665 break;
668 } 666 }
669 out:
670 return NOTIFY_OK;
671} 667}
672 668
673static struct notifier_block threshold_cpu_notifier __cpuinitdata = {
674 .notifier_call = threshold_cpu_callback,
675};
676
677static __init int threshold_init_device(void) 669static __init int threshold_init_device(void)
678{ 670{
679 unsigned lcpu = 0; 671 unsigned lcpu = 0;
@@ -684,7 +676,7 @@ static __init int threshold_init_device(void)
684 if (err) 676 if (err)
685 return err; 677 return err;
686 } 678 }
687 register_hotcpu_notifier(&threshold_cpu_notifier); 679 threshold_cpu_callback = amd_64_threshold_cpu_callback;
688 return 0; 680 return 0;
689} 681}
690 682
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46af71676738..8e786b0d665a 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -314,7 +314,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
314 mark_tsc_unstable("cpufreq changes"); 314 mark_tsc_unstable("cpufreq changes");
315 } 315 }
316 316
317 set_cyc2ns_scale(tsc_khz_ref, freq->cpu); 317 set_cyc2ns_scale(tsc_khz, freq->cpu);
318 318
319 return 0; 319 return 0;
320} 320}
@@ -325,6 +325,10 @@ static struct notifier_block time_cpufreq_notifier_block = {
325 325
326static int __init cpufreq_tsc(void) 326static int __init cpufreq_tsc(void)
327{ 327{
328 if (!cpu_has_tsc)
329 return 0;
330 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
331 return 0;
328 cpufreq_register_notifier(&time_cpufreq_notifier_block, 332 cpufreq_register_notifier(&time_cpufreq_notifier_block,
329 CPUFREQ_TRANSITION_NOTIFIER); 333 CPUFREQ_TRANSITION_NOTIFIER);
330 return 0; 334 return 0;
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index dbf532369711..6a0fca78c362 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -1,6 +1,7 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/pci.h> 2#include <linux/pci.h>
3#include <linux/topology.h> 3#include <linux/topology.h>
4#include <linux/cpu.h>
4#include "pci.h" 5#include "pci.h"
5 6
6#ifdef CONFIG_X86_64 7#ifdef CONFIG_X86_64
@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void)
555 return 0; 556 return 0;
556} 557}
557 558
558postcore_initcall(early_fill_mp_bus_info); 559#else /* !CONFIG_X86_64 */
559 560
560#endif 561static int __init early_fill_mp_bus_info(void) { return 0; }
562
563#endif /* !CONFIG_X86_64 */
561 564
562/* common 32/64 bit code */ 565/* common 32/64 bit code */
563 566
564#define ENABLE_CF8_EXT_CFG (1ULL << 46) 567#define ENABLE_CF8_EXT_CFG (1ULL << 46)
565 568
566static void enable_pci_io_ecs_per_cpu(void *unused) 569static void enable_pci_io_ecs(void *unused)
567{ 570{
568 u64 reg; 571 u64 reg;
569 rdmsrl(MSR_AMD64_NB_CFG, reg); 572 rdmsrl(MSR_AMD64_NB_CFG, reg);
@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused)
573 } 576 }
574} 577}
575 578
576static int __init enable_pci_io_ecs(void) 579static int __cpuinit amd_cpu_notify(struct notifier_block *self,
580 unsigned long action, void *hcpu)
577{ 581{
582 int cpu = (long)hcpu;
583 switch(action) {
584 case CPU_ONLINE:
585 case CPU_ONLINE_FROZEN:
586 smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
587 break;
588 default:
589 break;
590 }
591 return NOTIFY_OK;
592}
593
594static struct notifier_block __cpuinitdata amd_cpu_notifier = {
595 .notifier_call = amd_cpu_notify,
596};
597
598static int __init pci_io_ecs_init(void)
599{
600 int cpu;
601
578 /* assume all cpus from fam10h have IO ECS */ 602 /* assume all cpus from fam10h have IO ECS */
579 if (boot_cpu_data.x86 < 0x10) 603 if (boot_cpu_data.x86 < 0x10)
580 return 0; 604 return 0;
581 on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1); 605
606 register_cpu_notifier(&amd_cpu_notifier);
607 for_each_online_cpu(cpu)
608 amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
609 (void *)(long)cpu);
582 pci_probe |= PCI_HAS_IO_ECS; 610 pci_probe |= PCI_HAS_IO_ECS;
611
612 return 0;
613}
614
615static int __init amd_postcore_init(void)
616{
617 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
618 return 0;
619
620 early_fill_mp_bus_info();
621 pci_io_ecs_init();
622
583 return 0; 623 return 0;
584} 624}
585 625
586postcore_initcall(enable_pci_io_ecs); 626postcore_initcall(amd_postcore_init);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 5807d1bc73f7..d765da913842 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -31,8 +31,11 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/bootmem.h> 33#include <linux/bootmem.h>
34#include <linux/acpi.h>
34 35
35#include <asm/pat.h> 36#include <asm/pat.h>
37#include <asm/hpet.h>
38#include <asm/io_apic.h>
36 39
37#include "pci.h" 40#include "pci.h"
38 41
@@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res,
77} 80}
78EXPORT_SYMBOL(pcibios_align_resource); 81EXPORT_SYMBOL(pcibios_align_resource);
79 82
83static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
84{
85 unsigned long base;
86 unsigned long size;
87 int i;
88
89 base = res->start;
90 size = (res->start == 0 && res->end == res->start) ? 0 :
91 (res->end - res->start + 1);
92
93 if (!base || !size)
94 return 0;
95
96#ifdef CONFIG_HPET_TIMER
97 /* for hpet */
98 if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
99 dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
100 base, base + size - 1);
101 return 1;
102 }
103#endif
104
105#ifdef CONFIG_X86_IO_APIC
106 for (i = 0; i < nr_ioapics; i++) {
107 unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;
108
109 if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
110 dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
111 base, base + size - 1);
112 return 1;
113 }
114 }
115#endif
116
117#ifdef CONFIG_PCI_MMCONFIG
118 for (i = 0; i < pci_mmcfg_config_num; i++) {
119 unsigned long addr;
120
121 addr = pci_mmcfg_config[i].address;
122 if (base == addr && (res->flags & IORESOURCE_MEM)) {
123 dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
124 base, base + size - 1);
125 return 1;
126 }
127 }
128#endif
129
130 return 0;
131}
132
133static int check_platform(struct pci_dev *dev, struct resource *res)
134{
135 struct resource *root = NULL;
136
137 /*
138 * forcibly insert it into the
139 * resource tree
140 */
141 if (res->flags & IORESOURCE_MEM)
142 root = &iomem_resource;
143 else if (res->flags & IORESOURCE_IO)
144 root = &ioport_resource;
145
146 if (root && check_res_with_valid(dev, res)) {
147 insert_resource(root, res);
148
149 return 1;
150 }
151
152 return 0;
153}
80/* 154/*
81 * Handle resources of PCI devices. If the world were perfect, we could 155 * Handle resources of PCI devices. If the world were perfect, we could
82 * just allocate all the resource regions and do nothing more. It isn't. 156 * just allocate all the resource regions and do nothing more. It isn't.
@@ -128,6 +202,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
128 pr = pci_find_parent_resource(dev, r); 202 pr = pci_find_parent_resource(dev, r);
129 if (!r->start || !pr || 203 if (!r->start || !pr ||
130 request_resource(pr, r) < 0) { 204 request_resource(pr, r) < 0) {
205 if (check_platform(dev, r))
206 continue;
131 dev_err(&dev->dev, "BAR %d: can't " 207 dev_err(&dev->dev, "BAR %d: can't "
132 "allocate resource\n", idx); 208 "allocate resource\n", idx);
133 /* 209 /*
@@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass)
171 r->flags, disabled, pass); 247 r->flags, disabled, pass);
172 pr = pci_find_parent_resource(dev, r); 248 pr = pci_find_parent_resource(dev, r);
173 if (!pr || request_resource(pr, r) < 0) { 249 if (!pr || request_resource(pr, r) < 0) {
250 if (check_platform(dev, r))
251 continue;
174 dev_err(&dev->dev, "BAR %d: can't " 252 dev_err(&dev->dev, "BAR %d: can't "
175 "allocate resource\n", idx); 253 "allocate resource\n", idx);
176 /* We'll assign a new address later */ 254 /* We'll assign a new address later */