Fix acpi_processor_idle and idle= boot parameter interaction
PATCH 1/1 Fix acpi_processor_idle and idle= boot parameter interaction
acpi_processor_idle and "idle=" boot parameter interaction is broken. The problem is that, at boot time acpi driver is checking for "idle=" boot option and not registering the acpi idle handler. But, when there is a CST changed callback (typically when switching AC <-> battery or suspend-resume) there are no checks for boot_option_idle_override and acpi idle handler tries to get installed with nasty side effects.
With CPU_IDLE configured this issue causes results in a nasty oops on CST change callback and without CPU_IDLE there is no oops, but boot option of "idle=" gets ignored and acpi idle handler gets installed.
Change the behavior to not do anything in acpi idle handler when there is a "idle=" boot option.
Note that the problem is only there when "idle=" boot option is used.
--- drivers/acpi/processor_idle.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/acpi/processor_idle.c +12 -2
@@ -1295,6 +1295,8 @@ int acpi_processor_cst_has_changed(struc {int result =0 ; +if (boot_option_idle_override) +return 0 ;if (!pr)return -EINVAL ;
@@ -1734,6 +1736,9 @@ int acpi_processor_cst_has_changed(struc {int ret; +if (boot_option_idle_override) +return 0 ; +if (!pr)return -EINVAL ;
@@ -1764,6 +1769,8 @@ int __cpuinit acpi_processor_power_init(struct proc_dir_entry *entry =NULL ;unsigned int i; +if (boot_option_idle_override) +return 0 ;if (!first_run) {dmi_check_system (processor_power_dmi_table);
@@ -1799,7 +1806,7 @@ int __cpuinit acpi_processor_power_init(* Note that we use previously set idle handler will be used on * platforms that only support C1. */ -if ((pr->flags.power) && (!boot_option_idle_override)) { +if (pr->flags.power) {#ifdef CONFIG_CPU_IDLE acpi_processor_setup_cpuidle (pr); pr->power.dev.cpu = pr->id;
@@ -1835,8 +1842,11 @@ int __cpuinit acpi_processor_power_init(int acpi_processor_power_exit (struct acpi_processor *pr,struct acpi_device *device) { +if (boot_option_idle_override) +return 0 ; +#ifdef CONFIG_CPU_IDLE -if ((pr->flags.power) && (!boot_option_idle_override)) +if (pr->flags.power)cpuidle_unregister_device (&pr->power.dev);#endif pr->flags.power_setup_done =0 ;
Len Brown
reviewerThis is upstream now.
thanks,
-Len
Quoted 78 lines · Venki Pallipadi
acpi_processor_idleand "idle=" boot parameter interaction is broken. The problem is that, at boot time acpi driver is checking for "idle=" boot option and not registering the acpi idle handler. But, when there is a CST changed callback (typically when switching AC <-> battery or suspend-resume) there are no checks forboot_option_idle_overrideand acpi idle handler tries to get installed with nasty side effects.With
CPU_IDLEconfigured this issue causes results in a nasty oops on CST change callback and withoutCPU_IDLEthere is no oops, but boot option of "idle=" gets ignored and acpi idle handler gets installed.Change the behavior to not do anything in acpi idle handler when there is a "idle=" boot option.
Note that the problem is only there when "idle=" boot option is used.
Signed-off-by Venkatesh Pallipadi <[email protected]>--- drivers/acpi/processor_idle.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)Index:
linux-2.6/drivers/acpi/processor_idle.c
===================================================================drivers/acpi/processor_idle.c +12
-2@@ -1295,6 +1295,8 @@ int acpi_processor_cst_has_changed(struc {int result =0 ; +if (boot_option_idle_override) +return 0 ;if (!pr)return -EINVAL ;@@ -1734,6 +1736,9 @@ int acpi_processor_cst_has_changed(struc {int ret; +if (boot_option_idle_override) +return 0 ; +if (!pr)return -EINVAL ;@@ -1764,6 +1769,8 @@ int __cpuinit acpi_processor_power_init(struct proc_dir_entry *entry =NULL ;unsigned int i; +if (boot_option_idle_override) +return 0 ;if (!first_run) {dmi_check_system (processor_power_dmi_table);@@ -1799,7 +1806,7 @@ int __cpuinit acpi_processor_power_init(* Note that we use previously set idle handler will be used on * platforms that only support C1. */ -if ((pr->flags.power) && (!boot_option_idle_override)) { +if (pr->flags.power) {#ifdef CONFIG_CPU_IDLE acpi_processor_setup_cpuidle (pr); pr->power.dev.cpu = pr->id;@@ -1835,8 +1842,11 @@ int __cpuinit acpi_processor_power_init(int acpi_processor_power_exit (struct acpi_processor *pr,struct acpi_device *device) { +if (boot_option_idle_override) +return 0 ; +#ifdef CONFIG_CPU_IDLE -if ((pr->flags.power) && (!boot_option_idle_override)) +if (pr->flags.power)cpuidle_unregister_device (&pr->power.dev);#endif pr->flags.power_setup_done =0 ;