[Cbe-oss-dev] [RFC/PATCH] adding support for direct MBX interrupt on Axon based platform.
Jean-Christophe Dubois
jdubois at mc.com
Sun May 20 04:39:40 EST 2007
Ok, here is the second proposal using the translation interrupt class (class
1) while SLOF programs it using the application interrupt class (class 2).
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.21/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-2.6.21.orig/arch/powerpc/platforms/cell/setup.c
+++ linux-2.6.21/arch/powerpc/platforms/cell/setup.c
@@ -104,6 +104,42 @@ static void cell_mpic_cascade(unsigned i
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,98 @@ static void __init mpic_init_IRQ(void)
}
}
+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 attached
+ int node = 0;
+ unsigned long root = of_get_flat_dt_root();
+
+ /* check for the platform */
+ if (!of_flat_dt_is_compatible(root, "IBM,CBEA") &&
+ !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
+ return;
+
+ for (dn = NULL;
+ (dn = of_find_node_by_name(dn, "c3po"));node++) {
+ unsigned int virq;
+ int hw_int;
+ int iic_int;
+ int ioif = 0; /* Fallback to 0 if bad prop in dev-tree */
+ struct device_node *pdn = of_get_parent(dn);
+ u32 *ptr = NULL;
+ unsigned long c3po_base;
+ int ioif_len;
+ u32 *ioif_prop;
+ unsigned long *axon_reg;
+ unsigned long *c3po_reg;
+
+ if (pdn == NULL)
+ continue;
+
+ ioif_prop = (u32*) get_property(pdn, "ioif",&ioif_len);
+ axon_reg = (unsigned long *) get_property(pdn, "reg", NULL);
+ c3po_reg = (unsigned long *) get_property(dn, "reg", NULL);
+
+
+ if (!axon_reg | !c3po_reg) {
+ of_node_put(pdn);
+ continue;
+ }
+
+ if ( ioif_prop && ioif_len == 4 )
+ ioif = *ioif_prop;
+
+ /* compute the C3PO CPU address */
+ c3po_base = (*axon_reg) + (*c3po_reg & 0xffffffffffULL);
+
+ of_node_put(pdn);
+
+ /* remap the interrupt info part */
+ ptr = ioremap(c3po_base + 0x0828L, sizeof(u32) * 4);
+
+ if (ptr == NULL)
+ continue;
+
+ /* set the MBX direct int class to 1 */
+ *(ptr + 2) = (*(ptr + 2) & 0x0fffffff ) | 0x50000000;
+
+ iounmap(ptr);
+
+ hw_int = (node * 256) + 136 + ioif;
+ iic_int = (node << IIC_IRQ_NODE_SHIFT) |
+ (1 << IIC_IRQ_CLASS_SHIFT) |
+ (ioif?0xb:0);
+
+ 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