diff options
| author | Richard Röjfors <richard.rojfors@pelagicore.com> | 2010-03-05 16:44:35 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-06 14:26:48 -0500 |
| commit | 8c35c89aa3d7e0f253c3a10456a8b075288b4565 (patch) | |
| tree | 571fa92195a23fbd6cab7de7cba099aa69da7269 | |
| parent | 3e45f1d1155894e6f4291f5536b224874d52d8e2 (diff) | |
timbgpio: add support for interrupt triggering on both flanks
Introduce support for triggering interrupts on both rising and falling
edge.
This feature requires version 3 or newer of the IP, a version check is
done when triggering on both edges is requested.
Signed-off-by: Richard Röjfors <richard.rojfors@pelagicore.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/gpio/timbgpio.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c index 4ecba6e5a32d..d4295fa5369e 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/timbgpio.c | |||
| @@ -38,6 +38,8 @@ | |||
| 38 | #define TGPIO_ICR 0x14 | 38 | #define TGPIO_ICR 0x14 |
| 39 | #define TGPIO_FLR 0x18 | 39 | #define TGPIO_FLR 0x18 |
| 40 | #define TGPIO_LVR 0x1c | 40 | #define TGPIO_LVR 0x1c |
| 41 | #define TGPIO_VER 0x20 | ||
| 42 | #define TGPIO_BFLR 0x24 | ||
| 41 | 43 | ||
| 42 | struct timbgpio { | 44 | struct timbgpio { |
| 43 | void __iomem *membase; | 45 | void __iomem *membase; |
| @@ -126,17 +128,23 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger) | |||
| 126 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 128 | struct timbgpio *tgpio = get_irq_chip_data(irq); |
| 127 | int offset = irq - tgpio->irq_base; | 129 | int offset = irq - tgpio->irq_base; |
| 128 | unsigned long flags; | 130 | unsigned long flags; |
| 129 | u32 lvr, flr; | 131 | u32 lvr, flr, bflr = 0; |
| 132 | u32 ver; | ||
| 130 | 133 | ||
| 131 | if (offset < 0 || offset > tgpio->gpio.ngpio) | 134 | if (offset < 0 || offset > tgpio->gpio.ngpio) |
| 132 | return -EINVAL; | 135 | return -EINVAL; |
| 133 | 136 | ||
| 137 | ver = ioread32(tgpio->membase + TGPIO_VER); | ||
| 138 | |||
| 134 | spin_lock_irqsave(&tgpio->lock, flags); | 139 | spin_lock_irqsave(&tgpio->lock, flags); |
| 135 | 140 | ||
| 136 | lvr = ioread32(tgpio->membase + TGPIO_LVR); | 141 | lvr = ioread32(tgpio->membase + TGPIO_LVR); |
| 137 | flr = ioread32(tgpio->membase + TGPIO_FLR); | 142 | flr = ioread32(tgpio->membase + TGPIO_FLR); |
| 143 | if (ver > 2) | ||
| 144 | bflr = ioread32(tgpio->membase + TGPIO_BFLR); | ||
| 138 | 145 | ||
| 139 | if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 146 | if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
| 147 | bflr &= ~(1 << offset); | ||
| 140 | flr &= ~(1 << offset); | 148 | flr &= ~(1 << offset); |
| 141 | if (trigger & IRQ_TYPE_LEVEL_HIGH) | 149 | if (trigger & IRQ_TYPE_LEVEL_HIGH) |
| 142 | lvr |= 1 << offset; | 150 | lvr |= 1 << offset; |
| @@ -144,21 +152,27 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger) | |||
| 144 | lvr &= ~(1 << offset); | 152 | lvr &= ~(1 << offset); |
| 145 | } | 153 | } |
| 146 | 154 | ||
| 147 | if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) | 155 | if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { |
| 148 | return -EINVAL; | 156 | if (ver < 3) |
| 149 | else { | 157 | return -EINVAL; |
| 158 | else { | ||
| 159 | flr |= 1 << offset; | ||
| 160 | bflr |= 1 << offset; | ||
| 161 | } | ||
| 162 | } else { | ||
| 163 | bflr &= ~(1 << offset); | ||
| 150 | flr |= 1 << offset; | 164 | flr |= 1 << offset; |
| 151 | /* opposite compared to the datasheet, but it mirrors the | ||
| 152 | * reality | ||
| 153 | */ | ||
| 154 | if (trigger & IRQ_TYPE_EDGE_FALLING) | 165 | if (trigger & IRQ_TYPE_EDGE_FALLING) |
| 155 | lvr |= 1 << offset; | ||
| 156 | else | ||
| 157 | lvr &= ~(1 << offset); | 166 | lvr &= ~(1 << offset); |
| 167 | else | ||
| 168 | lvr |= 1 << offset; | ||
| 158 | } | 169 | } |
| 159 | 170 | ||
| 160 | iowrite32(lvr, tgpio->membase + TGPIO_LVR); | 171 | iowrite32(lvr, tgpio->membase + TGPIO_LVR); |
| 161 | iowrite32(flr, tgpio->membase + TGPIO_FLR); | 172 | iowrite32(flr, tgpio->membase + TGPIO_FLR); |
| 173 | if (ver > 2) | ||
| 174 | iowrite32(bflr, tgpio->membase + TGPIO_BFLR); | ||
| 175 | |||
| 162 | iowrite32(1 << offset, tgpio->membase + TGPIO_ICR); | 176 | iowrite32(1 << offset, tgpio->membase + TGPIO_ICR); |
| 163 | spin_unlock_irqrestore(&tgpio->lock, flags); | 177 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 164 | 178 | ||
