[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