diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-29 17:17:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-29 17:17:35 -0700 |
commit | 6bec11921a7d7b11d0b1909596636632aece5a26 (patch) | |
tree | 1bf2ac7d5c482afb2c5cf59c0fc7db7c7ac03ff6 /drivers/gpio | |
parent | 553cbf0a8f19c669bed82028988aa977558ef551 (diff) | |
parent | db7e1bc479cc941c53839b18ff811c7def0c52e7 (diff) | |
download | linux-stable-6bec11921a7d7b11d0b1909596636632aece5a26.tar.gz linux-stable-6bec11921a7d7b11d0b1909596636632aece5a26.tar.bz2 linux-stable-6bec11921a7d7b11d0b1909596636632aece5a26.zip |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm:
ARM: 6061/1: PL061 GPIO: Bug fix - setting gpio for HIGH_LEVEL interrupt is not working.
ARM: 5957/1: ARM: RealView SD/MMC Card detection and write-protect using GPIOLIB
ARM: 6030/1: KS8695: enable console
ARM: 6060/1: PL061 GPIO: Setting gpio val after changing direction to OUT.
ARM: 6059/1: PL061 GPIO: Changing *_irq_chip_data with *_irq_data for real irqs.
ARM: 6023/1: update bcmring_defconfig to latest version and fix build error
ARM: fix build error in arch/arm/kernel/process.c
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/pl061.c | 14 |
1 files changed, 10 insertions, 4 deletions
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, 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; @@ -183,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); @@ -204,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; @@ -297,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++) { |