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.

> 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,
which is clearly not what I want a 200+ MHz processor to do while
waiting for a slow bus like I2C.

Regards,
Wolfgang

_______________________________________________
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