|
@@ -525,42 +525,6 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
|
|
|
return (edx & MWAIT_EDX_C1);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
|
|
|
- * For more information see
|
|
|
- * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
|
|
|
- * - Erratum #365 for family 0x11 (not affected because C1e not in use)
|
|
|
- */
|
|
|
-static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
|
|
|
-{
|
|
|
- u64 val;
|
|
|
- if (c->x86_vendor != X86_VENDOR_AMD)
|
|
|
- goto no_c1e_idle;
|
|
|
-
|
|
|
- /* Family 0x0f models < rev F do not have C1E */
|
|
|
- if (c->x86 == 0x0F && c->x86_model >= 0x40)
|
|
|
- return 1;
|
|
|
-
|
|
|
- if (c->x86 == 0x10) {
|
|
|
- /*
|
|
|
- * check OSVW bit for CPUs that are not affected
|
|
|
- * by erratum #400
|
|
|
- */
|
|
|
- if (cpu_has(c, X86_FEATURE_OSVW)) {
|
|
|
- rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
|
|
|
- if (val >= 2) {
|
|
|
- rdmsrl(MSR_AMD64_OSVW_STATUS, val);
|
|
|
- if (!(val & BIT(1)))
|
|
|
- goto no_c1e_idle;
|
|
|
- }
|
|
|
- }
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
-no_c1e_idle:
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static cpumask_var_t c1e_mask;
|
|
|
static int c1e_detected;
|
|
|
|
|
@@ -638,7 +602,8 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
|
|
|
*/
|
|
|
printk(KERN_INFO "using mwait in idle threads.\n");
|
|
|
pm_idle = mwait_idle;
|
|
|
- } else if (check_c1e_idle(c)) {
|
|
|
+ } else if (cpu_has_amd_erratum(amd_erratum_400)) {
|
|
|
+ /* E400: APIC timer interrupt does not wake up CPU from C1e */
|
|
|
printk(KERN_INFO "using C1E aware idle routine\n");
|
|
|
pm_idle = c1e_idle;
|
|
|
} else
|