Jivin Wolfgang Wegner lays it down ...
> Hi,
> 
> On Mon, Apr 07, 2008 at 07:13:48AM +1000, David McCullough wrote:
> > 
> > Jivin Wolfgang Wegner lays it down ...
> > > In my I2C driver, the code is the following:
> > > 
> > > static
> > > irqreturn_t coldfire_i2c_interrupt(int irq, void *dev_id)
> > > {
> > >   /* check if we are called with the correct IRQ number */
> > >   if(irq != (MCFINT_VECBASE + MCFINT_I2C))
> > >     return IRQ_NONE;
> > > 
> > >   /* check if I2C int flag is set and send the event to waiting queue */
> > >   if(*MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) {
> > >           *MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;
> > >           atomic_set(&coldfire_i2c_irq_happened, 1);
> > >           wake_up_interruptible(&coldfire_i2c_queue);
> > >   }
> > >   return IRQ_HANDLED;
> > > }
> > > 
> > > static int coldfire_wait_transfer(void) {
> > > 
> > >   int timeout;
> > > 
> > >   /* wait for data transfer to complete */
> > >   timeout = wait_event_interruptible_timeout(coldfire_i2c_queue,
> > >                                              1 == 
> > > atomic_read(&coldfire_i2c_irq_happened),
> > >                                              COLDFIRE_I2C_TIMEOUT);
> > > 
> > 
> > What happens if you get an interrupt between here ...
> > 
> > >   if ((timeout <= 0 ) || (*MCF_I2C_I2SR & MCF_I2C_I2SR_IAL)) {
> > >           printk("wt: timeout = %d, I2SR = %x\n, ih = %d",timeout, 
> > > *MCF_I2C_I2SR, atomic_read(&coldfire_i2c_irq_happened));
> > >           return -1;
> > >   }
> > >   else {
> > 
> > And here ?  Won't coldfire_i2c_irq_happened get cleared when an
> > interrupt service is pending ?
> 
> you are right, this is a problem that could happen in theory - but on
> the other hand there should be one and exactly one interrupt while waiting
> for the transfer to complete, so I can not see where the other execution
> thread triggering the second interrupt should come from.


Trace and make sure it isn't.  I don't know the HW,  are you acking the
interrupt or stopping further interrupts ?


> > Just check the HW in coldfire_wait_transfer,
> > 
> >     while (1) {
> >             spinlock_irq(xxx)
> >             irqpending = (*MCF_I2C_I2SR & MCF_I2C_I2SR_IAL);
> >             spinunlock_irq(xxx)
> >             if (irqpending) {
> >                     /* remember to protect HW register accesses in here */
> >                     service interrupt
> >             }
> >     }
> 
> Well, maybe I got it wrong, but to me this looks like a busy wait,

It is,  but you aren't doing the work in your interrupt rouinte,
and normally (ie., good practice) you would be limiting the number of
times it can loop with a work counter or similar.  Check out some network
dirvers for examples.

> which is clearly not what I want a 200+ MHz processor to do while
> waiting for a slow bus like I2C.

It's only busy while there are interrupts pending on the device.  If the
bus is slow you will easily pull everything out of the chip and exit for
further processing before the next interrupt comes along and wakes it up.

Cheers,
Davidm

-- 
David McCullough,  [EMAIL PROTECTED],   Ph:+61 734352815
Secure Computing - SnapGear  http://www.uCdot.org http://www.cyberguard.com
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to