aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
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)