
From: Manfred Spraul <manfred@colorfullife.com>

apm.c:suspend() calls set_system_power_state() under (effectively)
spin_lock_irq(i8253_lock).

But set_system_power_state() unconditionally enables interrupts, in
apm_bios_call_simple().  This generates nasty warnings from the uniprocessor
spinlock debugging code, and would be deadlocky if APM worked on SMP.

So drop the locks around the set_system_power_state() call.


 arch/i386/kernel/apm.c |   10 ++++++++++
 1 files changed, 10 insertions(+)

diff -puN arch/i386/kernel/apm.c~apm-locking-fix arch/i386/kernel/apm.c
--- 25/arch/i386/kernel/apm.c~apm-locking-fix	2003-04-20 12:56:03.000000000 -0700
+++ 25-akpm/arch/i386/kernel/apm.c	2003-04-20 12:56:03.000000000 -0700
@@ -1205,7 +1205,17 @@ static int suspend(int vetoable)
 	spin_lock(&i8253_lock);
 
 	get_time_diff();
+	/*
+	 * Irq spinlock must be dropped around set_system_power_state.
+	 * We'll undo any timer changes due to interrupts below.
+	 */
+	spin_unlock(&i8253_lock);
+	write_sequnlock_irq(&xtime_lock);
+
 	err = set_system_power_state(APM_STATE_SUSPEND);
+
+	write_seqlock_irq(&xtime_lock);
+	spin_lock(&i8253_lock);
 	reinit_timer();
 	set_time();
 	ignore_normal_resume = 1;

_
