Commit b709c083 authored by Stephen Rothwell's avatar Stephen Rothwell

ppc64: move stack switching up in interrupt processing

This will make the ppc64 multiplatform irq handling more like
the generic handling.
Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
parent 66ba135c
......@@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq)
mtlr r0
blr
_GLOBAL(call_handle_IRQ_event)
_GLOBAL(call_ppc_irq_dispatch_handler)
mflr r0
std r0,16(r1)
stdu r1,THREAD_SIZE-112(r6)
mr r1,r6
bl .handle_IRQ_event
stdu r1,THREAD_SIZE-112(r5)
mr r1,r5
bl .ppc_irq_dispatch_handler
ld r1,0(r1)
ld r0,16(r1)
mtlr r0
......
......@@ -157,9 +157,6 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
int cpu = smp_processor_id();
irq_desc_t *desc = get_irq_desc(irq);
irqreturn_t action_ret;
#ifdef CONFIG_IRQSTACKS
struct thread_info *curtp, *irqtp;
#endif
kstat_cpu(cpu).irqs[irq]++;
......@@ -227,20 +224,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
for (;;) {
spin_unlock(&desc->lock);
#ifdef CONFIG_IRQSTACKS
/* Switch to the irq stack to handle this */
curtp = current_thread_info();
irqtp = hardirq_ctx[smp_processor_id()];
if (curtp != irqtp) {
irqtp->task = curtp->task;
irqtp->flags = 0;
action_ret = call_handle_IRQ_event(irq, regs, action, irqtp);
irqtp->task = NULL;
if (irqtp->flags)
set_bits(irqtp->flags, &curtp->flags);
} else
#endif
action_ret = handle_IRQ_event(irq, regs, action);
action_ret = handle_IRQ_event(irq, regs, action);
spin_lock(&desc->lock);
if (!noirqdebug)
......@@ -310,6 +294,9 @@ void do_IRQ(struct pt_regs *regs)
void do_IRQ(struct pt_regs *regs)
{
int irq;
#ifdef CONFIG_IRQSTACKS
struct thread_info *curtp, *irqtp;
#endif
irq_enter();
......@@ -330,9 +317,22 @@ void do_IRQ(struct pt_regs *regs)
irq = ppc_md.get_irq(regs);
if (irq >= 0)
ppc_irq_dispatch_handler(regs, irq);
else
if (irq >= 0) {
#ifdef CONFIG_IRQSTACKS
/* Switch to the irq stack to handle this */
curtp = current_thread_info();
irqtp = hardirq_ctx[smp_processor_id()];
if (curtp != irqtp) {
irqtp->task = curtp->task;
irqtp->flags = 0;
call_ppc_irq_dispatch_handler(regs, irq, irqtp);
irqtp->task = NULL;
if (irqtp->flags)
set_bits(irqtp->flags, &curtp->flags);
} else
#endif
ppc_irq_dispatch_handler(regs, irq);
} else
/* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts++;
......
......@@ -78,12 +78,12 @@ _GLOBAL(call_do_softirq)
mtlr r0
blr
_GLOBAL(call_handle_IRQ_event)
_GLOBAL(call_ppc_irq_dispatch_handler)
mflr r0
std r0,16(r1)
stdu r1,THREAD_SIZE-112(r6)
mr r1,r6
bl .handle_IRQ_event
stdu r1,THREAD_SIZE-112(r5)
mr r1,r5
bl .ppc_irq_dispatch_handler
ld r1,0(r1)
ld r0,16(r1)
mtlr r0
......
......@@ -488,8 +488,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS];
extern void irq_ctx_init(void);
extern void call_do_softirq(struct thread_info *tp);
extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
struct irqaction *action, struct thread_info *tp);
extern int call_ppc_irq_dispatch_handler(struct pt_regs *regs, int irq,
struct thread_info *tp);
#define __ARCH_HAS_DO_SOFTIRQ
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment