diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-09 02:54:55 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-09 02:54:55 +0000 |
commit | 493c987f7a352ca64fdb4dc03a21e24cbaf46f55 (patch) | |
tree | 184cddc0925e082c0500afd042f92e9f340fe890 /arch/i386 | |
parent | 2d25612a92c62b5708d6d43f38d28c6141173328 (diff) |
Merge with Linux 2.4.0-pre3-test6.
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/config.in | 4 | ||||
-rw-r--r-- | arch/i386/kernel/apm.c | 2 | ||||
-rw-r--r-- | arch/i386/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/i386/lib/dec_and_lock.c | 40 |
4 files changed, 50 insertions, 0 deletions
diff --git a/arch/i386/config.in b/arch/i386/config.in index 7344e802c..a2252d7af 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -34,6 +34,7 @@ choice 'Processor family' \ # Define implied options from the CPU selection here # if [ "$CONFIG_M386" = "y" ]; then + define_bool CONFIG_X86_CMPXCHG n define_int CONFIG_X86_L1_CACHE_BYTES 16 else define_bool CONFIG_X86_WP_WORKS_OK y @@ -139,6 +140,9 @@ if [ "$CONFIG_SMP" != "y" ]; then define_bool CONFIG_X86_LOCAL_APIC y fi fi +if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then + define_bool CONFIG_HAVE_DEC_LOCK y +fi endmenu mainmenu_option next_comment diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index c78a8f512..6a4eedf72 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -660,6 +660,7 @@ static void apm_power_off(void) #endif } +#ifdef CONFIG_APM_DO_ENABLE static int apm_enable_power_management(int enable) { u32 eax; @@ -675,6 +676,7 @@ static int apm_enable_power_management(int enable) apm_bios_info.flags |= APM_BIOS_DISABLED; return APM_SUCCESS; } +#endif static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) { diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 2394245a6..be8fcec0a 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -13,4 +13,8 @@ ifdef CONFIG_X86_USE_3DNOW L_OBJS += mmx.o endif +ifdef CONFIG_HAVE_DEC_LOCK +L_OBJS += dec_and_lock.o +endif + include $(TOPDIR)/Rules.make diff --git a/arch/i386/lib/dec_and_lock.c b/arch/i386/lib/dec_and_lock.c new file mode 100644 index 000000000..ffd486900 --- /dev/null +++ b/arch/i386/lib/dec_and_lock.c @@ -0,0 +1,40 @@ +/* + * x86 version of "atomic_dec_and_lock()" using + * the atomic "cmpxchg" instruction. + * + * (For CPU's lacking cmpxchg, we use the slow + * generic version, and this one never even gets + * compiled). + */ + +#include <linux/spinlock.h> +#include <asm/atomic.h> + +int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + +repeat: + counter = atomic_read(atomic); + newcount = counter-1; + + if (!newcount) + goto slow_path; + + asm volatile("lock; cmpxchgl %1,%2" + :"=a" (newcount) + :"r" (newcount), "m" (atomic->counter), "0" (counter)); + + /* If the above failed, "eax" will have changed */ + if (newcount != counter) + goto repeat; + return 0; + +slow_path: + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} |