aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/gpio.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-05-04 13:14:27 -0700
committerKevin Hilman <khilman@deeprootsystems.com>2009-05-26 07:17:54 -0700
commitdf4aab46a8256ac0f0c2701b3fe23b7dd05e6b48 (patch)
tree3ac065f49b9f20d0e759b829824caf7553358e32 /arch/arm/mach-davinci/gpio.c
parent59a3759d0fe8d969888c741bb33f4946e4d3750d (diff)
downloadkernel_samsung_smdk4412-df4aab46a8256ac0f0c2701b3fe23b7dd05e6b48.zip
kernel_samsung_smdk4412-df4aab46a8256ac0f0c2701b3fe23b7dd05e6b48.tar.gz
kernel_samsung_smdk4412-df4aab46a8256ac0f0c2701b3fe23b7dd05e6b48.tar.bz2
davinci: gpio irq enable tweaks
Fix two IRQ triggering bugs affecting GPIO IRQs: - Make sure enabling with IRQ_TYPE_NONE ("default, unspecified") isn't a NOP ... default to both edges, at least one must work. - As noted by Kevin Hilman, setting the irq trigger type for a banked gpio interrupt shouldn't enable irqs that are disabled. Since GPIO IRQs haven't been used much yet, it's not clear these bugs could have affected anything. The few current users don't seem to have been obviously suffering from these issues. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
-rw-r--r--arch/arm/mach-davinci/gpio.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 1aba41c..34ba4ce 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -187,10 +187,15 @@ static void gpio_irq_enable(unsigned irq)
{
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
u32 mask = __gpio_mask(irq_to_gpio(irq));
+ unsigned status = irq_desc[irq].status;
- if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
+ status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+ if (!status)
+ status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+ if (status & IRQ_TYPE_EDGE_FALLING)
__raw_writel(mask, &g->set_falling);
- if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
+ if (status & IRQ_TYPE_EDGE_RISING)
__raw_writel(mask, &g->set_rising);
}
@@ -205,10 +210,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger)
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
irq_desc[irq].status |= trigger;
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
- ? &g->set_falling : &g->clr_falling);
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
- ? &g->set_rising : &g->clr_rising);
+ /* don't enable the IRQ if it's currently disabled */
+ if (irq_desc[irq].depth == 0) {
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+ ? &g->set_falling : &g->clr_falling);
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+ ? &g->set_rising : &g->clr_rising);
+ }
return 0;
}