PM: ACPI and APM must not be enabled at the same time
Subsystems (4)
Len Brown
reviewerPATCH 1/1 PM: ACPI and APM must not be enabled at the same time
ACPI and APM used "pm_active" to guarantee that they would not be simultaneously active.
But pm_active was recently moved under CONFIG_PM_LEGACY, so that without CONFIG_PM_LEGACY, pm_active became a NOP -- allowing ACPI and APM to both be simultaneously enabled. This caused unpredictable results, including boot hangs.
Further, the code under CONFIG_PM_LEGACY is scheduled for removal.
So replace pm_active with pm_flags.pm_flags depends only on CONFIG_PM,
which is present for both CONFIG_APM and CONFIG_ACPI.
Signed-off-by Len Brown <[email protected]>
--- arch/i386/kernel/apm.c | 10 +++------- drivers/acpi/bus.c | 7 ++----- include/linux/pm.h | 9 +++++++++ include/linux/pm_legacy.h | 6 ------ kernel/power/main.c | 3 +++ kernel/power/pm.c | 4 ---- 6 files changed, 17 insertions(+), 22 deletions(-)
arch/i386/kernel/apm.c +3 -7
@@ -2255,14 +2255,12 @@ static int __init apm_init(void) apm_info.disabled =1 ;return -ENODEV ; } -if (PM_IS_ACTIVE ()) { +if (pm_flags &PM_ACPI ) {printk (KERN_NOTICE "apm: overridden by ACPI.\n" ); apm_info.disabled =1 ;return -ENODEV ; } -#ifdef CONFIG_PM_LEGACY - pm_active =1 ; -#endif + pm_flags |=PM_APM ;/* * Set up a segment that references the real mode segment 0x40
@@ -2366,9 +2364,7 @@ static void __exit apm_exit(void)kthread_stop (kapmd_task); kapmd_task =NULL ; } -#ifdef CONFIG_PM_LEGACY - pm_active =0 ; -#endif + pm_flags &= ~PM_APM ; }module_init (apm_init);
drivers/acpi/bus.c +2 -5
@@ -29,7 +29,6 @@#include <linux/list.h> #include <linux/sched.h> #include <linux/pm.h> -#include <linux/pm_legacy.h> #include <linux/device.h> #include <linux/proc_fs.h> #ifdef CONFIG_X86
@@ -755,16 +754,14 @@ static int __init acpi_init(void) result =acpi_bus_init ();if (!result) { -#ifdef CONFIG_PM_LEGACY -if (!PM_IS_ACTIVE ()) - pm_active =1 ; +if (!(pm_flags &PM_APM )) + pm_flags |=PM_ACPI ;else { printk(KERN_INFO PREFIX "APM is already active, exiting\n");disable_acpi (); result = -ENODEV ; } -#endif }else disable_acpi ();
include/linux/pm.h +9 -0
@@ -319,6 +319,15 @@ static inline int call_platform_enable_wakeup(struct device *dev, int is_on)device_set_wakeup_enable (dev,val); \ } while(0) +/* +* Global Power Management flags +* Used to keep APM and ACPI from both being active +*/ +extern unsigned int pm_flags; + +#define PM_APM 1 +#define PM_ACPI 2 +#endif /* __KERNEL__ */ #endif /* _LINUX_PM_H */
include/linux/pm_legacy.h +0 -6
@@ -4,10 +4,6 @@#ifdef CONFIG_PM_LEGACY -extern int pm_active; - -#define PM_IS_ACTIVE () (pm_active != 0) -/* * Register a device with power management */
@@ -21,8 +17,6 @@ int __deprecated pm_send_all(pm_request_t rqst, void *data);#else /* CONFIG_PM_LEGACY */ -#define PM_IS_ACTIVE () 0 -static inline struct pm_dev *pm_register (pm_dev_t type,unsigned long id,pm_callback callback)
kernel/power/main.c +3 -0
@@ -29,6 +29,9 @@DEFINE_MUTEX (pm_mutex); +unsigned int pm_flags; +EXPORT_SYMBOL (pm_flags); +struct pm_ops *pm_ops;/**
kernel/power/pm.c +0 -4
@@ -27,8 +27,6 @@#include <linux/interrupt.h> #include <linux/mutex.h> -int pm_active; -/* * Locking notes: * pm_devs_lock can be a semaphore providing pm ops are not called
@@ -204,6 +202,4 @@ int pm_send_all(pm_request_t rqst, void *data)EXPORT_SYMBOL (pm_register);EXPORT_SYMBOL (pm_send_all); -EXPORT_SYMBOL (pm_active); -