aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyril Chemparathy <cyril@ti.com>2010-05-01 18:37:55 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2010-05-06 18:02:09 -0400
commitb27b6d03f245e5eaf6473da58a2612077fb7cfe7 (patch)
treeb6ed359c8b604edcaed5025aa83c57d77daec1a9
parent686b634a07451fc4fe3b712fe211bfa861a53241 (diff)
Davinci: gpio - fine grained locking
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>
-rw-r--r--arch/arm/mach-davinci/gpio.c9
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h3
2 files changed, 8 insertions, 4 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index e422cd300d4c..b62d5e2bd37e 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -33,8 +33,6 @@ struct davinci_gpio_regs {
33 u32 intstat; 33 u32 intstat;
34}; 34};
35 35
36static DEFINE_SPINLOCK(gpio_lock);
37
38#define chip2controller(chip) \ 36#define chip2controller(chip) \
39 container_of(chip, struct davinci_gpio_controller, chip) 37 container_of(chip, struct davinci_gpio_controller, chip)
40 38
@@ -83,10 +81,11 @@ static inline int __davinci_direction(struct gpio_chip *chip,
83{ 81{
84 struct davinci_gpio_controller *d = chip2controller(chip); 82 struct davinci_gpio_controller *d = chip2controller(chip);
85 struct davinci_gpio_regs __iomem *g = d->regs; 83 struct davinci_gpio_regs __iomem *g = d->regs;
84 unsigned long flags;
86 u32 temp; 85 u32 temp;
87 u32 mask = 1 << offset; 86 u32 mask = 1 << offset;
88 87
89 spin_lock(&gpio_lock); 88 spin_lock_irqsave(&d->lock, flags);
90 temp = __raw_readl(&g->dir); 89 temp = __raw_readl(&g->dir);
91 if (out) { 90 if (out) {
92 temp &= ~mask; 91 temp &= ~mask;
@@ -95,7 +94,7 @@ static inline int __davinci_direction(struct gpio_chip *chip,
95 temp |= mask; 94 temp |= mask;
96 } 95 }
97 __raw_writel(temp, &g->dir); 96 __raw_writel(temp, &g->dir);
98 spin_unlock(&gpio_lock); 97 spin_unlock_irqrestore(&d->lock, flags);
99 98
100 return 0; 99 return 0;
101} 100}
@@ -175,6 +174,8 @@ static int __init davinci_gpio_setup(void)
175 if (chips[i].chip.ngpio > 32) 174 if (chips[i].chip.ngpio > 32)
176 chips[i].chip.ngpio = 32; 175 chips[i].chip.ngpio = 32;
177 176
177 spin_lock_init(&chips[i].lock);
178
178 regs = gpio2regs(base); 179 regs = gpio2regs(base);
179 chips[i].regs = regs; 180 chips[i].regs = regs;
180 chips[i].set_data = &regs->set_data; 181 chips[i].set_data = &regs->set_data;
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index 9a71a26eb77f..504cc180a60b 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -14,6 +14,8 @@
14#define __DAVINCI_GPIO_H 14#define __DAVINCI_GPIO_H
15 15
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/spinlock.h>
18
17#include <asm-generic/gpio.h> 19#include <asm-generic/gpio.h>
18 20
19#include <mach/irqs.h> 21#include <mach/irqs.h>
@@ -52,6 +54,7 @@ enum davinci_gpio_type {
52struct davinci_gpio_controller { 54struct davinci_gpio_controller {
53 struct gpio_chip chip; 55 struct gpio_chip chip;
54 int irq_base; 56 int irq_base;
57 spinlock_t lock;
55 void __iomem *regs; 58 void __iomem *regs;
56 void __iomem *set_data; 59 void __iomem *set_data;
57 void __iomem *clr_data; 60 void __iomem *clr_data;