aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/pl061.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/pl061.c')
-rw-r--r--drivers/gpio/pl061.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 3ad1eeb49609..105701a1f05b 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -24,6 +24,7 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h> 26#include <linux/amba/pl061.h>
27#include <linux/slab.h>
27 28
28#define GPIODIR 0x400 29#define GPIODIR 0x400
29#define GPIOIS 0x404 30#define GPIOIS 0x404
@@ -90,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
90 gpiodir = readb(chip->base + GPIODIR); 91 gpiodir = readb(chip->base + GPIODIR);
91 gpiodir |= 1 << offset; 92 gpiodir |= 1 << offset;
92 writeb(gpiodir, chip->base + GPIODIR); 93 writeb(gpiodir, chip->base + GPIODIR);
94
95 /*
96 * gpio value is set again, because pl061 doesn't allow to set value of
97 * a gpio pin before configuring it in OUT mode.
98 */
99 writeb(!!value << offset, chip->base + (1 << (offset + 2)));
93 spin_unlock_irqrestore(&chip->lock, flags); 100 spin_unlock_irqrestore(&chip->lock, flags);
94 101
95 return 0; 102 return 0;
@@ -182,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
182 gpioibe &= ~(1 << offset); 189 gpioibe &= ~(1 << offset);
183 if (trigger & IRQ_TYPE_EDGE_RISING) 190 if (trigger & IRQ_TYPE_EDGE_RISING)
184 gpioiev |= 1 << offset; 191 gpioiev |= 1 << offset;
185 else 192 else if (trigger & IRQ_TYPE_EDGE_FALLING)
186 gpioiev &= ~(1 << offset); 193 gpioiev &= ~(1 << offset);
187 } 194 }
188 writeb(gpioibe, chip->base + GPIOIBE); 195 writeb(gpioibe, chip->base + GPIOIBE);
@@ -203,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
203 210
204static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) 211static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
205{ 212{
206 struct list_head *chip_list = get_irq_chip_data(irq); 213 struct list_head *chip_list = get_irq_data(irq);
207 struct list_head *ptr; 214 struct list_head *ptr;
208 struct pl061_gpio *chip; 215 struct pl061_gpio *chip;
209 216
@@ -296,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
296 goto iounmap; 303 goto iounmap;
297 } 304 }
298 INIT_LIST_HEAD(chip_list); 305 INIT_LIST_HEAD(chip_list);
299 set_irq_chip_data(irq, chip_list); 306 set_irq_data(irq, chip_list);
300 } else 307 } else
301 chip_list = get_irq_chip_data(irq); 308 chip_list = get_irq_data(irq);
302 list_add(&chip->list, chip_list); 309 list_add(&chip->list, chip_list);
303 310
304 for (i = 0; i < PL061_GPIO_NR; i++) { 311 for (i = 0; i < PL061_GPIO_NR; i++) {