[PATCH 2/2] genirq: move mask_cache into struct irq_chip_type

Thomas Gleixner tglx at linutronix.de
Fri Mar 15 16:47:23 EDT 2013


Gerlando,

On Fri, 15 Mar 2013, Gerlando Falauto wrote:

> This fixes a regression introduced by e59347a
> "arm: orion: Use generic irq chip".
> 
> The same interrupt mask cache (stored within struct irq_chip_generic)
> is shared between all the irq_chip_type instances. As each irq_chip_type
> can use a distinct mask register, sharing a single mask cache may not be
> correct. For instance in the case of Orion SoCs, which have separate
> mask registers for edge and level interrupts.
> 
> This patch moves mask_cache from struct irq_chip_generic into struct
> irq_chip_type. Note that the interrupt support for Samsung SoCs is also
> slightly affected.

The patch is correct, but we want a more incremental approach.

Step 1: 
     Add the pointer and the mask_cache to ct
     init all ct->pointers in the setup code to gc->mask_cache
     switch core code over to use the ct->pointer

     Functional equivilent!

Step 2:
     Convert each user out of core to the ct->pointer (separate patches)

     Functional equivilent!

Step 3:
     Rename gc->mask_cache to gc->shared_mask_cache

     And we keep that instead of using ct[0].mask_cache simply because
     it makes the code simpler to understand.

Step 4:
     Add the extra flag and the initializer for the separate mask_caches

Step5:
     Convert the affected SOCs (separate patches)

Otherwise I only have a coding style related request:

> @@ -246,9 +246,21 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
>  	list_add_tail(&gc->list, &gc_list);
>  	raw_spin_unlock(&gc_lock);
>  
> -	/* Init mask cache ? */
> -	if (flags & IRQ_GC_INIT_MASK_CACHE)
> -		gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask);
> +	for (i = 0; i < gc->num_ct; i++) {
> +		if (flags & IRQ_GC_SEPARATE_MASK_REGISTERS)
> +			/* Define mask cache pointer */
> +			ct[i].pmask_cache = &ct[i].mask_cache;
> +		else
> +			/* They all point to the same mask cache */
> +			ct[i].pmask_cache = &ct[0].mask_cache;
> +
> +		/* Init mask cache ? */
> +		if ((flags & IRQ_GC_INIT_MASK_CACHE)
> +		 && ((flags & IRQ_GC_SEPARATE_MASK_REGISTER)
> +		  || (i == 0)))
> +			*ct[i].pmask_cache =
> +				irq_reg_readl(gc->reg_base + ct[i].regs.mask);
> +	}

My eyes are burning, my head is spinning and I have a hard time not to
use swearwords.

	bool mskperct = flags & IRQ_GC_SEPARATE_MASK_REGISTERS;
	bool mskinit = flags & IRQ_GC_INIT_MASK_CACHE;
	u32 *shmsk = &gc->shared_mask_cache;

	if (!mskperct && mskinit)
	     	*shmsk = irq_reg_readl(gc->reg_base + ct->regs.mask);

	for (i = 0; i < gc->num_ct: i++, ct++) {
	       ct->pmask_cache = mskperct ? &ct->mask_cache : shmsk;
	       
	       if (mskperct && mskinit)
	       	  	ct->mask_cache = irq_reg_readl(gc->reg_base +
				       	 	       ct->regs.mask);
	}

Or something like that, perhaps ?

Thanks,

	tglx



More information about the linux-arm-kernel mailing list