If its very slow hardware then that might explain your problem. You
would be sitting with interrupts off for a very long time. What really
makes the difference to how you handle it is - if the irq is shared, and
how easy it is to block.
If it is not shared, or can be blocked fast then you end up with code
that basically says
irq_handler
block irq
set work_to_do
kick off a tasklet
return
and take care in the tasklet to avoid blocking IRQ's during the actual
reads from the chip. You might do something like
if(!test_and_set_bit(0, &chip_do_read))
{
add_read_to_queue();
reenable_int
}
else
set_bit(1, &chip_do_read);
and elsewhere where you touch that data or might lock against it do
set_bit(0, &chip_do_read);
/* Above maybe code that waits politely for that.. */
blah
blah
/* Now clean up */
if(test_bit(1, &chip_do_read)) /* Poll deferred */
{
clear_bit(1, &chip_do_read);
add_read_to_queue();
clear_bit(0, &chip_do_read);
reeanable_int
}
else
clear_bit(0, &chip_do_read);
or use xchg, or atomic_t counters
-
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/