diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2013-09-05 09:49:45 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2013-10-01 06:53:25 -0400 |
commit | 7d65f4a6553203da6a22097821d151fbbe7e4956 (patch) | |
tree | 4ac4162ca37756530112c29e8dbf1d2568313d81 /arch/sh | |
parent | ded797547548a5b8e7b92383a41e4c0e6b0ecb7f (diff) |
irq: Consolidate do_softirq() arch overriden implementations
All arch overriden implementations of do_softirq() share the following
common code: disable irqs (to avoid races with the pending check),
check if there are softirqs pending, then execute __do_softirq() on
a specific stack.
Consolidate the common parts such that archs only worry about the
stack switch.
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@au1.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul Mackerras <paulus@au1.ibm.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/kernel/irq.c | 57 |
1 files changed, 21 insertions, 36 deletions
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 063af10ff3c1..0833736afa32 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -149,47 +149,32 @@ void irq_ctx_exit(int cpu) | |||
149 | hardirq_ctx[cpu] = NULL; | 149 | hardirq_ctx[cpu] = NULL; |
150 | } | 150 | } |
151 | 151 | ||
152 | asmlinkage void do_softirq(void) | 152 | void do_softirq_own_stack(void) |
153 | { | 153 | { |
154 | unsigned long flags; | ||
155 | struct thread_info *curctx; | 154 | struct thread_info *curctx; |
156 | union irq_ctx *irqctx; | 155 | union irq_ctx *irqctx; |
157 | u32 *isp; | 156 | u32 *isp; |
158 | 157 | ||
159 | if (in_interrupt()) | 158 | curctx = current_thread_info(); |
160 | return; | 159 | irqctx = softirq_ctx[smp_processor_id()]; |
161 | 160 | irqctx->tinfo.task = curctx->task; | |
162 | local_irq_save(flags); | 161 | irqctx->tinfo.previous_sp = current_stack_pointer; |
163 | 162 | ||
164 | if (local_softirq_pending()) { | 163 | /* build the stack frame on the softirq stack */ |
165 | curctx = current_thread_info(); | 164 | isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); |
166 | irqctx = softirq_ctx[smp_processor_id()]; | 165 | |
167 | irqctx->tinfo.task = curctx->task; | 166 | __asm__ __volatile__ ( |
168 | irqctx->tinfo.previous_sp = current_stack_pointer; | 167 | "mov r15, r9 \n" |
169 | 168 | "jsr @%0 \n" | |
170 | /* build the stack frame on the softirq stack */ | 169 | /* switch to the softirq stack */ |
171 | isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); | 170 | " mov %1, r15 \n" |
172 | 171 | /* restore the thread stack */ | |
173 | __asm__ __volatile__ ( | 172 | "mov r9, r15 \n" |
174 | "mov r15, r9 \n" | 173 | : /* no outputs */ |
175 | "jsr @%0 \n" | 174 | : "r" (__do_softirq), "r" (isp) |
176 | /* switch to the softirq stack */ | 175 | : "memory", "r0", "r1", "r2", "r3", "r4", |
177 | " mov %1, r15 \n" | 176 | "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" |
178 | /* restore the thread stack */ | 177 | ); |
179 | "mov r9, r15 \n" | ||
180 | : /* no outputs */ | ||
181 | : "r" (__do_softirq), "r" (isp) | ||
182 | : "memory", "r0", "r1", "r2", "r3", "r4", | ||
183 | "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" | ||
184 | ); | ||
185 | |||
186 | /* | ||
187 | * Shouldn't happen, we returned above if in_interrupt(): | ||
188 | */ | ||
189 | WARN_ON_ONCE(softirq_count()); | ||
190 | } | ||
191 | |||
192 | local_irq_restore(flags); | ||
193 | } | 178 | } |
194 | #else | 179 | #else |
195 | static inline void handle_one_irq(unsigned int irq) | 180 | static inline void handle_one_irq(unsigned int irq) |