diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /include/asm-sparc/hardirq.h | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'include/asm-sparc/hardirq.h')
-rw-r--r-- | include/asm-sparc/hardirq.h | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h index cfee071dc..00205d6ef 100644 --- a/include/asm-sparc/hardirq.h +++ b/include/asm-sparc/hardirq.h @@ -1,7 +1,7 @@ /* hardirq.h: 32-bit Sparc hard IRQ support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au) + * Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com) */ #ifndef __SPARC_HARDIRQ_H @@ -9,77 +9,83 @@ #include <linux/config.h> #include <linux/threads.h> +#include <linux/brlock.h> +#include <linux/spinlock.h> /* entry.S is sensitive to the offsets of these fields */ typedef struct { unsigned int __softirq_active; unsigned int __softirq_mask; +#ifndef CONFIG_SMP unsigned int __local_irq_count; +#else + unsigned int __unused_on_SMP; /* DaveM says use brlock for SMP irq. KAO */ +#endif unsigned int __local_bh_count; unsigned int __syscall_count; } ____cacheline_aligned irq_cpustat_t; #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ +/* Note that local_irq_count() is replaced by sparc64 specific version for SMP */ + +#ifndef CONFIG_SMP +#define irq_enter(cpu, irq) ((void)(irq), local_irq_count(cpu)++) +#define irq_exit(cpu, irq) ((void)(irq), local_irq_count(cpu)--) +#else +#undef local_irq_count +#define local_irq_count(cpu) (__brlock_array[cpu][BR_GLOBALIRQ_LOCK]) +#define irq_enter(cpu, irq) br_read_lock(BR_GLOBALIRQ_LOCK) +#define irq_exit(cpu, irq) br_read_unlock(BR_GLOBALIRQ_LOCK) +#endif /* * Are we in an interrupt context? Either doing bottom half * or hardware interrupt processing? */ -#define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) +#define in_interrupt() ((local_irq_count(smp_processor_id()) + \ + local_bh_count(smp_processor_id())) != 0) -#define in_irq() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) != 0); }) +/* This tests only the local processors hw IRQ context disposition. */ +#define in_irq() (local_irq_count(smp_processor_id()) != 0) #ifndef CONFIG_SMP -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { (void)(cpu); } while (0) - -#define hardirq_enter(cpu) (++local_irq_count(cpu)) -#define hardirq_exit(cpu) (--local_irq_count(cpu)) +#define hardirq_trylock(cpu) ((void)(cpu), local_irq_count(smp_processor_id()) == 0) +#define hardirq_endlock(cpu) do { (void)(cpu); } while(0) #define synchronize_irq() barrier() -#else +#else /* (CONFIG_SMP) */ -#include <asm/atomic.h> -#include <linux/spinlock.h> -#include <asm/system.h> -#include <asm/smp.h> +static __inline__ int irqs_running(void) +{ + int i; + + for (i = 0; i < smp_num_cpus; i++) + if (local_irq_count(cpu_logical_map(i))) + return 1; + return 0; +} extern unsigned char global_irq_holder; -extern spinlock_t global_irq_lock; -extern atomic_t global_irq_count; static inline void release_irqlock(int cpu) { - /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == (unsigned char) cpu) { + /* if we didn't own the irq lock, just ignore... */ + if(global_irq_holder == (unsigned char) cpu) { global_irq_holder = NO_PROC_ID; - spin_unlock(&global_irq_lock); + br_write_unlock(BR_GLOBALIRQ_LOCK); } } -static inline void hardirq_enter(int cpu) -{ - ++local_irq_count(cpu); - atomic_inc(&global_irq_count); -} - -static inline void hardirq_exit(int cpu) -{ - atomic_dec(&global_irq_count); - --local_irq_count(cpu); -} - static inline int hardirq_trylock(int cpu) { - return (! atomic_read(&global_irq_count) && - ! spin_is_locked (&global_irq_lock)); + spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock; + + return (!local_irq_count(cpu) && !spin_is_locked(lock)); } -#define hardirq_endlock(cpu) do { } while (0) +#define hardirq_endlock(cpu) do { (void)(cpu); } while (0) extern void synchronize_irq(void); |