aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2006-07-01 17:30:09 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-07-01 17:30:09 -0400
commit4a2581a080098ca3a0c4e416d7a282e96c75ebf8 (patch)
tree6709b53f00a271fe8dd76b6cfb821419c8afb206
parentf8b5473fcbddbfde827ecf82aa0e81fa2a878220 (diff)
[ARM] 3692/1: ARM: coswitch irq handling to the generic implementation
Patch from Thomas Gleixner From: Thomas Gleixner <tglx@linutronix.de> Switch the ARM irq core handling to the generic implementation. The ARM specific header files now contain mostly migration stubs and helper macros. Note that each machine type must be converted after this step seperately. This was seperated out from the patch for easier review. The main changes for the machine type code is the conversion of the type handlers to a 'type flow' and 'chip' model. This affects only the multiplex interrupt handlers. A conversion macro needs to be added to those implementations, which defines the data structure which is registered by the set_irq_chained_handler() macro. Some minor fixups of include files and the conversion of data structure access is necessary all over the place. The mostly macro based conversion was provided to allow an easy migration of the existing implementations. The code compiles on all defconfigs available in arch/arm/configs except those which were broken also before applying the conversion patches. The code has been boot and runtime tested on most ARM platforms. The results of an extensive testing and bugfixing series can be found at: http://www.linutronix.de/index.php?page=testing Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/kernel/fiq.c1
-rw-r--r--arch/arm/kernel/irq.c951
-rw-r--r--include/asm-arm/dyntick.h6
-rw-r--r--include/asm-arm/hw_irq.h9
-rw-r--r--include/asm-arm/irq.h22
-rw-r--r--include/asm-arm/mach/irq.h135
7 files changed, 93 insertions, 1043 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f123c7c9fc98..531661ac01b4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -47,6 +47,18 @@ config MCA
47 <file:Documentation/mca.txt> (and especially the web page given 47 <file:Documentation/mca.txt> (and especially the web page given
48 there) before attempting to build an MCA bus kernel. 48 there) before attempting to build an MCA bus kernel.
49 49
50config GENERIC_HARDIRQS
51 bool
52 default y
53
54config HARDIRQS_SW_RESEND
55 bool
56 default y
57
58config GENERIC_IRQ_PROBE
59 bool
60 default y
61
50config RWSEM_GENERIC_SPINLOCK 62config RWSEM_GENERIC_SPINLOCK
51 bool 63 bool
52 default y 64 default y
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 1ec3f7faa259..e8e90346f11c 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -38,6 +38,7 @@
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h>
41#include <linux/seq_file.h> 42#include <linux/seq_file.h>
42 43
43#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 4d31cf8d02d5..c3d4e94ef5bf 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -26,6 +26,7 @@
26#include <linux/signal.h> 26#include <linux/signal.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/irq.h>
29#include <linux/ptrace.h> 30#include <linux/ptrace.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/random.h> 32#include <linux/random.h>
@@ -37,192 +38,18 @@
37#include <linux/kallsyms.h> 38#include <linux/kallsyms.h>
38#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
39 40
40#include <asm/irq.h>
41#include <asm/system.h> 41#include <asm/system.h>
42#include <asm/mach/irq.h>
43#include <asm/mach/time.h> 42#include <asm/mach/time.h>
44 43
45/* 44/*
46 * Maximum IRQ count. Currently, this is arbitary. However, it should
47 * not be set too low to prevent false triggering. Conversely, if it
48 * is set too high, then you could miss a stuck IRQ.
49 *
50 * Maybe we ought to set a timer and re-enable the IRQ at a later time?
51 */
52#define MAX_IRQ_CNT 100000
53
54static int noirqdebug __read_mostly;
55static volatile unsigned long irq_err_count;
56static DEFINE_SPINLOCK(irq_controller_lock);
57static LIST_HEAD(irq_pending);
58
59struct irqdesc irq_desc[NR_IRQS];
60void (*init_arch_irq)(void) __initdata = NULL;
61
62/*
63 * No architecture-specific irq_finish function defined in arm/arch/irqs.h. 45 * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
64 */ 46 */
65#ifndef irq_finish 47#ifndef irq_finish
66#define irq_finish(irq) do { } while (0) 48#define irq_finish(irq) do { } while (0)
67#endif 49#endif
68 50
69/* 51void (*init_arch_irq)(void) __initdata = NULL;
70 * Dummy mask/unmask handler 52unsigned long irq_err_count;
71 */
72void dummy_mask_unmask_irq(unsigned int irq)
73{
74}
75
76irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs)
77{
78 return IRQ_NONE;
79}
80
81void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
82{
83 irq_err_count++;
84 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
85}
86
87static struct irqchip bad_chip = {
88 .ack = dummy_mask_unmask_irq,
89 .mask = dummy_mask_unmask_irq,
90 .unmask = dummy_mask_unmask_irq,
91};
92
93static struct irqdesc bad_irq_desc = {
94 .chip = &bad_chip,
95 .handle = do_bad_IRQ,
96 .pend = LIST_HEAD_INIT(bad_irq_desc.pend),
97 .disable_depth = 1,
98};
99
100#ifdef CONFIG_SMP
101void synchronize_irq(unsigned int irq)
102{
103 struct irqdesc *desc = irq_desc + irq;
104
105 while (desc->running)
106 barrier();
107}
108EXPORT_SYMBOL(synchronize_irq);
109
110#define smp_set_running(desc) do { desc->running = 1; } while (0)
111#define smp_clear_running(desc) do { desc->running = 0; } while (0)
112#else
113#define smp_set_running(desc) do { } while (0)
114#define smp_clear_running(desc) do { } while (0)
115#endif
116
117/**
118 * disable_irq_nosync - disable an irq without waiting
119 * @irq: Interrupt to disable
120 *
121 * Disable the selected interrupt line. Enables and disables
122 * are nested. We do this lazily.
123 *
124 * This function may be called from IRQ context.
125 */
126void disable_irq_nosync(unsigned int irq)
127{
128 struct irqdesc *desc = irq_desc + irq;
129 unsigned long flags;
130
131 spin_lock_irqsave(&irq_controller_lock, flags);
132 desc->disable_depth++;
133 list_del_init(&desc->pend);
134 spin_unlock_irqrestore(&irq_controller_lock, flags);
135}
136EXPORT_SYMBOL(disable_irq_nosync);
137
138/**
139 * disable_irq - disable an irq and wait for completion
140 * @irq: Interrupt to disable
141 *
142 * Disable the selected interrupt line. Enables and disables
143 * are nested. This functions waits for any pending IRQ
144 * handlers for this interrupt to complete before returning.
145 * If you use this function while holding a resource the IRQ
146 * handler may need you will deadlock.
147 *
148 * This function may be called - with care - from IRQ context.
149 */
150void disable_irq(unsigned int irq)
151{
152 struct irqdesc *desc = irq_desc + irq;
153
154 disable_irq_nosync(irq);
155 if (desc->action)
156 synchronize_irq(irq);
157}
158EXPORT_SYMBOL(disable_irq);
159
160/**
161 * enable_irq - enable interrupt handling on an irq
162 * @irq: Interrupt to enable
163 *
164 * Re-enables the processing of interrupts on this IRQ line.
165 * Note that this may call the interrupt handler, so you may
166 * get unexpected results if you hold IRQs disabled.
167 *
168 * This function may be called from IRQ context.
169 */
170void enable_irq(unsigned int irq)