diff options
author | venkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com> | 2008-01-31 20:35:03 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-02-07 02:11:14 -0500 |
commit | 2e906655baf1c6f6fccd212fc9e6499dc6928b80 (patch) | |
tree | c9d3d71db721f725e6333228efaba4443e878e70 /drivers/acpi/processor_idle.c | |
parent | 488b5ec871191359b9b79262a3d48456dae7ea5f (diff) |
ACPI: idle: Fix acpi_safe_halt usages and interrupt enabling/disabling
acpi_safe_halt() needs interrupts to be disabled for atomic
need_resched check and safe halt. Otherwise we may miss an
interrupt and go into halt.
acpi_safe_halt() also does not enable interrupts on all return paths.
So the callers should handle enable and disable interrupts around it.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 199ea2146153..106a22948aa9 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -201,6 +201,10 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) | |||
201 | return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); | 201 | return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); |
202 | } | 202 | } |
203 | 203 | ||
204 | /* | ||
205 | * Callers should disable interrupts before the call and enable | ||
206 | * interrupts after return. | ||
207 | */ | ||
204 | static void acpi_safe_halt(void) | 208 | static void acpi_safe_halt(void) |
205 | { | 209 | { |
206 | current_thread_info()->status &= ~TS_POLLING; | 210 | current_thread_info()->status &= ~TS_POLLING; |
@@ -413,6 +417,8 @@ static void acpi_processor_idle(void) | |||
413 | pm_idle_save(); | 417 | pm_idle_save(); |
414 | else | 418 | else |
415 | acpi_safe_halt(); | 419 | acpi_safe_halt(); |
420 | |||
421 | local_irq_enable(); | ||
416 | return; | 422 | return; |
417 | } | 423 | } |
418 | 424 | ||
@@ -521,6 +527,7 @@ static void acpi_processor_idle(void) | |||
521 | * skew otherwise. | 527 | * skew otherwise. |
522 | */ | 528 | */ |
523 | sleep_ticks = 0xFFFFFFFF; | 529 | sleep_ticks = 0xFFFFFFFF; |
530 | local_irq_enable(); | ||
524 | break; | 531 | break; |
525 | 532 | ||
526 | case ACPI_STATE_C2: | 533 | case ACPI_STATE_C2: |
@@ -1403,11 +1410,13 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
1403 | if (unlikely(!pr)) | 1410 | if (unlikely(!pr)) |
1404 | return 0; | 1411 | return 0; |
1405 | 1412 | ||
1413 | local_irq_disable(); | ||
1406 | if (pr->flags.bm_check) | 1414 | if (pr->flags.bm_check) |
1407 | acpi_idle_update_bm_rld(pr, cx); | 1415 | acpi_idle_update_bm_rld(pr, cx); |
1408 | 1416 | ||
1409 | acpi_safe_halt(); | 1417 | acpi_safe_halt(); |
1410 | 1418 | ||
1419 | local_irq_enable(); | ||
1411 | cx->usage++; | 1420 | cx->usage++; |
1412 | 1421 | ||
1413 | return 0; | 1422 | return 0; |
@@ -1517,7 +1526,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1517 | if (dev->safe_state) { | 1526 | if (dev->safe_state) { |
1518 | return dev->safe_state->enter(dev, dev->safe_state); | 1527 | return dev->safe_state->enter(dev, dev->safe_state); |
1519 | } else { | 1528 | } else { |
1529 | local_irq_disable(); | ||
1520 | acpi_safe_halt(); | 1530 | acpi_safe_halt(); |
1531 | local_irq_enable(); | ||
1521 | return 0; | 1532 | return 0; |
1522 | } | 1533 | } |
1523 | } | 1534 | } |