[Cbe-oss-dev] [RFC/PATCH] adding support for direct MBX interrupt on Axon based platform.

Jean-Christophe Dubois jdubois at mc.com
Fri May 18 21:36:30 EST 2007


This patch allows Linux to support the Mailbox direct interrupt that is left 
out in the actual SLOF device tree.

This patch has been tested on the CAB and the Malta blade with 2.6.20 and 
2.6.21 kernels.

Signed-Off-by: Jean-Christophe DUBOIS <jdubois at mc.com>

Index: linux-2.6.20/arch/powerpc/platforms/cell/interrupt.c
===================================================================
--- linux-2.6.20.orig/arch/powerpc/platforms/cell/interrupt.c	2007-02-04 
19:44:54.000000000 +0100
+++ linux-2.6.20/arch/powerpc/platforms/cell/interrupt.c	2007-03-28 
16:35:17.000000000 +0200
@@ -64,6 +64,22 @@
 	unsigned char node = bits.source >> 4;
 	unsigned char class = bits.class & 3;
 
+	/*
+	 * This is a special case for the Axon direct interrupt.
+	 * The direct interrupt is characterized by a priority set to 8
+	 * But the priority is not used to generate the hwnum
+	 * So here is a little hack.
+	 */
+	if ((unit == 0x0 || unit == 0xb) && (class == 2)
+	    && ((bits.prio>>4)  == 8)) {
+		/*
+		 * in order to discriminate the direct MBX we change the
+		 * unit for an unused value:
+		 * 0xc for IOIF0 and 0xd for IOIF1
+		 */
+		unit = unit?0xd:0xc;
+	}
+
 	/* Decode IPIs */
 	if (bits.flags & CBE_IIC_IRQ_IPI)
 		return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
@@ -93,7 +109,6 @@
 	.eoi = iic_eoi,
 };
 
-
 static void iic_ioexc_eoi(unsigned int irq)
 {
 }
@@ -130,7 +145,6 @@
 	desc->chip->eoi(irq);
 }
 
-
 static struct irq_chip iic_ioexc_chip = {
 	.typename = " CELL-IOEX",
 	.mask = iic_mask,
Index: linux-2.6.20/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-2.6.20.orig/arch/powerpc/platforms/cell/setup.c	2007-03-28 
16:34:37.000000000 +0200
+++ linux-2.6.20/arch/powerpc/platforms/cell/setup.c	2007-03-28 
16:35:17.000000000 +0200
@@ -104,6 +104,42 @@
 	desc->chip->eoi(irq);
 }
 
+static void c3po_mask(unsigned int irq)
+{
+}
+
+static void c3po_unmask(unsigned int irq)
+{
+}
+
+static void c3po_eoi(unsigned int irq)
+{
+}
+
+static void c3po_ack(unsigned int irq)
+{
+}
+
+static struct irq_chip c3po_chip = {
+	.typename = " AXON-C3PO",
+	.mask = c3po_mask,
+	.unmask = c3po_unmask,
+	.ack = c3po_ack,
+	.eoi = c3po_eoi,
+};
+
+static void c3po_irq_cascade(unsigned int irq, struct irq_desc *desc)
+{
+	int hw_int = (int)desc->handler_data;
+	unsigned int virq = irq_find_mapping(NULL, hw_int);
+
+	if (virq != NO_IRQ) {
+		generic_handle_irq(virq);
+	}
+
+	desc->chip->eoi(irq);
+}
+
 static void __init mpic_init_IRQ(void)
 {
 	struct device_node *dn;
@@ -134,12 +170,66 @@
 	}
 }
 
+static void __init c3po_init_IRQ(void)
+{
+	struct device_node *dn;
+	// We need a way to find out the cell/node to which the c3po is qttqched
+	int node = 0;
+
+	for (dn = NULL;
+	     (dn = of_find_node_by_name(dn, "c3po"));node++) {
+		unsigned int virq;
+		int hw_int;
+		int iic_int;
+		u32 *prop;
+		int len;
+
+		int ioif = 0; /* Fallback to 0 if bad prop in dev-tree */
+		struct device_node *pdn = of_get_parent(dn);
+
+		if (pdn) {
+			prop = (u32*) get_property(pdn, "ioif",&len);
+			if ( prop && len == 4 )
+				ioif = *prop;
+
+			of_node_put(pdn);
+		}
+
+		hw_int = (node * 256) + 136 + ioif;
+		iic_int = (node << IIC_IRQ_NODE_SHIFT) |
+			      (2 << IIC_IRQ_CLASS_SHIFT) |
+			      (0xc + ioif);
+
+		printk(KERN_INFO "c3po: ioif=%d, hw_int=%d, iic_int=%d \n",
+				ioif, hw_int, iic_int);
+
+		// We add the direct MBOX interrupt
+		virq = irq_create_mapping(NULL, iic_int);
+		if (virq == NO_IRQ)
+			continue;
+
+		set_irq_data(virq, (void *)hw_int);
+
+		set_irq_chained_handler (virq, c3po_irq_cascade);
+
+		virq = irq_create_mapping(NULL, hw_int);
+		if (virq == NO_IRQ)
+			continue;
+
+		set_irq_chip_and_handler(virq, &c3po_chip, handle_edge_irq);
+
+		set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+
+	}
+}
+
 
 static void __init cell_init_irq(void)
 {
 	iic_init_IRQ();
 	spider_init_IRQ();
 	mpic_init_IRQ();
+	c3po_init_IRQ();
 }
 
 static void __init cell_setup_arch(void)






More information about the cbe-oss-dev mailing list