[PATCH] ipic: change ack operation that register is accessedonly when needed
Li Yang
LeoLi at freescale.com
Tue Dec 4 13:06:47 EST 2007
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh at kernel.crashing.org]
> Sent: Tuesday, December 04, 2007 5:02 AM
> To: Li Yang
> Cc: galak at kernel.crashing.org; linuxppc-dev at ozlabs.org
> Subject: Re: [PATCH] ipic: change ack operation that register
> is accessedonly when needed
>
>
> > 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.
But actually ack is called by edge and per cpu handlers. Mask_and_ack
is also called by edge handler when the same interrupt is already in
progress. So I don't think that ack/mask_and_ack implicates flow type
by design.
- Leo
More information about the Linuxppc-dev
mailing list