summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91rm9200/gpio.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2006-03-20 18:58:02 +0100
committerKumar Gala <galak@kernel.crashing.org>2006-03-20 18:58:02 +0100
commit1a02e59a2970f9ed28ab51d3b08624b79e54d848 (patch)
tree470cce472be3b08c160e0c569648e7228651b12a /arch/arm/mach-at91rm9200/gpio.c
parentppc32: Fix BCSR_SIZE for MPC834x SYS (diff)
parent[PATCH] powerpc: Fix bug in bug fix for bug in lmb_alloc() (diff)
downloadlinux-1a02e59a2970f9ed28ab51d3b08624b79e54d848.tar.xz
linux-1a02e59a2970f9ed28ab51d3b08624b79e54d848.zip
Merge branch 'master'
Diffstat (limited to 'arch/arm/mach-at91rm9200/gpio.c')
-rw-r--r--arch/arm/mach-at91rm9200/gpio.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c
index 2fd2ef583e4d..0e396feec468 100644
--- a/arch/arm/mach-at91rm9200/gpio.c
+++ b/arch/arm/mach-at91rm9200/gpio.c
@@ -159,6 +159,23 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
}
EXPORT_SYMBOL(at91_set_deglitch);
+/*
+ * enable/disable the multi-driver; This is only valid for output and
+ * allows the output pin to run as an open collector output.
+ */
+int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR));
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_multi_drive);
+
/*--------------------------------------------------------------------------*/
@@ -257,8 +274,18 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs
gpio = &irq_desc[pin];
while (isr) {
- if (isr & 1)
- gpio->handle(pin, gpio, regs);
+ if (isr & 1) {
+ if (unlikely(gpio->disable_depth)) {
+ /*
+ * The core ARM interrupt handler lazily disables IRQs so
+ * another IRQ must be generated before it actually gets
+ * here to be disabled on the GPIO controller.
+ */
+ gpio_irq_mask(pin);
+ }
+ else
+ gpio->handle(pin, gpio, regs);
+ }
pin++;
gpio++;
isr >>= 1;