Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / arm / mach-davinci / gpio.c
index d241b4f..bf0ff58 100644 (file)
@@ -33,28 +33,26 @@ struct davinci_gpio_regs {
        u32     intstat;
 };
 
-static DEFINE_SPINLOCK(gpio_lock);
-
 #define chip2controller(chip)  \
        container_of(chip, struct davinci_gpio_controller, chip)
 
 static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+static void __iomem *gpio_base;
 
 static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
 {
        void __iomem *ptr;
-       void __iomem *base = davinci_soc_info.gpio_base;
 
        if (gpio < 32 * 1)
-               ptr = base + 0x10;
+               ptr = gpio_base + 0x10;
        else if (gpio < 32 * 2)
-               ptr = base + 0x38;
+               ptr = gpio_base + 0x38;
        else if (gpio < 32 * 3)
-               ptr = base + 0x60;
+               ptr = gpio_base + 0x60;
        else if (gpio < 32 * 4)
-               ptr = base + 0x88;
+               ptr = gpio_base + 0x88;
        else if (gpio < 32 * 5)
-               ptr = base + 0xb0;
+               ptr = gpio_base + 0xb0;
        else
                ptr = NULL;
        return ptr;
@@ -73,20 +71,17 @@ static int __init davinci_gpio_irq_setup(void);
 
 /*--------------------------------------------------------------------------*/
 
-/*
- * board setup code *MUST* set PINMUX0 and PINMUX1 as
- * needed, and enable the GPIO clock.
- */
-
+/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
 static inline int __davinci_direction(struct gpio_chip *chip,
                        unsigned offset, bool out, int value)
 {
        struct davinci_gpio_controller *d = chip2controller(chip);
        struct davinci_gpio_regs __iomem *g = d->regs;
+       unsigned long flags;
        u32 temp;
        u32 mask = 1 << offset;
 
-       spin_lock(&gpio_lock);
+       spin_lock_irqsave(&d->lock, flags);
        temp = __raw_readl(&g->dir);
        if (out) {
                temp &= ~mask;
@@ -95,7 +90,7 @@ static inline int __davinci_direction(struct gpio_chip *chip,
                temp |= mask;
        }
        __raw_writel(temp, &g->dir);
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&d->lock, flags);
 
        return 0;
 }
@@ -145,6 +140,9 @@ static int __init davinci_gpio_setup(void)
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        struct davinci_gpio_regs *regs;
 
+       if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
+               return 0;
+
        /*
         * The gpio banks conceptually expose a segmented bitmap,
         * and "ngpio" is one more than the largest zero-based
@@ -159,6 +157,10 @@ static int __init davinci_gpio_setup(void)
        if (WARN_ON(DAVINCI_N_GPIO < ngpio))
                ngpio = DAVINCI_N_GPIO;
 
+       gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
+       if (WARN_ON(!gpio_base))
+               return -ENOMEM;
+
        for (i = 0, base = 0; base < ngpio; i++, base += 32) {
                chips[i].chip.label = "DaVinci";
 
@@ -172,6 +174,8 @@ static int __init davinci_gpio_setup(void)
                if (chips[i].chip.ngpio > 32)
                        chips[i].chip.ngpio = 32;
 
+               spin_lock_init(&chips[i].lock);
+
                regs = gpio2regs(base);
                chips[i].regs = regs;
                chips[i].set_data = &regs->set_data;
@@ -445,7 +449,7 @@ done:
        /* BINTEN -- per-bank interrupt enable. genirq would also let these
         * bits be set/cleared dynamically.
         */
-       __raw_writel(binten, soc_info->gpio_base + 0x08);
+       __raw_writel(binten, gpio_base + 0x08);
 
        printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));