Hi!

I'm trying to fix a problem in an embedded device. The kernel is a
2.4.19, the processor an ARM-based OMAP1510 and the only information I
have is that in those devices suffering from the problem there is a
broken quartz. The problem is that the device will freeze when the
keypad is pressed too rapidly which leads me to the assumption that
it's the 32kHz quartz used for filtering key presses which is broken
(if it was the system clock, those devices probably wouldn't run at
all). My theory is that the filtering of the key presses doesn't work
which is why a lot of irqs for the keypad are fired at the linux kernel
if the keypad is pressed too rapidly.

I could solve this problem for the case that the device was in suspend
mode (waiting to be woke up via the keypad) by disabling the keypad irq
right at its hardware source for one second after every key press which
seems to assert my theory. Now the only problem remaining is that in
normal operation the portion of code that takes care of the suspend
mode is not active, hence I need to apply a similar solution to the
normal irq handling.

So what I want to do is disable the irq for the keypad for a certain
timespan every time it occurs which would be more or less equivalent to
a low-pass filtering of the keypad-input.

I have tried this from within the keypad driver. There, in the
irq-handler itself I disabled the irq for a certain timespan using a
kernel timer for re-enabling the irq. In this way I could drop the key
press rate as desired e.g. to just one key press every three seconds.
However, the broken device still crashes if the keypad is pressed too
rapidly no matter how long I set the minimum timespan between to
subsequent irqs...

I now figured that due to the software irq approach in the linux kernel
I would have to disable the irq right in the main irq handler. However,
this is where I'm stuck (Im not at all a kernel guru). I believe that
the file ./arch/arm/kernel/irq.c is the one I need to look at.
Unfortunately, I don't really understand it.

Could anybody please confirm that "do_IRQ()" in ./arch/arm/kernel/irq.c
is the function that is called directly in hardware irq context? If
not, where do I have to look for that? Any other input?


Many thanks in advance!

Philipp Boerker.