Messages in this thread | ![/](/images/icornerl.gif) | | Date | Wed, 17 Sep 2003 20:11:38 +0200 | From | Abraham vd Merwe <> | Subject | HELP PLEASE: i2c in interrupt? |
| |
Hi!
I'm working on a keypad driver which is sitting on an I/O expander on an I2C bus. Whenever a key is pressed, the I2C chip (the I/O expander) generates an interrupt and then I have to read the events from the I2C chip.
The problem is
(a) This operation is time critical. If I don't read the data from the I2C chip very fast (after the interrupt occurred) the events get lost
(b) I2C is done in hardware which means a read goes like this: START WRITE_DATA wait_for_interrupt ... STOP.
The important part here is the wait_for_interrupt. That means i2c_transfer() will wait on a wait queue which I can't do from an interupt so I created a task to do this for me and from the keypad interrupt routine, I do
queue_task (&keypad.task,&tq_immediate); mark_bh (IMMEDIATE_BH);
However that triggers a BUG
------------< snip <------< snip <------< snip <------------ Scheduling in interrupt kernel BUG at sched.c:566! Unable to handle kernel NULL pointer dereference at virtual address 00000000 ------------< snip <------< snip <------< snip <------------
so it is obviously illegal to do that from an interrupt. So my question is, how do I execute a function which will sleep _very_soon_ after an interrupt occurs (i.e. what I don't want to do is interrupt -> poll wakes up -> process does read -> i2c_transfer() - that's too long)
--
Regards Abraham
You will not be elected to public office this year.
___________________________________________________ Abraham vd Merwe - Frogfoot Networks CC 9 Kinnaird Court, 33 Main Street, Newlands, 7700 Phone: +27 21 686 1665 Cell: +27 82 565 4451 Http: http://www.frogfoot.net/ Email: abz@frogfoot.net
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |