aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-09-05 09:49:45 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-10-01 06:53:25 -0400
commit7d65f4a6553203da6a22097821d151fbbe7e4956 (patch)
tree4ac4162ca37756530112c29e8dbf1d2568313d81 /arch/sh
parentded797547548a5b8e7b92383a41e4c0e6b0ecb7f (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.c57
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
152asmlinkage void do_softirq(void) 152void 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
195static inline void handle_one_irq(unsigned int irq) 180static inline void handle_one_irq(unsigned int irq)