powerpc/cell has a slightly modified version of the edge handler. The main difference is that it does not ack and mask, but uses eoi. handle_edge_irq is an oddball handler anyway, which should be avoided wherever it can. So it's not worth to have a slightly different copy around. Add a special flag to reuse handle_edge_irq for this odd case. Signed-off-by: Thomas Gleixner Cc: Benjamin Herrenschmidt Cc: Jeremy Kerr Cc: Arnd Bergmann --- include/linux/irq.h | 3 ++- kernel/irq/chip.c | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) Index: linux-2.6-tip/include/linux/irq.h =================================================================== --- linux-2.6-tip.orig/include/linux/irq.h +++ linux-2.6-tip/include/linux/irq.h @@ -71,10 +71,11 @@ typedef void (*irq_flow_handler_t)(unsig #define IRQ_SUSPENDED 0x04000000 /* IRQ has gone through suspend sequence */ #define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */ #define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */ +#define IRQ_EDGE_EOI 0x20000000 /* IRQ abuses edge handler with EOI */ #define IRQF_MODIFY_MASK \ (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ - IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL) + IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_EDGE_EOI) #ifdef CONFIG_IRQ_PER_CPU # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) Index: linux-2.6-tip/kernel/irq/chip.c =================================================================== --- linux-2.6-tip.orig/kernel/irq/chip.c +++ linux-2.6-tip/kernel/irq/chip.c @@ -633,13 +633,15 @@ handle_edge_irq(unsigned int irq, struct if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || !desc->action)) { desc->status |= IRQ_PENDING; - mask_ack_irq(desc); + if (!(desc->status & IRQ_EDGE_EOI)) + mask_ack_irq(desc); goto out_unlock; } kstat_incr_irqs_this_cpu(irq, desc); /* Start handling the irq */ - desc->irq_data.chip->irq_ack(&desc->irq_data); + if (!(desc->status & IRQ_EDGE_EOI)) + desc->irq_data.chip->irq_ack(&desc->irq_data); /* Mark the IRQ currently in progress.*/ desc->status |= IRQ_INPROGRESS; @@ -649,7 +651,8 @@ handle_edge_irq(unsigned int irq, struct irqreturn_t action_ret; if (unlikely(!action)) { - mask_irq(desc); + if (!(desc->status & IRQ_EDGE_EOI)) + mask_irq(desc); goto out_unlock; } @@ -675,6 +678,8 @@ handle_edge_irq(unsigned int irq, struct desc->status &= ~IRQ_INPROGRESS; out_unlock: + if (desc->status & IRQ_EDGE_EOI) + desc->irq_data.chip->irq_eoi(&desc->irq_data); raw_spin_unlock(&desc->lock); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/