diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-12-07 13:16:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-12-07 13:16:17 -0500 |
commit | e17bcb43a26a7111f851b5ff6d1258ecd355de75 (patch) | |
tree | 8e8f3fd329089270c3c6be06abca0ea650ce69b7 /drivers/acpi/processor_idle.c | |
parent | 167b1de3ee4e50d65a2bd0a2667c9cd48faf54f3 (diff) |
ACPI: move timer broadcast before busmaster disable
The timer broadcast code might access HPET, which should not be
accessed after the busmaster disable.
In acpi_idle_enter_simple() this change also prevents, that we modify
the busmaster state without going actually idle. This might leave the
ACPI bm state in a stale state, when we leave the function early in
the need_resched() check.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b1fbee3f7fe1..2fe34cc73c13 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -531,6 +531,11 @@ static void acpi_processor_idle(void) | |||
531 | 531 | ||
532 | case ACPI_STATE_C3: | 532 | case ACPI_STATE_C3: |
533 | /* | 533 | /* |
534 | * Must be done before busmaster disable as we might | ||
535 | * need to access HPET ! | ||
536 | */ | ||
537 | acpi_state_timer_broadcast(pr, cx, 1); | ||
538 | /* | ||
534 | * disable bus master | 539 | * disable bus master |
535 | * bm_check implies we need ARB_DIS | 540 | * bm_check implies we need ARB_DIS |
536 | * !bm_check implies we need cache flush | 541 | * !bm_check implies we need cache flush |
@@ -557,7 +562,6 @@ static void acpi_processor_idle(void) | |||
557 | /* Get start time (ticks) */ | 562 | /* Get start time (ticks) */ |
558 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 563 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
559 | /* Invoke C3 */ | 564 | /* Invoke C3 */ |
560 | acpi_state_timer_broadcast(pr, cx, 1); | ||
561 | /* Tell the scheduler that we are going deep-idle: */ | 565 | /* Tell the scheduler that we are going deep-idle: */ |
562 | sched_clock_idle_sleep_event(); | 566 | sched_clock_idle_sleep_event(); |
563 | acpi_cstate_enter(cx); | 567 | acpi_cstate_enter(cx); |
@@ -1401,9 +1405,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1401 | if (acpi_idle_suspend) | 1405 | if (acpi_idle_suspend) |
1402 | return(acpi_idle_enter_c1(dev, state)); | 1406 | return(acpi_idle_enter_c1(dev, state)); |
1403 | 1407 | ||
1404 | if (pr->flags.bm_check) | ||
1405 | acpi_idle_update_bm_rld(pr, cx); | ||
1406 | |||
1407 | local_irq_disable(); | 1408 | local_irq_disable(); |
1408 | current_thread_info()->status &= ~TS_POLLING; | 1409 | current_thread_info()->status &= ~TS_POLLING; |
1409 | /* | 1410 | /* |
@@ -1418,13 +1419,21 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1418 | return 0; | 1419 | return 0; |
1419 | } | 1420 | } |
1420 | 1421 | ||
1422 | /* | ||
1423 | * Must be done before busmaster disable as we might need to | ||
1424 | * access HPET ! | ||
1425 | */ | ||
1426 | acpi_state_timer_broadcast(pr, cx, 1); | ||
1427 | |||
1428 | if (pr->flags.bm_check) | ||
1429 | acpi_idle_update_bm_rld(pr, cx); | ||
1430 | |||
1421 | if (cx->type == ACPI_STATE_C3) | 1431 | if (cx->type == ACPI_STATE_C3) |
1422 | ACPI_FLUSH_CPU_CACHE(); | 1432 | ACPI_FLUSH_CPU_CACHE(); |
1423 | 1433 | ||
1424 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1434 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1425 | /* Tell the scheduler that we are going deep-idle: */ | 1435 | /* Tell the scheduler that we are going deep-idle: */ |
1426 | sched_clock_idle_sleep_event(); | 1436 | sched_clock_idle_sleep_event(); |
1427 | acpi_state_timer_broadcast(pr, cx, 1); | ||
1428 | acpi_idle_do_entry(cx); | 1437 | acpi_idle_do_entry(cx); |
1429 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1438 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1430 | 1439 | ||