[Cbe-oss-dev] [RFC/PATCH] adding support for direct MBX interrupt on Axon based platform.
Jean-Christophe Dubois
jdubois at mc.com
Sat May 19 00:49:09 EST 2007
On Friday 18 May 2007 16:09:19 Arnd Bergmann wrote:
> Hi JC,
>
> Thanks for sending out this patch, I know people have been waiting
> for it. I never understood how it's wired and how it should be
> in the device-tree, this makes things much clearer.
>
> I think the mpic device node actually should be changed to point to
> the c3po as its parent, but that would mean that you can't boot
> an old linux kernel on a new device tree, because the code to
> handle c3po is missing there.
>
> Is the priority the only way you can distinguish mpic interrupts
> from non-mpic ones?
The programmable parts for a C3PO interrupt are: class, destination node,
destination thread on the node and priority. The SLOF firmware just change
the prirority for the 4 possible interrupts generated by the C3PO (MPIC
machine check = 0, MPIC critical = 4, direct MBX = 8, MPIC normal = c).
According to the Cell manual, class = 2 is correct for external interrupts.
Class 0 and 1 are reserved for internal SPU/DMA error/translation cases. 3 is
reserved.
> On Friday 18 May 2007, Jean-Christophe Dubois wrote:
> > 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.
>
> Please open a bug report against the device tree when there is something
> missing. It's much easier to fix it in the right place than to keep
> ugly hacks around.
>
> Since CAB is now an official product, I wonder how such an obvious bug
> could slip through QA testing...
Well I asked the question at the time the device tree was submited to us but I
was told there was no consensus in the firmware team on how to handle the MBX
direct interrupt because it was not a usual MPIC and therefore it was
intentionaly left out.
> > 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);
>
> This is the wrong place for it, the IIC code should not need to know
> about specific external interrupt controllers.
Well sorry about it but this is the only place where I can check priority.
> > +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;
>
> You should check the "compatible" property to make sure you are on one of
> the known machines. Just looking for a device named "c3po" is a bit
> too vague.
OK even if today c3po is quite unique to the Axon. I'll add it.
> > + 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);
>
> This is wrong, the hw_int and iic_int numbers should come from the
> "interrupts" and "interrupt-parent" property of the device node you are
> looking at.
Well there is none for the direct MBX interrupt, so I had to make one. I am
hardcoding it to 128 (MPIC external interrupts) + 4 (MPIC IPIs) + 4 (MPIC
timers) = 136. Then I have to distinguish between IOIF0 (CAB case) and IOIF1
(Malta case).
JC
> Arnd <><
More information about the cbe-oss-dev
mailing list