From b499f42b943332ba67e4b6dfbcd8b2c3481558d7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:41 +0100 Subject: [PATCH] --- yaml --- r: 80162 b: refs/heads/master c: ddb25f9ac1c4b4f9ba0bdacd7850a921a0c6886c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/acpi/processor_idle.c | 32 +++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ab5d6fd6f6db..0579e9330493 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 32c7553f824d0d76771404f0e11d6059f82e8de7 +refs/heads/master: ddb25f9ac1c4b4f9ba0bdacd7850a921a0c6886c diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 0721a8183c89..eb1f82f79153 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -357,6 +357,26 @@ int acpi_processor_resume(struct acpi_device * device) return 0; } +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +static int tsc_halts_in_c(int state) +{ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + /* + * AMD Fam10h TSC will tick in all + * C/P/S0/S1 states when this bit is set. + */ + if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) + return 0; + /*FALL THROUGH*/ + case X86_VENDOR_INTEL: + /* Several cases known where TSC halts in C2 too */ + default: + return state > ACPI_STATE_C1; + } +} +#endif + #ifndef CONFIG_CPU_IDLE static void acpi_processor_idle(void) { @@ -516,7 +536,8 @@ static void acpi_processor_idle(void) #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) /* TSC halts in C2, so notify users */ - mark_tsc_unstable("possible TSC halt in C2"); + if (tsc_halts_in_c(ACPI_STATE_C2)) + mark_tsc_unstable("possible TSC halt in C2"); #endif /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2); @@ -580,7 +601,8 @@ static void acpi_processor_idle(void) #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) /* TSC halts in C3, so notify users */ - mark_tsc_unstable("TSC halts in C3"); + if (tsc_halts_in_c(ACPI_STATE_C3)) + mark_tsc_unstable("TSC halts in C3"); #endif /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2); @@ -1445,7 +1467,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle");; + if (tsc_halts_in_c(cx->type)) + mark_tsc_unstable("TSC halts in idle");; #endif sleep_ticks = ticks_elapsed(t1, t2); @@ -1556,7 +1579,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle"); + if (tsc_halts_in_c(ACPI_STATE_C3)) + mark_tsc_unstable("TSC halts in idle"); #endif sleep_ticks = ticks_elapsed(t1, t2); /* Tell the scheduler how much we idled: */