ppc64: move stack switching up in interrupt processing
This will make the ppc64 multiplatform irq handling more like the generic handling. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
This commit is contained in:
Родитель
66ba135c5a
Коммит
b709c08328
|
@ -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,19 +224,6 @@ 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);
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
|
@ -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)
|
||||
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
|
||||
} 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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче