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