#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/moduleparam.h>
+#include <linux/sched.h> /* need_resched() */
#include <asm/io.h>
#include <asm/uaccess.h>
return;
}
+static void acpi_safe_halt(void)
+{
+ int polling = test_thread_flag(TIF_POLLING_NRFLAG);
+ if (polling) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ }
+ if (!need_resched())
+ safe_halt();
+ if (polling)
+ set_thread_flag(TIF_POLLING_NRFLAG);
+}
+
static atomic_t c3_cpu_count;
static void acpi_processor_idle(void)
int sleep_ticks = 0;
u32 t1, t2 = 0;
- pr = processors[raw_smp_processor_id()];
+ pr = processors[smp_processor_id()];
if (!pr)
return;
}
cx = pr->power.state;
- if (!cx)
- goto easy_out;
+ if (!cx) {
+ if (pm_idle_save)
+ pm_idle_save();
+ else
+ acpi_safe_halt();
+ return;
+ }
/*
* Check BM Activity
if (pm_idle_save)
pm_idle_save();
else
- safe_halt();
+ acpi_safe_halt();
+
/*
* TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument
*/
if (next_state != pr->power.state)
acpi_processor_power_activate(pr, next_state);
-
- return;
-
- easy_out:
- /* do C1 instead of busy loop */
- if (pm_idle_save)
- pm_idle_save();
- else
- safe_halt();
- return;
}
static int acpi_processor_set_power_policy(struct acpi_processor *pr)