[PATCH/2.6.17-rc4 4/10]Powerpc: Add tsi108 pic support

Kumar Gala galak at kernel.crashing.org
Wed May 31 05:18:14 EST 2006


On May 29, 2006, at 10:28 PM, Zang Roy-r61911 wrote:

>>
>> On Wed, 2006-05-17 at 18:14 +0800, Zang Roy-r61911 wrote:
>>> Add Tundra Semiconductor tsi108 host bridge interrupt
>> controller support.
>>
>> It looks a bit like an hacked up MPIC... Is it different
>> enough to justify a separate driver ? Or would it be possible
>> to define a TSI108 flag to pass the current mpic driver and
>> add the necessary bits to it ?
>>
>
> Tsi108 implementation of MPIC has many differences form the  
> original one,  the following
> code implements it with mpic. Any comment? The following patch is  
> just based on
> my previous send out patches.

In the future please provide it against the base, much easier to read.

> Integrate Tundra Semiconductor tsi108 host bridge interrupt controller
> to mpic arch.
>
> Signed-off-by: Alexandre Bounine <alexandreb at tundra.com>
>

[snip]

>
> --- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/mpic.c	2006-03-20  
> 00:53:29.000000000 -0500
> +++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/mpic.c	2006-05-29  
> 16:07:03.000000000 -0400
> @@ -81,7 +81,7 @@ static inline void _mpic_write(unsigned
>  static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
>  {
>  	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
> -	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> +	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi *  
> MPIC_GREG_IPI_STRIDE);
>
>  	if (mpic->flags & MPIC_BROKEN_IPI)
>  		be = !be;
> @@ -90,7 +90,7 @@ static inline u32 _mpic_ipi_read(struct
>
>  static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int  
> ipi, u32 value)
>  {
> -	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> +	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi *  
> MPIC_GREG_IPI_STRIDE);
>
>  	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset,  
> value);
>  }
> @@ -393,7 +393,11 @@ static inline struct mpic * mpic_from_ir
>  static inline void mpic_eoi(struct mpic *mpic)
>  {
>  	mpic_cpu_write(MPIC_CPU_EOI, 0);
> +#ifndef CONFIG_TSI108_BRIDGE
>  	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
> +#else
> +	(void)mpic_cpu_read(MPIC_CPU_OUTPUT);
> +#endif
>  }
>
>  #ifdef CONFIG_SMP
> @@ -514,9 +518,26 @@ static void mpic_end_irq(unsigned int ir
>  	}
>  #endif /* CONFIG_MPIC_BROKEN_U3 */
>
> +#ifdef CONFIG_TSI108_BRIDGE
> +	if ((irq_desc[irq].status & IRQ_LEVEL) != 0)
> +#endif

Why do you have to check if its a LEVEL irq?

>  	mpic_eoi(mpic);
>  }
>
> +#ifdef CONFIG_TSI108_BRIDGE
> +static void mpic_ack_irq(unsigned int irq)
> +{
> +	struct mpic *mpic = mpic_from_irq(irq);
> +
> +#ifdef DEBUG_IRQ
> +	DBG("%s: ack_irq: %d\n", mpic->name, irq);
> +#endif
> +
> +	if ((irq_desc[irq].status & IRQ_LEVEL) == 0)
> +		mpic_eoi(mpic);
> +}
> +#endif /* CONFIG_TSI108_BRIDGE */
> +

if the PIC works like other openpic's you dont need an 'ack' we  
handle it via 'end'

>  #ifdef CONFIG_SMP
>
>  static void mpic_enable_ipi(unsigned int irq)
> @@ -596,6 +617,9 @@ struct mpic * __init mpic_alloc(unsigned
>  	mpic->hc_irq.enable = mpic_enable_irq;
>  	mpic->hc_irq.disable = mpic_disable_irq;
>  	mpic->hc_irq.end = mpic_end_irq;
> +#ifdef CONFIG_TSI108_BRIDGE
> +	mpic->hc_irq.ack = mpic_ack_irq;
> +#endif
>  	if (flags & MPIC_PRIMARY)
>  		mpic->hc_irq.set_affinity = mpic_set_affinity;
>  #ifdef CONFIG_SMP
> @@ -955,8 +979,13 @@ void mpic_send_ipi(unsigned int ipi_no,
>  	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
>  #endif
>
> +#ifndef CONFIG_TSI108_BRIDGE
>  	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
>  		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
> +#else /* CONFIG_TSI108_BRIDGE */
> +	mpic_write(mpic->gregs, MPIC_CPU_IPI_DISPATCH,
> +		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
> +#endif /* !CONFIG_TSI108_BRIDGE */
>  }
>
>  int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
> @@ -972,11 +1001,20 @@ int mpic_get_one_irq(struct mpic *mpic,
>  		DBG("%s: cascading ...\n", mpic->name);
>  #endif
>  		irq = mpic->cascade(regs, mpic->cascade_data);
> +#ifdef DEBUG_LOW
> +		DBG("%s: cascaded irq: %d\n", mpic->name, irq);
> +#endif
> +#ifndef CONFIG_TSI108_BRIDGE
>  		mpic_eoi(mpic);
> +#endif
>  		return irq;
>  	}
> -	if (unlikely(irq == MPIC_VEC_SPURRIOUS))
> +	if (unlikely(irq == MPIC_VEC_SPURRIOUS)) {
> +#ifdef CONFIG_TSI108_BRIDGE
> +		mpic_eoi(mpic);
> +#endif
>  		return -1;
> +	}

why the changes to where we do mpic_eoi for TSI108?

>  	if (irq < MPIC_VEC_IPI_0) {
>  #ifdef DEBUG_IRQ
>  		DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset);



[snip]



More information about the Linuxppc-dev mailing list