public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC] ARM: OMAP: handle lazy IRQ disable properly
@ 2006-04-02 20:04 Imre Deak
       [not found] ` <1147882410.22799.5.camel@orphique>
  0 siblings, 1 reply; 6+ messages in thread
From: Imre Deak @ 2006-04-02 20:04 UTC (permalink / raw)
  To: Yrjola Juha (Nokia-M/Helsinki); +Cc: linux-omap

[-- Attachment #1: Type: text/plain, Size: 1094 bytes --]

GPIO IRQs can't be disabled at the moment, since the ARM lazy IRQ
masking is not handled properly by the current GPIO IRQ handler.

Implementing it properly would solve the following issues, which the
standard do_edge_IRQ, do_level_IRQ handlers already do:

- Account for disable_irq delaying the IRQ masking till the next
  interrupt. The IRQ dispatcher should check whether the IRQ line is
  disabled through irq_desc.disable_depth and if so it should not call
  the IRQ handler and should leave the IRQ masked. enable_irq will do
  later the unmasking.

- Try to avoid lost edge triggered interrupts. We won't reenter an
  already running IRQ handler, but will call it again in the next
  iteration of the IRQ dispatch loop.

- Avoid a possible stack overflow. This can happen when the next 
  interrupt is generated before the device driver gets the chance to
  act upon the first interrupt. Since we run edge triggered IRQ handlers
  unmasked this could lead to an unbounded recursion in the IRQ 
  dispatcher. This is at least the case with the ads7846 touchscreen
  controller.

--Imre


[-- Attachment #2: omap-gpio_disable_lazy-patch.diff --]
[-- Type: text/x-patch, Size: 1654 bytes --]

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index d3c8ea7..642f5eb 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -736,6 +736,7 @@ static void gpio_irq_handler(unsigned in
 	u32 isr;
 	unsigned int gpio_irq;
 	struct gpio_bank *bank;
+	u32 retrigger = 0;
 
 	desc->chip->ack(irq);
 
@@ -785,16 +786,49 @@ static void gpio_irq_handler(unsigned in
 		if (!level_mask)
 			desc->chip->unmask(irq);
 
+		isr |= retrigger;
+		retrigger = 0;
 		if (!isr)
 			break;
 
 		gpio_irq = bank->virtual_irq_start;
 		for (; isr != 0; isr >>= 1, gpio_irq++) {
 			struct irqdesc *d;
+			int irq_mask;
 			if (!(isr & 1))
 				continue;
 			d = irq_desc + gpio_irq;
+			/* Don't run the handler if it's already running
+			 * or was disabled lazely.
+			 */
+			if (unlikely((d->disable_depth || d->running))) {
+				irq_mask = 1 <<
+					(gpio_irq - bank->virtual_irq_start);
+				/* The unmasking will be done by
+				 * enable_irq in case it is disabled or
+				 * after returning from the handler if
+				 * it's already running.
+				 */
+				_enable_gpio_irqbank(bank, irq_mask, 0);
+				if (!d->disable_depth) {
+					/* Level triggered interrupts
+					 * won't ever be reentered
+					 */
+					BUG_ON(level_mask & irq_mask);
+					d->pending = 1;
+				}
+				continue;
+			}
+			d->running = 1;
 			desc_handle_irq(gpio_irq, d, regs);
+			d->running = 0;
+			if (unlikely(d->pending && !d->disable_depth)) {
+				irq_mask = 1 <<
+					(gpio_irq - bank->virtual_irq_start);
+				d->pending = 0;
+				_enable_gpio_irqbank(bank, irq_mask, 1);
+				retrigger |= irq_mask;
+			}
 		}
 
 		if (cpu_is_omap24xx()) {

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-05-27  0:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-02 20:04 [RFC] ARM: OMAP: handle lazy IRQ disable properly Imre Deak
     [not found] ` <1147882410.22799.5.camel@orphique>
2006-05-17 18:14   ` Imre Deak
2006-05-17 18:33     ` Imre Deak
2006-05-24 11:55       ` [PATCH] ARM: OMAP: fix GPIO IRQ mask handling [was Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly] Imre Deak
2006-05-26 22:59         ` Tony Lindgren
2006-05-27  0:22           ` David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox