* [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[parent not found: <1147882410.22799.5.camel@orphique>]
* Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly [not found] ` <1147882410.22799.5.camel@orphique> @ 2006-05-17 18:14 ` Imre Deak 2006-05-17 18:33 ` Imre Deak 0 siblings, 1 reply; 6+ messages in thread From: Imre Deak @ 2006-05-17 18:14 UTC (permalink / raw) To: ext Ladislav Michl; +Cc: linux-omap, Yrjola Juha (Nokia-M/Helsinki) [-- Attachment #1: Type: text/plain, Size: 877 bytes --] Hi, ext Ladislav Michl wrote: > On Sun, 2006-04-02 at 23:04 +0300, Imre Deak wrote: >> 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. > > Imre, > > I updated linux-omap git tree yesterday and found that it no longer > boots on VoiceBlue (5910) board; smc91x driver doesn't get any > interrupts. Reverting following commit made it work again. > > diff-tree e829dc78d9908b3949c2994b331c5279049b9098 > Author: Imre Deak <imre.deak@nokia.com> > Date: Thu May 11 16:13:42 2006 +0300 > > ARM: OMAP: GPIO IRQ lazy IRQ disable fix > > It is not exactly the same as the one you provided here, but it seems it > is based on it. I missed the fact that some OMAPs have IRQ mask others IRQ enable register.. Could you try it with the attached patch? --Imre > > Best regards, > ladis [-- Attachment #2: omap-gpio_irq_mask-patch.diff --] [-- Type: text/plain, Size: 997 bytes --] diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd1e508..0fb4081 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -540,19 +540,24 @@ static inline void _clear_gpio_irqstatus static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; + int inv = 0; + u32 mask; switch (bank->method) { case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; + inv = 1; break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; + inv = 1; break; case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQENABLE1; break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; + inv = 1; break; case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQENABLE1; @@ -562,7 +567,8 @@ static u32 _get_gpio_irqbank_mask(struct return 0; } - return __raw_readl(reg); + mask = __raw_readl(reg); + return inv ? !mask : mask; } static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) [-- Attachment #3: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly 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 0 siblings, 1 reply; 6+ messages in thread From: Imre Deak @ 2006-05-17 18:33 UTC (permalink / raw) To: ext Ladislav Michl; +Cc: linux-omap, Yrjola Juha (Nokia-M/Helsinki) [-- Attachment #1: Type: text/plain, Size: 1010 bytes --] Imre Deak wrote: > Hi, > > ext Ladislav Michl wrote: >> On Sun, 2006-04-02 at 23:04 +0300, Imre Deak wrote: >>> 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. >> >> Imre, >> >> I updated linux-omap git tree yesterday and found that it no longer >> boots on VoiceBlue (5910) board; smc91x driver doesn't get any >> interrupts. Reverting following commit made it work again. >> >> diff-tree e829dc78d9908b3949c2994b331c5279049b9098 Author: Imre Deak >> <imre.deak@nokia.com> >> Date: Thu May 11 16:13:42 2006 +0300 >> >> ARM: OMAP: GPIO IRQ lazy IRQ disable fix >> >> It is not exactly the same as the one you provided here, but it seems it >> is based on it. > > I missed the fact that some OMAPs have IRQ mask others IRQ enable > register.. Could you try it with the attached patch? > Or rather this one. Have to check the bank size as well and invert properly. --Imre > >> >> Best regards, >> ladis > [-- Attachment #2: omap-gpio_irq_mask-patch.diff --] [-- Type: text/plain, Size: 1071 bytes --] diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd1e508..beb1e1a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -540,29 +540,44 @@ static inline void _clear_gpio_irqstatus static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; + int inv = 0; + u32 l; + u32 mask; switch (bank->method) { case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; + mask = 0x0f; + inv = 1; break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; + mask = 0x0f; + inv = 1; break; case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQENABLE1; + mask = 0x0f; break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; + mask = 0xff; + inv = 1; break; case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQENABLE1; + mask = 0xff; break; default: BUG(); return 0; } - return __raw_readl(reg); + l = __raw_readl(reg); + if (inv) + l = ~l; + l &= mask; + return l; } static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) [-- Attachment #3: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] ARM: OMAP: fix GPIO IRQ mask handling [was Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly] 2006-05-17 18:33 ` Imre Deak @ 2006-05-24 11:55 ` Imre Deak 2006-05-26 22:59 ` Tony Lindgren 0 siblings, 1 reply; 6+ messages in thread From: Imre Deak @ 2006-05-24 11:55 UTC (permalink / raw) To: Tony Lindgren; +Cc: michl, linux-omap, Yrjola Juha (Nokia-M/Helsinki) [ Ignore the two previous ones they were both bogus:( I tested this on OMAP1510 innovator ] ARM: OMAP: fix GPIO IRQ mask handling The GPIO IRQ mask was retrieved incorrectly in cases where we have a mask register instead of an enable register. Also we should only return the valid bits depending on the bank size. This fixes a bug on 1510/1610 based OMAPs where GPIO IRQs are not delivered. Signed-off-by: Imre Deak <imre.deak@nokia.com> diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd1e508..e75a2ca 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -540,29 +540,44 @@ static inline void _clear_gpio_irqstatus static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; + int inv = 0; + u32 l; + u32 mask; switch (bank->method) { case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; + mask = 0xffff; + inv = 1; break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; + mask = 0xffff; + inv = 1; break; case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQENABLE1; + mask = 0xffff; break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; + mask = 0xffffffff; + inv = 1; break; case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQENABLE1; + mask = 0xffffffff; break; default: BUG(); return 0; } - return __raw_readl(reg); + l = __raw_readl(reg); + if (inv) + l = ~l; + l &= mask; + return l; } static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ARM: OMAP: fix GPIO IRQ mask handling [was Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly] 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 0 siblings, 1 reply; 6+ messages in thread From: Tony Lindgren @ 2006-05-26 22:59 UTC (permalink / raw) To: Imre Deak; +Cc: michl, linux-omap, Yrjola Juha (Nokia-M/Helsinki) * Imre Deak <imre.deak@nokia.com> [060524 04:55]: > [ Ignore the two previous ones they were both bogus:( I tested this on > OMAP1510 innovator ] > > ARM: OMAP: fix GPIO IRQ mask handling > > The GPIO IRQ mask was retrieved incorrectly in cases where we have a mask > register instead of an enable register. Also we should only return the > valid bits depending on the bank size. > > This fixes a bug on 1510/1610 based OMAPs where GPIO IRQs are not > delivered. Great, hopefully this will finally fix the last GPIO irq issues! Pushing today. Tony ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ARM: OMAP: fix GPIO IRQ mask handling [was Re: [RFC] ARM: OMAP: handle lazy IRQ disable properly] 2006-05-26 22:59 ` Tony Lindgren @ 2006-05-27 0:22 ` David Brownell 0 siblings, 0 replies; 6+ messages in thread From: David Brownell @ 2006-05-27 0:22 UTC (permalink / raw) To: linux-omap-open-source; +Cc: michl, Yrjola Juha (Nokia-M/Helsinki) On Friday 26 May 2006 3:59 pm, Tony Lindgren wrote: > > Great, hopefully this will finally fix the last GPIO irq issues! Just in time to phase in the new generic IRQ infrastructure. :) One of the GPIO IRQ issues gets resolved there by having the analogue of do_simple_IRQ() test for disabled IRQs like all the other dispatchers. Better do it there than in drivers or platform irq code... - Dave ^ permalink raw reply [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