Messages in this thread Patch in this message | | | Date | Sun, 21 Jul 2002 22:41:36 +0200 (CEST) | From | Ingo Molnar <> | Subject | [patch] "big IRQ lock" removal, 2.5.27-A5 |
| |
reviewed and fixed the apm.c hacks, it's now using the proper spinlocks and not cli()/sti(). Latest full patch is at:
http://redhat.com/~mingo/remove-irqlock-patches/remove-irqlock-2.5.27-A5
(the apm.c changes are attached as well.)
Ingo
--- linux/arch/i386/kernel/apm.c.orig Sun Jul 21 20:37:10 2002 +++ linux/arch/i386/kernel/apm.c Sun Jul 21 22:36:42 2002 @@ -222,6 +222,8 @@ #include <linux/sysrq.h> +extern rwlock_t xtime_lock; +extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1141,40 +1143,25 @@ static void set_time(void) { - unsigned long flags; - - if (got_clock_diff) { /* Must know time zone in order to set clock */ - save_flags(flags); - cli(); + if (got_clock_diff) /* Must know time zone in order to set clock */ CURRENT_TIME = get_cmos_time() + clock_cmos_diff; - restore_flags(flags); - } } static void get_time_diff(void) { #ifndef CONFIG_APM_RTC_IS_GMT - unsigned long flags; - /* * Estimate time zone so that set_time can update the clock */ - save_flags(flags); clock_cmos_diff = -get_cmos_time(); - cli(); clock_cmos_diff += CURRENT_TIME; got_clock_diff = 1; - restore_flags(flags); #endif } -static void reinit_timer(void) +static inline void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - - save_flags(flags); - cli(); /* set the clock to 100 Hz */ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ udelay(10); @@ -1182,7 +1169,6 @@ udelay(10); outb(LATCH >> 8 , 0x40); /* MSB */ udelay(10); - restore_flags(flags); #endif } @@ -1203,13 +1189,21 @@ } printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); } + /* serialize with the timer interrupt */ + write_lock_irq(&xtime_lock); + + /* protect against access to timer chip registers */ + spin_lock(&i8253_lock); + get_time_diff(); - cli(); err = set_system_power_state(APM_STATE_SUSPEND); reinit_timer(); set_time(); ignore_normal_resume = 1; - sti(); + + spin_unlock(&i8253_lock); + write_unlock_irq(&xtime_lock); + if (err == APM_NO_ERROR) err = APM_SUCCESS; if (err != APM_SUCCESS) @@ -1232,8 +1226,12 @@ { int err; + /* serialize with the timer interrupt */ + write_lock_irq(&xtime_lock); /* If needed, notify drivers here */ get_time_diff(); + write_unlock_irq(&xtime_lock); + err = set_system_power_state(APM_STATE_STANDBY); if ((err != APM_SUCCESS) && (err != APM_NO_ERROR)) apm_error("standby", err); @@ -1321,7 +1319,9 @@ ignore_bounce = 1; if ((event != APM_NORMAL_RESUME) || (ignore_normal_resume == 0)) { + write_lock_irq(&xtime_lock); set_time(); + write_unlock_irq(&xtime_lock); pm_send_all(PM_RESUME, (void *)0); queue_event(event, NULL); } @@ -1336,7 +1336,9 @@ break; case APM_UPDATE_TIME: + write_lock_irq(&xtime_lock); set_time(); + write_unlock_irq(&xtime_lock); break; case APM_CRITICAL_SUSPEND: - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |