diff options
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0599854e2217..f0208a958185 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -148,13 +148,17 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | |||
| 148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; | 148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 151 | static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) |
| 152 | do { \ | 152 | { |
| 153 | int l = __raw_readl(base + reg); \ | 153 | int l = __raw_readl(base + reg); |
| 154 | if (set) l |= bit_mask; \ | 154 | |
| 155 | else l &= ~bit_mask; \ | 155 | if (set) |
| 156 | __raw_writel(l, base + reg); \ | 156 | l |= mask; |
| 157 | } while(0) | 157 | else |
| 158 | l &= ~mask; | ||
| 159 | |||
| 160 | __raw_writel(l, base + reg); | ||
| 161 | } | ||
| 158 | 162 | ||
| 159 | /** | 163 | /** |
| 160 | * _set_gpio_debounce - low level gpio debounce time | 164 | * _set_gpio_debounce - low level gpio debounce time |
| @@ -210,28 +214,28 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
| 210 | u32 gpio_bit = 1 << gpio; | 214 | u32 gpio_bit = 1 << gpio; |
| 211 | 215 | ||
| 212 | if (cpu_is_omap44xx()) { | 216 | if (cpu_is_omap44xx()) { |
| 213 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, | 217 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, |
| 214 | trigger & IRQ_TYPE_LEVEL_LOW); | 218 | trigger & IRQ_TYPE_LEVEL_LOW); |
| 215 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, | 219 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, |
| 216 | trigger & IRQ_TYPE_LEVEL_HIGH); | 220 | trigger & IRQ_TYPE_LEVEL_HIGH); |
| 217 | MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, | 221 | _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, |
| 218 | trigger & IRQ_TYPE_EDGE_RISING); | 222 | trigger & IRQ_TYPE_EDGE_RISING); |
| 219 | MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, | 223 | _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, |
| 220 | trigger & IRQ_TYPE_EDGE_FALLING); | 224 | trigger & IRQ_TYPE_EDGE_FALLING); |
| 221 | } else { | 225 | } else { |
| 222 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 226 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, |
| 223 | trigger & IRQ_TYPE_LEVEL_LOW); | 227 | trigger & IRQ_TYPE_LEVEL_LOW); |
| 224 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 228 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, |
| 225 | trigger & IRQ_TYPE_LEVEL_HIGH); | 229 | trigger & IRQ_TYPE_LEVEL_HIGH); |
| 226 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 230 | _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit, |
| 227 | trigger & IRQ_TYPE_EDGE_RISING); | 231 | trigger & IRQ_TYPE_EDGE_RISING); |
| 228 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 232 | _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, |
| 229 | trigger & IRQ_TYPE_EDGE_FALLING); | 233 | trigger & IRQ_TYPE_EDGE_FALLING); |
| 230 | } | 234 | } |
| 231 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { | 235 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { |
| 232 | if (cpu_is_omap44xx()) { | 236 | if (cpu_is_omap44xx()) { |
| 233 | MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, | 237 | _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit, |
| 234 | trigger != 0); | 238 | trigger != 0); |
| 235 | } else { | 239 | } else { |
| 236 | /* | 240 | /* |
| 237 | * GPIO wakeup request can only be generated on edge | 241 | * GPIO wakeup request can only be generated on edge |
| @@ -1086,6 +1090,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | |||
| 1086 | 1090 | ||
| 1087 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, | 1091 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, |
| 1088 | handle_simple_irq); | 1092 | handle_simple_irq); |
| 1093 | if (!gc) { | ||
| 1094 | dev_err(bank->dev, "Memory alloc failed for gc\n"); | ||
| 1095 | return; | ||
| 1096 | } | ||
| 1097 | |||
| 1089 | ct = gc->chip_types; | 1098 | ct = gc->chip_types; |
| 1090 | 1099 | ||
| 1091 | /* NOTE: No ack required, reading IRQ status clears it. */ | 1100 | /* NOTE: No ack required, reading IRQ status clears it. */ |
