Commit 8712e9ef authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras

PPC32: interrupt fixes along the lines of Ingo's changes to x86.

We don't unmask the interrupt at the end of handling it if there
is no action (i.e. someone has done free_irq).  Add some likely
and unlikely hints and fix synchronize_irq.
parent e5aaf60c
...@@ -130,7 +130,8 @@ static void i8259_unmask_irq(unsigned int irq_nr) ...@@ -130,7 +130,8 @@ static void i8259_unmask_irq(unsigned int irq_nr)
static void i8259_end_irq(unsigned int irq) static void i8259_end_irq(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq].action)
i8259_unmask_irq(irq); i8259_unmask_irq(irq);
} }
......
...@@ -443,7 +443,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) ...@@ -443,7 +443,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
* use the action we have. * use the action we have.
*/ */
action = NULL; action = NULL;
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
action = desc->action; action = desc->action;
if (!action || !action->handler) { if (!action || !action->handler) {
ppc_spurious_interrupts++; ppc_spurious_interrupts++;
...@@ -468,7 +468,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) ...@@ -468,7 +468,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
a different instance of this same irq, the other processor a different instance of this same irq, the other processor
will take care of it. will take care of it.
*/ */
if (!action) if (unlikely(!action))
goto out; goto out;
...@@ -487,12 +487,12 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) ...@@ -487,12 +487,12 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
handle_irq_event(irq, regs, action); handle_irq_event(irq, regs, action);
spin_lock(&desc->lock); spin_lock(&desc->lock);
if (!(desc->status & IRQ_PENDING)) if (likely(!(desc->status & IRQ_PENDING)))
break; break;
desc->status &= ~IRQ_PENDING; desc->status &= ~IRQ_PENDING;
} }
desc->status &= ~IRQ_INPROGRESS;
out: out:
desc->status &= ~IRQ_INPROGRESS;
/* /*
* The ->end() handler has to deal with interrupts which got * The ->end() handler has to deal with interrupts which got
* disabled while the handler was running. * disabled while the handler was running.
...@@ -561,10 +561,6 @@ void __init init_IRQ(void) ...@@ -561,10 +561,6 @@ void __init init_IRQ(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void synchronize_irq(unsigned int irq) void synchronize_irq(unsigned int irq)
{ {
/* is there anything to synchronize with? */
if (!irq_desc[irq].action)
return;
while (irq_desc[irq].status & IRQ_INPROGRESS) while (irq_desc[irq].status & IRQ_INPROGRESS)
barrier(); barrier();
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/open_pic.h> #include <asm/open_pic.h>
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/hardirq.h>
#include "open_pic_defs.h" #include "open_pic_defs.h"
...@@ -798,7 +799,8 @@ static void openpic_ack_irq(unsigned int irq_nr) ...@@ -798,7 +799,8 @@ static void openpic_ack_irq(unsigned int irq_nr)
static void openpic_end_irq(unsigned int irq_nr) static void openpic_end_irq(unsigned int irq_nr)
{ {
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action)
openpic_enable_irq(irq_nr); openpic_enable_irq(irq_nr);
} }
......
...@@ -236,7 +236,8 @@ ppc405_uic_end(unsigned int irq) ...@@ -236,7 +236,8 @@ ppc405_uic_end(unsigned int irq)
} }
} }
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))
&& irq_desc[irq].action) {
ppc_cached_irq_mask[word] |= 1 << (31 - bit); ppc_cached_irq_mask[word] |= 1 << (31 - bit);
switch (word){ switch (word){
case 0: case 0:
......
...@@ -90,7 +90,8 @@ static void m8260_end_irq(unsigned int irq_nr) ...@@ -90,7 +90,8 @@ static void m8260_end_irq(unsigned int irq_nr)
int bit, word; int bit, word;
volatile uint *simr; volatile uint *simr;
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
bit = irq_to_siubit[irq_nr]; bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr]; word = irq_to_siureg[irq_nr];
......
...@@ -46,7 +46,8 @@ static void m8xx_unmask_irq(unsigned int irq_nr) ...@@ -46,7 +46,8 @@ static void m8xx_unmask_irq(unsigned int irq_nr)
static void m8xx_end_irq(unsigned int irq_nr) static void m8xx_end_irq(unsigned int irq_nr)
{ {
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
int bit, word; int bit, word;
bit = irq_nr & 0x1f; bit = irq_nr & 0x1f;
......
...@@ -149,7 +149,8 @@ static void __pmac pmac_unmask_irq(unsigned int irq_nr) ...@@ -149,7 +149,8 @@ static void __pmac pmac_unmask_irq(unsigned int irq_nr)
static void __pmac pmac_end_irq(unsigned int irq_nr) static void __pmac pmac_end_irq(unsigned int irq_nr)
{ {
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
set_bit(irq_nr, ppc_cached_irq_mask); set_bit(irq_nr, ppc_cached_irq_mask);
pmac_set_irq_mask(irq_nr, 1); pmac_set_irq_mask(irq_nr, 1);
} }
......
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