public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@nokia.com>
To: "Yrjola Juha (Nokia-M/Helsinki)" <Juha.Yrjola@nokia.com>
Cc: linux-omap <linux-omap-open-source@linux.omap.com>
Subject: [RFC] ARM: OMAP: handle lazy IRQ disable properly
Date: Sun, 02 Apr 2006 23:04:27 +0300	[thread overview]
Message-ID: <1144008267.8058.58.camel@bitbox.mine.nu> (raw)

[-- 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 --]



             reply	other threads:[~2006-04-02 20:04 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-02 20:04 Imre Deak [this message]
     [not found] ` <1147882410.22799.5.camel@orphique>
2006-05-17 18:14   ` [RFC] ARM: OMAP: handle lazy IRQ disable properly 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1144008267.8058.58.camel@bitbox.mine.nu \
    --to=imre.deak@nokia.com \
    --cc=Juha.Yrjola@nokia.com \
    --cc=linux-omap-open-source@linux.omap.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox