Davinci: gpio - fine grained locking
authorCyril Chemparathy <cyril@ti.com>
Sat, 1 May 2010 22:37:55 +0000 (18:37 -0400)
committerKevin Hilman <khilman@deeprootsystems.com>
Thu, 6 May 2010 22:02:09 +0000 (15:02 -0700)
This patch eliminates the global gpio_lock, and implements a per-controller
lock instead.  This also switches to irqsave/irqrestore locks in case gpios
are manipulated in isr.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Tested-by: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/mach-davinci/gpio.c
arch/arm/mach-davinci/include/mach/gpio.h

index e422cd300d4c4c4ff6f10c643a6d8eb6d0149597..b62d5e2bd37ee038108278f35d0476c0dfdae758 100644 (file)
@@ -33,8 +33,6 @@ struct davinci_gpio_regs {
        u32     intstat;
 };
 
-static DEFINE_SPINLOCK(gpio_lock);
-
 #define chip2controller(chip)  \
        container_of(chip, struct davinci_gpio_controller, chip)
 
@@ -83,10 +81,11 @@ static inline int __davinci_direction(struct gpio_chip *chip,
 {
        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 +94,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;
 }
@@ -175,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;
index 9a71a26eb77fb01f09cb06b9ffc514b454a7a5a9..504cc180a60b76756bda2b5e1e5bb139392c11e7 100644 (file)
@@ -14,6 +14,8 @@
 #define        __DAVINCI_GPIO_H
 
 #include <linux/io.h>
+#include <linux/spinlock.h>
+
 #include <asm-generic/gpio.h>
 
 #include <mach/irqs.h>
@@ -52,6 +54,7 @@ enum davinci_gpio_type {
 struct davinci_gpio_controller {
        struct gpio_chip        chip;
        int                     irq_base;
+       spinlock_t              lock;
        void __iomem            *regs;
        void __iomem            *set_data;
        void __iomem            *clr_data;