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>

authored by Thomas Gleixner and committed by Ingo Molnar e17bcb43 167b1de3

+14 -5
+14 -5
drivers/acpi/processor_idle.c
··· 531 531 532 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 539 * disable bus master 535 540 * bm_check implies we need ARB_DIS 536 541 * !bm_check implies we need cache flush ··· 562 557 /* Get start time (ticks) */ 563 558 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 564 559 /* Invoke C3 */ 565 - acpi_state_timer_broadcast(pr, cx, 1); 566 560 /* Tell the scheduler that we are going deep-idle: */ 567 561 sched_clock_idle_sleep_event(); 568 562 acpi_cstate_enter(cx); ··· 1405 1401 if (acpi_idle_suspend) 1406 1402 return(acpi_idle_enter_c1(dev, state)); 1407 1403 1408 - if (pr->flags.bm_check) 1409 - acpi_idle_update_bm_rld(pr, cx); 1410 - 1411 1404 local_irq_disable(); 1412 1405 current_thread_info()->status &= ~TS_POLLING; 1413 1406 /* ··· 1419 1418 return 0; 1420 1419 } 1421 1420 1421 + /* 1422 + * Must be done before busmaster disable as we might need to 1423 + * access HPET ! 1424 + */ 1425 + acpi_state_timer_broadcast(pr, cx, 1); 1426 + 1427 + if (pr->flags.bm_check) 1428 + acpi_idle_update_bm_rld(pr, cx); 1429 + 1422 1430 if (cx->type == ACPI_STATE_C3) 1423 1431 ACPI_FLUSH_CPU_CACHE(); 1424 1432 1425 1433 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1426 1434 /* Tell the scheduler that we are going deep-idle: */ 1427 1435 sched_clock_idle_sleep_event(); 1428 - acpi_state_timer_broadcast(pr, cx, 1); 1429 1436 acpi_idle_do_entry(cx); 1430 1437 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1431 1438