Commit 714d8ac4 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] C1 fixes when processor driver is loaded

honor "halt=" cmdline parameter
use monitor/mwait when available
http://bugzilla.kernel.org/show_bug.cgi?id=2280Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent bcaf14d8
......@@ -57,6 +57,9 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int hlt_counter;
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
/*
* Return saved PC of a blocked thread.
*/
......@@ -211,6 +214,7 @@ static int __init idle_setup (char *str)
pm_idle = default_idle;
}
boot_option_idle_override = 1;
return 1;
}
......
......@@ -47,6 +47,8 @@
void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
void
ia64_do_show_stack (struct unw_frame_info *info, void *arg)
......
......@@ -54,6 +54,9 @@ unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
atomic_t hlt_counter = ATOMIC_INIT(0);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
/*
* Powermanagement idle function, if any..
*/
......@@ -192,6 +195,7 @@ static int __init idle_setup (char *str)
pm_idle = poll_idle;
}
boot_option_idle_override = 1;
return 1;
}
......
......@@ -411,8 +411,15 @@ acpi_processor_idle (void)
switch (pr->power.state) {
case ACPI_STATE_C1:
/* Invoke C1. */
safe_halt();
/*
* Invoke C1.
* Use the appropriate idle routine, the one that would
* be used without acpi C-states.
*/
if (pm_idle_save)
pm_idle_save();
else
safe_halt();
/*
* TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument
......@@ -2388,22 +2395,28 @@ acpi_processor_add (
/*
* Install the idle handler if processor power management is supported.
* Note that the default idle handler (default_idle) will be used on
* Note that we use previously set idle handler will be used on
* platforms that only support C1.
*/
if ((pr->id == 0) && (pr->flags.power)) {
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle;
if ((pr->flags.power) && (!boot_option_idle_override)) {
printk(KERN_INFO PREFIX "%s [%s] (supports",
acpi_device_name(device), acpi_device_bid(device));
for (i = 1; i < ACPI_C_STATE_COUNT; i++)
if (pr->power.states[i].valid)
printk(" C%d", i);
printk(")\n");
if (pr->id == 0) {
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle;
}
}
printk(KERN_INFO PREFIX "%s [%s] (supports",
acpi_device_name(device), acpi_device_bid(device));
for (i=1; i<ACPI_C_STATE_COUNT; i++)
if (pr->power.states[i].valid)
printk(" C%d", i);
if (pr->flags.throttling)
printk(", %d throttling states", pr->throttling.state_count);
printk(")\n");
if (pr->flags.throttling) {
printk(KERN_INFO PREFIX "%s [%s] (supports",
acpi_device_name(device), acpi_device_bid(device));
printk(" %d throttling states", pr->throttling.state_count);
printk(")\n");
}
end:
if (result) {
......
......@@ -650,4 +650,6 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c);
#define ARCH_HAS_SCHED_WAKE_IDLE
#endif
extern unsigned long boot_option_idle_override;
#endif /* __ASM_I386_PROCESSOR_H */
......@@ -688,6 +688,8 @@ prefetchw (const void *x)
#define spin_lock_prefetch(x) prefetchw(x)
extern unsigned long boot_option_idle_override;
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_PROCESSOR_H */
......@@ -461,4 +461,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
#define ARCH_HAS_SCHED_WAKE_IDLE
#endif
extern unsigned long boot_option_idle_override;
#endif /* __ASM_X86_64_PROCESSOR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment