gpio: pch9: Use proper flow type handlers
authorThomas Gleixner <tglx@linutronix.de>
Sat, 28 Apr 2012 08:13:45 +0000 (10:13 +0200)
committerGrant Likely <grant.likely@secretlab.ca>
Sat, 12 May 2012 00:18:50 +0000 (18:18 -0600)
commitdf9541a60af0985c3a756dc5f99b9253d2565a07
treedb404b9bc490968251c4f250c74733965b28ea93
parent6edd94db250038c8fdf176f23ca4017d2f312509
gpio: pch9: Use proper flow type handlers

Jean-Francois Dagenais reported:

 Configuring a gpio pin with the gpio-pch driver with
 "IRQF_TRIGGER_LOW | IRQF_ONESHOT" generates an interrupt storm for
 threaded ISR until the ISR thread actually gets to physically clear
 the interrupt on the triggering chip!! The immediate observable
 symptom is the high CPU usage for my ISR thread task and the
 interrupt count in /proc/interrupts incrementing radically.

The driver is wrong in several ways:

1) Using handle_simple_irq() does not provide proper flow control
   handling. In the case of oneshot threaded handlers for the
   demultiplexed interrupts this results in an interrupt storm because
   the simple handler does not deal with masking/unmasking.  Even
   without threaded oneshot handlers an interrupt storm for level type
   interrupts can easily be triggered when the interrupt is disabled
   and the interrupt line is activated from the device.

2) Acknowlegding the demultiplexed interrupt before calling the
   handler is wrong for level type interrupts.

3) The set_type function unconditionally enables the interrupt. It's
   supposed to set the type and nothing else. The unmasking is done by
   the core code.

Move the acknowledge code into a separate function and add it to the
demux irqchip callbacks.

Remove the unconditional enabling from the set_type() callback and set
the proper flow handlers depending on the selected type (level/edge).

Reported-and-tested-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
drivers/gpio/gpio-pch.c