Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
[pandora-kernel.git] / arch / arm / plat-mxc / gpio.c
index 71437c6..57ec4a8 100644 (file)
@@ -214,13 +214,16 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
        struct mxc_gpio_port *port =
                container_of(chip, struct mxc_gpio_port, chip);
        u32 l;
+       unsigned long flags;
 
+       spin_lock_irqsave(&port->lock, flags);
        l = __raw_readl(port->base + GPIO_GDIR);
        if (dir)
                l |= 1 << offset;
        else
                l &= ~(1 << offset);
        __raw_writel(l, port->base + GPIO_GDIR);
+       spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -229,9 +232,12 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
                container_of(chip, struct mxc_gpio_port, chip);
        void __iomem *reg = port->base + GPIO_DR;
        u32 l;
+       unsigned long flags;
 
+       spin_lock_irqsave(&port->lock, flags);
        l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
        __raw_writel(l, reg);
+       spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -285,6 +291,8 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
                port[i].chip.base = i * 32;
                port[i].chip.ngpio = 32;
 
+               spin_lock_init(&port[i].lock);
+
                /* its a serious configuration bug when it fails */
                BUG_ON( gpiochip_add(&port[i].chip) < 0 );
 
@@ -292,6 +300,12 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
                        /* setup one handler for each entry */
                        set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
                        set_irq_data(port[i].irq, &port[i]);
+                       if (port[i].irq_high) {
+                               /* setup handler for GPIO 16 to 31 */
+                               set_irq_chained_handler(port[i].irq_high,
+                                               mx3_gpio_irq_handler);
+                               set_irq_data(port[i].irq_high, &port[i]);
+                       }
                }
        }