enable kexec
[linux-2.6.git] / arch / ppc / platforms / pmac_pic.c
index 1c8f300..bebba87 100644 (file)
@@ -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)
@@ -260,7 +272,7 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
                                        node->child->intrs = &gatwick_int_pool[count];
                                        count += 3;
                                }
-                               node->child->n_intrs = 3;                       
+                               node->child->n_intrs = 3;
                                node->child->intrs[0].line = 15+irq_base;
                                node->child->intrs[1].line =  4+irq_base;
                                node->child->intrs[2].line =  5+irq_base;
@@ -279,7 +291,7 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
                        node->intrs[0].line = 29+irq_base;
                        printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
                                        node->intrs[0].line);
-               
+
                        ya_node = node->child;
                        while(ya_node)
                        {
@@ -444,7 +456,7 @@ void __init pmac_pic_init(void)
                                        nmi_irq = pswitch->intrs[0].line;
                                        openpic_init_nmi_irq(nmi_irq);
                                        request_irq(nmi_irq, xmon_irq, 0,
-                                                   "NMI - XMON", 0);
+                                                   "NMI - XMON", NULL);
                                }
                        }
 #endif /* CONFIG_XMON */
@@ -501,7 +513,7 @@ void __init pmac_pic_init(void)
                                pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
                                        (addr + (2 - i) * 0x10);
                }
-       
+
                /* get addresses of second controller */
                irqctrler = irqctrler->next;
                if (irqctrler && irqctrler->n_addrs > 0) {
@@ -542,7 +554,7 @@ void __init pmac_pic_init(void)
                for ( i = max_real_irqs ; i < max_irqs ; i++ )
                        irq_desc[i].handler = &gatwick_pic;
                request_irq( irq_cascade, gatwick_action, SA_INTERRUPT,
-                            "cascade", 0 );
+                            "cascade", NULL );
        }
        printk("System has %d possible interrupts\n", max_irqs);
        if (max_irqs != max_real_irqs)
@@ -550,7 +562,7 @@ void __init pmac_pic_init(void)
                        max_real_irqs);
 
 #ifdef CONFIG_XMON
-       request_irq(20, xmon_irq, 0, "NMI - XMON", 0);
+       request_irq(20, xmon_irq, 0, "NMI - XMON", NULL);
 #endif /* CONFIG_XMON */
 }