1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc. 9 */ 10#ifndef _ASM_HARDIRQ_H 11#define _ASM_HARDIRQ_H 12 13#include <linux/config.h> 14#include <linux/threads.h> 15#include <linux/irq.h> 16#include <linux/spinlock.h> 17 18typedef struct { 19 unsigned int __softirq_pending; 20 unsigned int __local_irq_count; 21 unsigned int __local_bh_count; 22 unsigned int __syscall_count; 23 struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ 24} ____cacheline_aligned irq_cpustat_t; 25 26#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 27 28/* 29 * Are we in an interrupt context? Either doing bottom half 30 * or hardware interrupt processing? 31 */ 32#define in_interrupt() ({ int __cpu = smp_processor_id(); \ 33 (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) 34#define in_irq() (local_irq_count(smp_processor_id()) != 0) 35 36#ifndef CONFIG_SMP 37 38#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) 39#define hardirq_endlock(cpu) do { } while (0) 40 41#define irq_enter(cpu, irq) (local_irq_count(cpu)++) 42#define irq_exit(cpu, irq) (local_irq_count(cpu)--) 43 44#define synchronize_irq() barrier(); 45 46#else 47 48#include <asm/atomic.h> 49#include <linux/spinlock.h> 50#include <asm/smp.h> 51 52extern int global_irq_holder; 53extern spinlock_t global_irq_lock; 54 55static inline int irqs_running (void) 56{ 57 int i; 58 59 for (i = 0; i < smp_num_cpus; i++) 60 if (local_irq_count(i)) 61 return 1; 62 return 0; 63} 64 65static inline void release_irqlock(int cpu) 66{ 67 /* if we didn't own the irq lock, just ignore.. */ 68 if (global_irq_holder == cpu) { 69 global_irq_holder = NO_PROC_ID; 70 spin_unlock(&global_irq_lock); 71 } 72} 73 74static inline int hardirq_trylock(int cpu) 75{ 76 return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock); 77} 78 79#define hardirq_endlock(cpu) do { } while (0) 80 81static inline void irq_enter(int cpu, int irq) 82{ 83 ++local_irq_count(cpu); 84 85 while (spin_is_locked(&global_irq_lock)) 86 barrier(); 87} 88 89static inline void irq_exit(int cpu, int irq) 90{ 91 --local_irq_count(cpu); 92} 93 94extern void synchronize_irq(void); 95 96#endif /* CONFIG_SMP */ 97#endif /* _ASM_HARDIRQ_H */ 98