summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2004-09-07 17:48:45 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-09-07 17:48:45 -0700
commitcfec5c01d3d2957f346e4560a4eee0a54195b6f6 (patch)
tree165f304dfa1e7e1d9368a8c4f60ec1ef8ea9dc2a /include/linux
parent36ea58a510aa8c04ff181becfb7dcc1726094f31 (diff)
[PATCH] factor out common <asm/hardirq.h> code
Since the irq handling rework in 2.5 lots of code in the individual <asm/hardirq.h> files is the same. This patch moves that common code to <linux/hardirq.h>. The following differences existed: - alpha, m68k, m68knommu and v850 were missing the ~PREEMPT_ACTIVE masking in the CONFIG_PREEMPT case of in_atomic(). These architectures don't support CONFIG_PREEMPT else this would have been an easily-spottbale bug - S390 didn't provide synchronize_irq as it doesn't fit into their I/O model. They now get a spurious prototype/macro - ppc added a new preemptible() macro that is provided for all architectures now. Most drivers were using <linux/interrupt.h> as they should, but a few drivers and lots of architecture code has been updated to use <linux/hardirq.h> instead of <asm/hardirq.h> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/hardirq.h51
-rw-r--r--include/linux/interrupt.h2
2 files changed, 52 insertions, 1 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
new file mode 100644
index 000000000000..6ab0b3daaa68
--- /dev/null
+++ b/include/linux/hardirq.h
@@ -0,0 +1,51 @@
+#ifndef LINUX_HARDIRQ_H
+#define LINUX_HARDIRQ_H
+
+#include <linux/config.h>
+#ifdef CONFIG_PREEPT
+#include <linux/smp_lock.h>
+#endif
+#include <asm/hardirq.h>
+
+#define __IRQ_MASK(x) ((1UL << (x))-1)
+
+#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
+
+#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
+#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
+#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq() (hardirq_count())
+#define in_softirq() (softirq_count())
+#define in_interrupt() (irq_count())
+
+#define hardirq_trylock() (!in_interrupt())
+#define hardirq_endlock() do { } while (0)
+
+#ifdef CONFIG_PREEMPT
+# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define preemptible() (preempt_count() == 0 && !irqs_disabled())
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define in_atomic() (preempt_count() != 0)
+# define preemptible() 0
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+
+#ifdef CONFIG_SMP
+extern void synchronize_irq(unsigned int irq);
+#else
+# define synchronize_irq(irq) barrier()
+#endif
+
+#endif /* LINUX_HARDIRQ_H */
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 565321b05213..c7bf37959009 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -8,8 +8,8 @@
#include <linux/bitops.h>
#include <linux/preempt.h>
#include <linux/cpumask.h>
+#include <linux/hardirq.h>
#include <asm/atomic.h>
-#include <asm/hardirq.h>
#include <asm/ptrace.h>
#include <asm/system.h>