diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2009-04-08 06:31:23 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-05-28 12:24:10 -0400 |
commit | 6cc6f3ebd19fea722c19630af5ad68af7f51d493 (patch) | |
tree | eaec2731bc00ca227adaf166e22e391bdb124f39 | |
parent | 1cb2a8e1767ab60370ecce90654c0f281c602d95 (diff) |
x86, mce: unify Intel thermal init, prepare
Prepare for unification, make two intel_init_thermal equal.
[ Impact: cleanup ]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/p4.c | 44 |
2 files changed, 40 insertions, 39 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index cef3ee30744b..b85d0c107c84 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c | |||
@@ -34,21 +34,22 @@ asmlinkage void smp_thermal_interrupt(void) | |||
34 | irq_exit(); | 34 | irq_exit(); |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline void intel_set_thermal_handler(void) { } | ||
38 | |||
37 | static void intel_init_thermal(struct cpuinfo_x86 *c) | 39 | static void intel_init_thermal(struct cpuinfo_x86 *c) |
38 | { | 40 | { |
39 | u32 l, h; | ||
40 | int tm2 = 0; | ||
41 | unsigned int cpu = smp_processor_id(); | 41 | unsigned int cpu = smp_processor_id(); |
42 | int tm2 = 0; | ||
43 | u32 l, h; | ||
42 | 44 | ||
43 | if (!cpu_has(c, X86_FEATURE_ACPI)) | 45 | /* Thermal monitoring depends on ACPI and clock modulation*/ |
44 | return; | 46 | if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC)) |
45 | |||
46 | if (!cpu_has(c, X86_FEATURE_ACC)) | ||
47 | return; | 47 | return; |
48 | 48 | ||
49 | /* first check if TM1 is already enabled by the BIOS, in which | 49 | /* |
50 | * case there might be some SMM goo which handles it, so we can't even | 50 | * First check if its enabled already, in which case there might |
51 | * put a handler since it might be delivered via SMI already. | 51 | * be some SMM goo which handles it, so we can't even put a handler |
52 | * since it might be delivered via SMI already: | ||
52 | */ | 53 | */ |
53 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); | 54 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); |
54 | h = apic_read(APIC_LVTTHMR); | 55 | h = apic_read(APIC_LVTTHMR); |
@@ -61,31 +62,35 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
61 | if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2)) | 62 | if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2)) |
62 | tm2 = 1; | 63 | tm2 = 1; |
63 | 64 | ||
65 | /* Check whether a vector already exists */ | ||
64 | if (h & APIC_VECTOR_MASK) { | 66 | if (h & APIC_VECTOR_MASK) { |
65 | printk(KERN_DEBUG | 67 | printk(KERN_DEBUG |
66 | "CPU%d: Thermal LVT vector (%#x) already " | 68 | "CPU%d: Thermal LVT vector (%#x) already installed\n", |
67 | "installed\n", cpu, (h & APIC_VECTOR_MASK)); | 69 | cpu, (h & APIC_VECTOR_MASK)); |
68 | return; | 70 | return; |
69 | } | 71 | } |
70 | 72 | ||
71 | h = THERMAL_APIC_VECTOR; | 73 | /* We'll mask the thermal vector in the lapic till we're ready: */ |
72 | h |= (APIC_DM_FIXED | APIC_LVT_MASKED); | 74 | h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED; |
73 | apic_write(APIC_LVTTHMR, h); | 75 | apic_write(APIC_LVTTHMR, h); |
74 | 76 | ||
75 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); | 77 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); |
76 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h); | 78 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h); |
77 | 79 | ||
80 | intel_set_thermal_handler(); | ||
81 | |||
78 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); | 82 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); |
79 | wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); | 83 | wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); |
80 | 84 | ||
85 | /* Unmask the thermal vector: */ | ||
81 | l = apic_read(APIC_LVTTHMR); | 86 | l = apic_read(APIC_LVTTHMR); |
82 | apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); | 87 | apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); |
88 | |||
83 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", | 89 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", |
84 | cpu, tm2 ? "TM2" : "TM1"); | 90 | cpu, tm2 ? "TM2" : "TM1"); |
85 | 91 | ||
86 | /* enable thermal throttle processing */ | 92 | /* enable thermal throttle processing */ |
87 | atomic_set(&therm_throt_en, 1); | 93 | atomic_set(&therm_throt_en, 1); |
88 | return; | ||
89 | } | 94 | } |
90 | 95 | ||
91 | /* | 96 | /* |
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index cb344aba479c..f70753a443bb 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c | |||
@@ -66,19 +66,21 @@ void smp_thermal_interrupt(struct pt_regs *regs) | |||
66 | irq_exit(); | 66 | irq_exit(); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void intel_set_thermal_handler(void) | ||
70 | { | ||
71 | vendor_thermal_interrupt = intel_thermal_interrupt; | ||
72 | } | ||
73 | |||
69 | /* P4/Xeon Thermal regulation detect and init: */ | 74 | /* P4/Xeon Thermal regulation detect and init: */ |
70 | static void intel_init_thermal(struct cpuinfo_x86 *c) | 75 | static void intel_init_thermal(struct cpuinfo_x86 *c) |
71 | { | 76 | { |
72 | unsigned int cpu = smp_processor_id(); | 77 | unsigned int cpu = smp_processor_id(); |
78 | int tm2 = 0; | ||
73 | u32 l, h; | 79 | u32 l, h; |
74 | 80 | ||
75 | /* Thermal monitoring: */ | 81 | /* Thermal monitoring depends on ACPI and clock modulation*/ |
76 | if (!cpu_has(c, X86_FEATURE_ACPI)) | 82 | if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC)) |
77 | return; /* -ENODEV */ | 83 | return; |
78 | |||
79 | /* Clock modulation: */ | ||
80 | if (!cpu_has(c, X86_FEATURE_ACC)) | ||
81 | return; /* -ENODEV */ | ||
82 | 84 | ||
83 | /* | 85 | /* |
84 | * First check if its enabled already, in which case there might | 86 | * First check if its enabled already, in which case there might |
@@ -90,35 +92,28 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
90 | if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { | 92 | if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { |
91 | printk(KERN_DEBUG | 93 | printk(KERN_DEBUG |
92 | "CPU%d: Thermal monitoring handled by SMI\n", cpu); | 94 | "CPU%d: Thermal monitoring handled by SMI\n", cpu); |
93 | 95 | return; | |
94 | return; /* -EBUSY */ | ||
95 | } | 96 | } |
96 | 97 | ||
97 | /* Check whether a vector already exists, temporarily masked? */ | 98 | if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2)) |
99 | tm2 = 1; | ||
100 | |||
101 | /* Check whether a vector already exists */ | ||
98 | if (h & APIC_VECTOR_MASK) { | 102 | if (h & APIC_VECTOR_MASK) { |
99 | printk(KERN_DEBUG | 103 | printk(KERN_DEBUG |
100 | "CPU%d: Thermal LVT vector (%#x) already installed\n", | 104 | "CPU%d: Thermal LVT vector (%#x) already installed\n", |
101 | cpu, (h & APIC_VECTOR_MASK)); | 105 | cpu, (h & APIC_VECTOR_MASK)); |
102 | 106 | return; | |
103 | return; /* -EBUSY */ | ||
104 | } | 107 | } |
105 | 108 | ||
106 | /* | ||
107 | * The temperature transition interrupt handler setup: | ||
108 | */ | ||
109 | |||
110 | /* Our delivery vector: */ | ||
111 | h = THERMAL_APIC_VECTOR; | ||
112 | |||
113 | /* We'll mask the thermal vector in the lapic till we're ready: */ | 109 | /* We'll mask the thermal vector in the lapic till we're ready: */ |
114 | h |= APIC_DM_FIXED | APIC_LVT_MASKED; | 110 | h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED; |
115 | apic_write(APIC_LVTTHMR, h); | 111 | apic_write(APIC_LVTTHMR, h); |
116 | 112 | ||
117 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); | 113 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); |
118 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h); | 114 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h); |
119 | 115 | ||
120 | /* Ok, we're good to go... */ | 116 | intel_set_thermal_handler(); |
121 | vendor_thermal_interrupt = intel_thermal_interrupt; | ||
122 | 117 | ||
123 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); | 118 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); |
124 | wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); | 119 | wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); |
@@ -127,7 +122,8 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
127 | l = apic_read(APIC_LVTTHMR); | 122 | l = apic_read(APIC_LVTTHMR); |
128 | apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); | 123 | apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); |
129 | 124 | ||
130 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); | 125 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", |
126 | cpu, tm2 ? "TM2" : "TM1"); | ||
131 | 127 | ||
132 | /* enable thermal throttle processing */ | 128 | /* enable thermal throttle processing */ |
133 | atomic_set(&therm_throt_en, 1); | 129 | atomic_set(&therm_throt_en, 1); |