[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