[PATCH] powerpc: MPIC: support more than 256 sources
Michael Ellerman
michael at ellerman.id.au
Fri Jan 26 11:49:00 EST 2007
On Thu, 2007-01-25 at 15:38 -0600, Olof Johansson wrote:
> Allow more than the default 256 MPIC sources. Allocates a new flag
> (MPIC_LARGE_VECTORS) to be used by platform code when instantiating
> the mpic.
>
> I picked 11 bits worth right now since it would cover the number of
> sources on any hardware I have seen. It can always be increased later
> if needed.
>
>
> Signed-off-by: Olof Johansson <olof at lixom.net>
>
> Index: powerpc/arch/powerpc/sysdev/mpic.c
> ===================================================================
> --- powerpc.orig/arch/powerpc/sysdev/mpic.c
> +++ powerpc/arch/powerpc/sysdev/mpic.c
> @@ -496,13 +496,18 @@ static void __init mpic_scan_ht_pics(str
> static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
> {
> unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic;
>
> if (irq < NUM_ISA_INTERRUPTS)
> return NULL;
> +
> + mpic = irq_desc[irq].chip_data;
> +
> if (is_ipi)
> - *is_ipi = (src >= MPIC_VEC_IPI_0 && src <= MPIC_VEC_IPI_3);
> + *is_ipi = (src >= mpic->ipi_vecs[0] &&
> + src <= mpic->ipi_vecs[3]);
>
> - return irq_desc[irq].chip_data;
> + return mpic;
> }
>
> /* Convert a cpu mask from logical to physical cpu numbers. */
> @@ -540,7 +545,11 @@ static inline void mpic_eoi(struct mpic
> #ifdef CONFIG_SMP
> static irqreturn_t mpic_ipi_action(int irq, void *dev_id)
> {
> - smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0);
> + struct mpic *mpic;
> +
> + mpic = mpic_find(irq, NULL);
> + smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]);
> +
> return IRQ_HANDLED;
> }
> #endif /* CONFIG_SMP */
> @@ -663,7 +672,7 @@ static void mpic_end_ht_irq(unsigned int
> static void mpic_unmask_ipi(unsigned int irq)
> {
> struct mpic *mpic = mpic_from_ipi(irq);
> - unsigned int src = mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0;
> + unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
>
> DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
> mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
> @@ -807,11 +816,11 @@ static int mpic_host_map(struct irq_host
>
> DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
>
> - if (hw == MPIC_VEC_SPURRIOUS)
> + if (hw == mpic->spurious_vec)
> return -EINVAL;
>
> #ifdef CONFIG_SMP
> - else if (hw >= MPIC_VEC_IPI_0) {
> + else if (hw >= mpic->ipi_vecs[0]) {
> WARN_ON(!(mpic->flags & MPIC_PRIMARY));
>
> DBG("mpic: mapping as IPI\n");
> @@ -904,6 +913,7 @@ struct mpic * __init mpic_alloc(struct d
> u32 reg;
> const char *vers;
> int i;
> + int intvec_base;
> u64 paddr = phys_addr;
>
> mpic = alloc_bootmem(sizeof(struct mpic));
> @@ -914,9 +924,9 @@ struct mpic * __init mpic_alloc(struct d
> mpic->name = name;
> mpic->of_node = of_node_get(node);
>
> - mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 256,
> + mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size,
> &mpic_host_ops,
> - MPIC_VEC_SPURRIOUS);
> + flags & MPIC_LARGE_VECTORS ? 2048 : 256);
> if (mpic->irqhost == NULL) {
> of_node_put(node);
> return NULL;
> @@ -944,6 +954,21 @@ struct mpic * __init mpic_alloc(struct d
> mpic->irq_count = irq_count;
> mpic->num_sources = 0; /* so far */
>
> + if (flags & MPIC_LARGE_VECTORS)
> + intvec_base = 2039;
> + else
> + intvec_base = 247;
> +
> + mpic->timer_vecs[0] = intvec_base;
> + mpic->timer_vecs[1] = intvec_base+1;
> + mpic->timer_vecs[2] = intvec_base+2;
> + mpic->timer_vecs[3] = intvec_base+3;
> + mpic->ipi_vecs[0] = intvec_base+4;
> + mpic->ipi_vecs[1] = intvec_base+5;
> + mpic->ipi_vecs[2] = intvec_base+6;
> + mpic->ipi_vecs[3] = intvec_base+7;
> + mpic->spurious_vec = intvec_base+8;
It took me a minute to work out where 2039 and 247 came from, it might
be clearer as:
+ if (flags & MPIC_LARGE_VECTORS)
+ intvec_top = 2047;
+ else
+ intvec_top = 255;
+
+ mpic->timer_vecs[0] = intvec_top - 8;
+ mpic->timer_vecs[1] = intvec_top - 7;
+ mpic->timer_vecs[2] = intvec_top - 6;
+ mpic->timer_vecs[3] = intvec_top - 5;
+ mpic->ipi_vecs[0] = intvec_top - 4;
+ mpic->ipi_vecs[1] = intvec_top - 3;
+ mpic->ipi_vecs[2] = intvec_top - 2;
+ mpic->ipi_vecs[3] = intvec_top - 1;
+ mpic->spurious_vec = intvec_top;
Better still, can you get 255/2047 as (num_sources - 1) or something?
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20070126/c4fe17cd/attachment.pgp>
More information about the Linuxppc-dev
mailing list