summaryrefslogtreecommitdiff
path: root/drivers/gpio/pl061.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-05-03 11:17:01 +0400
committerIngo Molnar <mingo@elte.hu>2010-05-03 11:17:01 +0400
commit53ba4f2fa73225113a488584df0d85d3cba52943 (patch)
treed85b984d9818abc3ccc0237eb53b710d9e96c39e /drivers/gpio/pl061.c
parentbd6d29c25bb1a24a4c160ec5de43e0004e01f72b (diff)
parent66f41d4c5c8a5deed66fdcc84509376c9a0bf9d8 (diff)
downloadlinux-53ba4f2fa73225113a488584df0d85d3cba52943.tar.xz
Merge commit 'v2.6.34-rc6' into core/locking
Diffstat (limited to 'drivers/gpio/pl061.c')
-rw-r--r--drivers/gpio/pl061.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 4ee4c8367a3f..105701a1f05b 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -24,6 +24,7 @@
#include <linux/device.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl061.h>
+#include <linux/slab.h>
#define GPIODIR 0x400
#define GPIOIS 0x404
@@ -90,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
gpiodir = readb(chip->base + GPIODIR);
gpiodir |= 1 << offset;
writeb(gpiodir, chip->base + GPIODIR);
+
+ /*
+ * gpio value is set again, because pl061 doesn't allow to set value of
+ * a gpio pin before configuring it in OUT mode.
+ */
+ writeb(!!value << offset, chip->base + (1 << (offset + 2)));
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -182,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
gpioibe &= ~(1 << offset);
if (trigger & IRQ_TYPE_EDGE_RISING)
gpioiev |= 1 << offset;
- else
+ else if (trigger & IRQ_TYPE_EDGE_FALLING)
gpioiev &= ~(1 << offset);
}
writeb(gpioibe, chip->base + GPIOIBE);
@@ -203,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct list_head *chip_list = get_irq_chip_data(irq);
+ struct list_head *chip_list = get_irq_data(irq);
struct list_head *ptr;
struct pl061_gpio *chip;
@@ -219,7 +226,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
if (pending == 0)
continue;
- for_each_bit(offset, &pending, PL061_GPIO_NR)
+ for_each_set_bit(offset, &pending, PL061_GPIO_NR)
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
}
desc->chip->unmask(irq);
@@ -296,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
goto iounmap;
}
INIT_LIST_HEAD(chip_list);
- set_irq_chip_data(irq, chip_list);
+ set_irq_data(irq, chip_list);
} else
- chip_list = get_irq_chip_data(irq);
+ chip_list = get_irq_data(irq);
list_add(&chip->list, chip_list);
for (i = 0; i < PL061_GPIO_NR; i++) {