diff options
author | Kevin Hilman <khilman@mvista.com> | 2008-01-17 00:56:16 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-04-14 12:57:11 -0400 |
commit | 672e302e3c04e40e7c236cb09159f593f24f5def (patch) | |
tree | ef2229d89a3e8c48b9f09d0af5e1491349e16dde /arch/arm/plat-omap/gpio.c | |
parent | b144ff6f3068602e5bbcefab888b97bcedb9b4a5 (diff) |
ARM: OMAP: use edge/level handlers from generic IRQ framework
Currently, the GPIO interrupt handling is duplicating some of the work
done by the generic IRQ handlers (handle_edge_irq, handle_level_irq)
such as detecting nesting, handling re-triggers etc. Remove this
duplication and use generic hooks based on IRQ type.
Using generic IRQ handlers ensures correct behavior when using
threaded interrupts introduced by the -rt patch.
Signed-off-by: Kevin Hilman <khilman@mvista.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 42 |
1 files changed, 7 insertions, 35 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 4f104e4f6c04..1903a3491ee9 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -542,10 +542,6 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
542 | bank->level_mask = | 542 | bank->level_mask = |
543 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | | 543 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | |
544 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 544 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
545 | /* | ||
546 | * FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only | ||
547 | * level triggering requested. | ||
548 | */ | ||
549 | } | 545 | } |
550 | #endif | 546 | #endif |
551 | 547 | ||
@@ -656,6 +652,12 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
656 | irq_desc[irq].status |= type; | 652 | irq_desc[irq].status |= type; |
657 | } | 653 | } |
658 | spin_unlock_irqrestore(&bank->lock, flags); | 654 | spin_unlock_irqrestore(&bank->lock, flags); |
655 | |||
656 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
657 | __set_irq_handler_unlocked(irq, handle_level_irq); | ||
658 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
659 | __set_irq_handler_unlocked(irq, handle_edge_irq); | ||
660 | |||
659 | return retval; | 661 | return retval; |
660 | } | 662 | } |
661 | 663 | ||
@@ -1050,42 +1052,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1050 | gpio_irq = bank->virtual_irq_start; | 1052 | gpio_irq = bank->virtual_irq_start; |
1051 | for (; isr != 0; isr >>= 1, gpio_irq++) { | 1053 | for (; isr != 0; isr >>= 1, gpio_irq++) { |
1052 | struct irq_desc *d; | 1054 | struct irq_desc *d; |
1053 | int irq_mask; | 1055 | |
1054 | if (!(isr & 1)) | 1056 | if (!(isr & 1)) |
1055 | continue; | 1057 | continue; |
1056 | d = irq_desc + gpio_irq; | 1058 | d = irq_desc + gpio_irq; |
1057 | /* Don't run the handler if it's already running | ||
1058 | * or was disabled lazely. | ||
1059 | */ | ||
1060 | if (unlikely((d->depth || | ||
1061 | (d->status & IRQ_INPROGRESS)))) { | ||
1062 | irq_mask = 1 << | ||
1063 | (gpio_irq - bank->virtual_irq_start); | ||
1064 | /* The unmasking will be done by | ||
1065 | * enable_irq in case it is disabled or | ||
1066 | * after returning from the handler if | ||
1067 | * it's already running. | ||
1068 | */ | ||
1069 | _enable_gpio_irqbank(bank, irq_mask, 0); | ||
1070 | if (!d->depth) { | ||
1071 | /* Level triggered interrupts | ||
1072 | * won't ever be reentered | ||
1073 | */ | ||
1074 | BUG_ON(level_mask & irq_mask); | ||
1075 | d->status |= IRQ_PENDING; | ||
1076 | } | ||
1077 | continue; | ||
1078 | } | ||
1079 | 1059 | ||
1080 | desc_handle_irq(gpio_irq, d); | 1060 | desc_handle_irq(gpio_irq, d); |
1081 | |||
1082 | if (unlikely((d->status & IRQ_PENDING) && !d->depth)) { | ||
1083 | irq_mask = 1 << | ||
1084 | (gpio_irq - bank->virtual_irq_start); | ||
1085 | d->status &= ~IRQ_PENDING; | ||
1086 | _enable_gpio_irqbank(bank, irq_mask, 1); | ||
1087 | retrigger |= irq_mask; | ||
1088 | } | ||
1089 | } | 1061 | } |
1090 | } | 1062 | } |
1091 | /* if bank has any level sensitive GPIO pin interrupt | 1063 | /* if bank has any level sensitive GPIO pin interrupt |