diff options
author | venkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com> | 2008-01-31 17:35:03 -0800 |
---|---|---|
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) | |
download | lwn-2e906655baf1c6f6fccd212fc9e6499dc6928b80.tar.gz lwn-2e906655baf1c6f6fccd212fc9e6499dc6928b80.zip |
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) return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); } +/* + * Callers should disable interrupts before the call and enable + * interrupts after return. + */ static void acpi_safe_halt(void) { current_thread_info()->status &= ~TS_POLLING; @@ -413,6 +417,8 @@ static void acpi_processor_idle(void) pm_idle_save(); else acpi_safe_halt(); + + local_irq_enable(); return; } @@ -521,6 +527,7 @@ static void acpi_processor_idle(void) * skew otherwise. */ sleep_ticks = 0xFFFFFFFF; + local_irq_enable(); break; case ACPI_STATE_C2: @@ -1403,11 +1410,13 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, if (unlikely(!pr)) return 0; + local_irq_disable(); if (pr->flags.bm_check) acpi_idle_update_bm_rld(pr, cx); acpi_safe_halt(); + local_irq_enable(); cx->usage++; return 0; @@ -1517,7 +1526,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, if (dev->safe_state) { return dev->safe_state->enter(dev, dev->safe_state); } else { + local_irq_disable(); acpi_safe_halt(); + local_irq_enable(); return 0; } } |