diff options
| -rw-r--r-- | arch/arm/plat-mxc/gpio.c | 8 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/include/mach/gpio.h | 1 |
2 files changed, 9 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 11dc06190b5d..57ec4a896a5d 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c | |||
| @@ -214,13 +214,16 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | |||
| 214 | struct mxc_gpio_port *port = | 214 | struct mxc_gpio_port *port = |
| 215 | container_of(chip, struct mxc_gpio_port, chip); | 215 | container_of(chip, struct mxc_gpio_port, chip); |
| 216 | u32 l; | 216 | u32 l; |
| 217 | unsigned long flags; | ||
| 217 | 218 | ||
| 219 | spin_lock_irqsave(&port->lock, flags); | ||
| 218 | l = __raw_readl(port->base + GPIO_GDIR); | 220 | l = __raw_readl(port->base + GPIO_GDIR); |
| 219 | if (dir) | 221 | if (dir) |
| 220 | l |= 1 << offset; | 222 | l |= 1 << offset; |
| 221 | else | 223 | else |
| 222 | l &= ~(1 << offset); | 224 | l &= ~(1 << offset); |
| 223 | __raw_writel(l, port->base + GPIO_GDIR); | 225 | __raw_writel(l, port->base + GPIO_GDIR); |
| 226 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 224 | } | 227 | } |
| 225 | 228 | ||
| 226 | static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 229 | 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) | |||
| 229 | container_of(chip, struct mxc_gpio_port, chip); | 232 | container_of(chip, struct mxc_gpio_port, chip); |
| 230 | void __iomem *reg = port->base + GPIO_DR; | 233 | void __iomem *reg = port->base + GPIO_DR; |
| 231 | u32 l; | 234 | u32 l; |
| 235 | unsigned long flags; | ||
| 232 | 236 | ||
| 237 | spin_lock_irqsave(&port->lock, flags); | ||
| 233 | l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); | 238 | l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); |
| 234 | __raw_writel(l, reg); | 239 | __raw_writel(l, reg); |
| 240 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 235 | } | 241 | } |
| 236 | 242 | ||
| 237 | static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) | 243 | 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) | |||
| 285 | port[i].chip.base = i * 32; | 291 | port[i].chip.base = i * 32; |
| 286 | port[i].chip.ngpio = 32; | 292 | port[i].chip.ngpio = 32; |
| 287 | 293 | ||
| 294 | spin_lock_init(&port[i].lock); | ||
| 295 | |||
| 288 | /* its a serious configuration bug when it fails */ | 296 | /* its a serious configuration bug when it fails */ |
| 289 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); | 297 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); |
| 290 | 298 | ||
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h index 9541ecbfd22c..661fbc605759 100644 --- a/arch/arm/plat-mxc/include/mach/gpio.h +++ b/arch/arm/plat-mxc/include/mach/gpio.h | |||
| @@ -37,6 +37,7 @@ struct mxc_gpio_port { | |||
| 37 | int virtual_irq_start; | 37 | int virtual_irq_start; |
| 38 | struct gpio_chip chip; | 38 | struct gpio_chip chip; |
| 39 | u32 both_edges; | 39 | u32 both_edges; |
| 40 | spinlock_t lock; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | int mxc_gpio_init(struct mxc_gpio_port*, int); | 43 | int mxc_gpio_init(struct mxc_gpio_port*, int); |
