diff options
| -rw-r--r-- | arch/ppc/kernel/irq.c | 7 | ||||
| -rw-r--r-- | arch/ppc/platforms/pmac_pic.c | 44 |
2 files changed, 34 insertions, 17 deletions
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 6bb1fcc04c2c..2ac2e4b55225 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -171,7 +171,12 @@ setup_irq(unsigned int irq, struct irqaction * new) if (!shared) { desc->depth = 0; desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); - unmask_irq(irq); + if (desc->handler) { + if (desc->handler->startup) + desc->handler->startup(irq); + else if (desc->handler->enable) + desc->handler->enable(irq); + } } spin_unlock_irqrestore(&desc->lock,flags); diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 5566d7bc9685..bebba87931ee 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -144,6 +144,22 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) spin_unlock_irqrestore(&pmac_pic_lock, flags); } +/* When an irq gets requested for the first client, if it's an + * edge interrupt, we clear any previous one on the controller + */ +static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr) +{ + unsigned long bit = 1UL << (irq_nr & 0x1f); + int i = irq_nr >> 5; + + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + out_le32(&pmac_irq_hw[i]->ack, bit); + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr, 0); + + return 0; +} + static void __pmac pmac_mask_irq(unsigned int irq_nr) { clear_bit(irq_nr, ppc_cached_irq_mask); @@ -168,25 +184,21 @@ static void __pmac pmac_end_irq(unsigned int irq_nr) struct hw_interrupt_type pmac_pic = { - " PMAC-PIC ", - NULL, - NULL, - pmac_unmask_irq, - pmac_mask_irq, - pmac_mask_and_ack_irq, - pmac_end_irq, - NULL + .typename = " PMAC-PIC ", + .startup = pmac_startup_irq, + .enable = pmac_unmask_irq, + .disable = pmac_mask_irq, + .ack = pmac_mask_and_ack_irq, + .end = pmac_end_irq, }; struct hw_interrupt_type gatwick_pic = { - " GATWICK ", - NULL, - NULL, - pmac_unmask_irq, - pmac_mask_irq, - pmac_mask_and_ack_irq, - pmac_end_irq, - NULL + .typename = " GATWICK ", + .startup = pmac_startup_irq, + .enable = pmac_unmask_irq, + .disable = pmac_mask_irq, + .ack = pmac_mask_and_ack_irq, + .end = pmac_end_irq, }; static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) |
