[PATCH] ipic: change ack operation that register is accessed only when needed

Benjamin Herrenschmidt benh at kernel.crashing.org
Tue Dec 4 08:02:27 EST 2007


>  static void ipic_ack_irq(unsigned int virq)
>  {
> -	struct ipic *ipic = ipic_from_irq(virq);
>  	unsigned int src = ipic_irq_to_hw(virq);
> -	unsigned long flags;
> -	u32 temp;
>  
> -	spin_lock_irqsave(&ipic_lock, flags);
> +	/* Only external interrupts in edge mode support ACK */
> +	if (unlikely(ipic_info[src].ack &&
> +			((get_irq_desc(virq)->status & IRQ_TYPE_SENSE_MASK) ==
> +			IRQ_TYPE_EDGE_FALLING))) {
> +		struct ipic *ipic = ipic_from_irq(virq);
> +		unsigned long flags;
> +		u32 temp;
>  
> -	temp = ipic_read(ipic->regs, ipic_info[src].pend);
> -	temp |= (1 << (31 - ipic_info[src].bit));
> -	ipic_write(ipic->regs, ipic_info[src].pend, temp);
> +		spin_lock_irqsave(&ipic_lock, flags);
>  
> -	spin_unlock_irqrestore(&ipic_lock, flags);
> +		temp = ipic_read(ipic->regs, ipic_info[src].ack);
> +		temp |= (1 << (31 - ipic_info[src].bit));
> +		ipic_write(ipic->regs, ipic_info[src].ack, temp);
> +
> +		spin_unlock_irqrestore(&ipic_lock, flags);
> +	}
>  }

That doesn't look right... 

That should be handled by the higher level flow handler. The generic
edge one calls ack and the level one mask_and_ack. Just make them do the
right thing, no need to test for the flow type in the low level
function.

Ben.





More information about the Linuxppc-dev mailing list