Jivin Wolfgang Wegner lays it down ...
> Hi,
>
> after I solved the startup problem I could now investigate another
> thing.
>
> From time to time, I have problems with some drivers (namely QSPI
> in interrupt mode and my self-hacked I2C driver in interrupt mode)
> getting stuck when sleeping on a waitqueue. This happens on an
> MCF5373L, using the code for MCF532x as they are compatible except
> the additional devices on MCF532x.
>
> 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 ?
> atomic_set(&coldfire_i2c_irq_happened, 0);
> return 0;
> }
> };
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
}
}
You can probably do away with coldfire_i2c_irq_happened, which will
make it easier to get the code right :-)
Cheers,
Davidm
> From time to time, the timeout happens and I get the message:
>
> wt: timeout = 0, I2SR = a0, ih = 1
>
> So obviously the interrupt happens and is correctly handled, but the
> waitqueue is not awoken.
>
> Did anybody else experience such a problem, or is it again something
> peculiar to my setup?
--
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