aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2235f4e02d26..eb1f82f79153 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -357,6 +357,26 @@ int acpi_processor_resume(struct acpi_device * device)
357 return 0; 357 return 0;
358} 358}
359 359
360#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
361static int tsc_halts_in_c(int state)
362{
363 switch (boot_cpu_data.x86_vendor) {
364 case X86_VENDOR_AMD:
365 /*
366 * AMD Fam10h TSC will tick in all
367 * C/P/S0/S1 states when this bit is set.
368 */
369 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
370 return 0;
371 /*FALL THROUGH*/
372 case X86_VENDOR_INTEL:
373 /* Several cases known where TSC halts in C2 too */
374 default:
375 return state > ACPI_STATE_C1;
376 }
377}
378#endif
379
360#ifndef CONFIG_CPU_IDLE 380#ifndef CONFIG_CPU_IDLE
361static void acpi_processor_idle(void) 381static void acpi_processor_idle(void)
362{ 382{
@@ -516,7 +536,8 @@ static void acpi_processor_idle(void)
516 536
517#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 537#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
518 /* TSC halts in C2, so notify users */ 538 /* TSC halts in C2, so notify users */
519 mark_tsc_unstable("possible TSC halt in C2"); 539 if (tsc_halts_in_c(ACPI_STATE_C2))
540 mark_tsc_unstable("possible TSC halt in C2");
520#endif 541#endif
521 /* Compute time (ticks) that we were actually asleep */ 542 /* Compute time (ticks) that we were actually asleep */
522 sleep_ticks = ticks_elapsed(t1, t2); 543 sleep_ticks = ticks_elapsed(t1, t2);
@@ -534,6 +555,7 @@ static void acpi_processor_idle(void)
534 break; 555 break;
535 556
536 case ACPI_STATE_C3: 557 case ACPI_STATE_C3:
558 acpi_unlazy_tlb(smp_processor_id());
537 /* 559 /*
538 * Must be done before busmaster disable as we might 560 * Must be done before busmaster disable as we might
539 * need to access HPET ! 561 * need to access HPET !
@@ -579,7 +601,8 @@ static void acpi_processor_idle(void)
579 601
580#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 602#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
581 /* TSC halts in C3, so notify users */ 603 /* TSC halts in C3, so notify users */
582 mark_tsc_unstable("TSC halts in C3"); 604 if (tsc_halts_in_c(ACPI_STATE_C3))
605 mark_tsc_unstable("TSC halts in C3");
583#endif 606#endif
584 /* Compute time (ticks) that we were actually asleep */ 607 /* Compute time (ticks) that we were actually asleep */
585 sleep_ticks = ticks_elapsed(t1, t2); 608 sleep_ticks = ticks_elapsed(t1, t2);
@@ -1423,6 +1446,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1423 return 0; 1446 return 0;
1424 } 1447 }
1425 1448
1449 acpi_unlazy_tlb(smp_processor_id());
1426 /* 1450 /*
1427 * Must be done before busmaster disable as we might need to 1451 * Must be done before busmaster disable as we might need to
1428 * access HPET ! 1452 * access HPET !
@@ -1443,7 +1467,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1443 1467
1444#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1468#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1445 /* TSC could halt in idle, so notify users */ 1469 /* TSC could halt in idle, so notify users */
1446 mark_tsc_unstable("TSC halts in idle");; 1470 if (tsc_halts_in_c(cx->type))
1471 mark_tsc_unstable("TSC halts in idle");;
1447#endif 1472#endif
1448 sleep_ticks = ticks_elapsed(t1, t2); 1473 sleep_ticks = ticks_elapsed(t1, t2);
1449 1474
@@ -1554,7 +1579,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1554 1579
1555#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1580#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1556 /* TSC could halt in idle, so notify users */ 1581 /* TSC could halt in idle, so notify users */
1557 mark_tsc_unstable("TSC halts in idle"); 1582 if (tsc_halts_in_c(ACPI_STATE_C3))
1583 mark_tsc_unstable("TSC halts in idle");
1558#endif 1584#endif
1559 sleep_ticks = ticks_elapsed(t1, t2); 1585 sleep_ticks = ticks_elapsed(t1, t2);
1560 /* Tell the scheduler how much we idled: */ 1586 /* Tell the scheduler how much we idled: */