HELP PLEASE: i2c in interrupt?

From: Abraham vd Merwe
Date: Wed Sep 17 2003 - 13:13:07 EST


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@xxxxxxxxxxxx

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/