summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/ppc/kernel/irq.c7
-rw-r--r--arch/ppc/platforms/pmac_pic.c44
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)