diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/pca953x.c | 14 | ||||
-rw-r--r-- | drivers/gpio/pl061.c | 14 |
2 files changed, 23 insertions, 5 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7d521e1d17e1..b827c976dc62 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -252,6 +252,18 @@ static void pca953x_irq_bus_lock(unsigned int irq) | |||
252 | static void pca953x_irq_bus_sync_unlock(unsigned int irq) | 252 | static void pca953x_irq_bus_sync_unlock(unsigned int irq) |
253 | { | 253 | { |
254 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 254 | struct pca953x_chip *chip = get_irq_chip_data(irq); |
255 | uint16_t new_irqs; | ||
256 | uint16_t level; | ||
257 | |||
258 | /* Look for any newly setup interrupt */ | ||
259 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; | ||
260 | new_irqs &= ~chip->reg_direction; | ||
261 | |||
262 | while (new_irqs) { | ||
263 | level = __ffs(new_irqs); | ||
264 | pca953x_gpio_direction_input(&chip->gpio_chip, level); | ||
265 | new_irqs &= ~(1 << level); | ||
266 | } | ||
255 | 267 | ||
256 | mutex_unlock(&chip->irq_lock); | 268 | mutex_unlock(&chip->irq_lock); |
257 | } | 269 | } |
@@ -278,7 +290,7 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type) | |||
278 | else | 290 | else |
279 | chip->irq_trig_raise &= ~mask; | 291 | chip->irq_trig_raise &= ~mask; |
280 | 292 | ||
281 | return pca953x_gpio_direction_input(&chip->gpio_chip, level); | 293 | return 0; |
282 | } | 294 | } |
283 | 295 | ||
284 | static struct irq_chip pca953x_irq_chip = { | 296 | static struct irq_chip pca953x_irq_chip = { |
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c index 5ad8f778ced4..105701a1f05b 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/pl061.c | |||
@@ -91,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, | |||
91 | gpiodir = readb(chip->base + GPIODIR); | 91 | gpiodir = readb(chip->base + GPIODIR); |
92 | gpiodir |= 1 << offset; | 92 | gpiodir |= 1 << offset; |
93 | 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))); | ||
94 | spin_unlock_irqrestore(&chip->lock, flags); | 100 | spin_unlock_irqrestore(&chip->lock, flags); |
95 | 101 | ||
96 | return 0; | 102 | return 0; |
@@ -183,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger) | |||
183 | gpioibe &= ~(1 << offset); | 189 | gpioibe &= ~(1 << offset); |
184 | if (trigger & IRQ_TYPE_EDGE_RISING) | 190 | if (trigger & IRQ_TYPE_EDGE_RISING) |
185 | gpioiev |= 1 << offset; | 191 | gpioiev |= 1 << offset; |
186 | else | 192 | else if (trigger & IRQ_TYPE_EDGE_FALLING) |
187 | gpioiev &= ~(1 << offset); | 193 | gpioiev &= ~(1 << offset); |
188 | } | 194 | } |
189 | writeb(gpioibe, chip->base + GPIOIBE); | 195 | writeb(gpioibe, chip->base + GPIOIBE); |
@@ -204,7 +210,7 @@ static struct irq_chip pl061_irqchip = { | |||
204 | 210 | ||
205 | static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | 211 | static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) |
206 | { | 212 | { |
207 | struct list_head *chip_list = get_irq_chip_data(irq); | 213 | struct list_head *chip_list = get_irq_data(irq); |
208 | struct list_head *ptr; | 214 | struct list_head *ptr; |
209 | struct pl061_gpio *chip; | 215 | struct pl061_gpio *chip; |
210 | 216 | ||
@@ -297,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) | |||
297 | goto iounmap; | 303 | goto iounmap; |
298 | } | 304 | } |
299 | INIT_LIST_HEAD(chip_list); | 305 | INIT_LIST_HEAD(chip_list); |
300 | set_irq_chip_data(irq, chip_list); | 306 | set_irq_data(irq, chip_list); |
301 | } else | 307 | } else |
302 | chip_list = get_irq_chip_data(irq); | 308 | chip_list = get_irq_data(irq); |
303 | list_add(&chip->list, chip_list); | 309 | list_add(&chip->list, chip_list); |
304 | 310 | ||
305 | for (i = 0; i < PL061_GPIO_NR; i++) { | 311 | for (i = 0; i < PL061_GPIO_NR; i++) { |