diff options
-rw-r--r-- | arch/arm/mach-omap1/gpio15xx.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap1/gpio16xx.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap1/gpio7xx.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 157 |
5 files changed, 53 insertions, 114 deletions
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index f8c15eabf06e..2adfece30ce6 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c | |||
@@ -42,6 +42,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { | |||
42 | .irqstatus = OMAP_MPUIO_GPIO_INT, | 42 | .irqstatus = OMAP_MPUIO_GPIO_INT, |
43 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | 43 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, |
44 | .irqenable_inv = true, | 44 | .irqenable_inv = true, |
45 | .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { | 48 | static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { |
@@ -83,6 +84,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { | |||
83 | .irqstatus = OMAP1510_GPIO_INT_STATUS, | 84 | .irqstatus = OMAP1510_GPIO_INT_STATUS, |
84 | .irqenable = OMAP1510_GPIO_INT_MASK, | 85 | .irqenable = OMAP1510_GPIO_INT_MASK, |
85 | .irqenable_inv = true, | 86 | .irqenable_inv = true, |
87 | .irqctrl = OMAP1510_GPIO_INT_CONTROL, | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { | 90 | static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { |
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 1eb47e2760d8..46bb57a8cb7d 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c | |||
@@ -45,6 +45,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { | |||
45 | .irqstatus = OMAP_MPUIO_GPIO_INT, | 45 | .irqstatus = OMAP_MPUIO_GPIO_INT, |
46 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, | 46 | .irqenable = OMAP_MPUIO_GPIO_MASKIT, |
47 | .irqenable_inv = true, | 47 | .irqenable_inv = true, |
48 | .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { | 51 | static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { |
@@ -90,6 +91,8 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { | |||
90 | .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, | 91 | .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, |
91 | .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, | 92 | .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, |
92 | .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, | 93 | .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, |
94 | .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, | ||
95 | .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, | ||
93 | }; | 96 | }; |
94 | 97 | ||
95 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { | 98 | static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { |
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 923eaa1df955..207a23cfa1a0 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c | |||
@@ -47,6 +47,7 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { | |||
47 | .irqstatus = OMAP_MPUIO_GPIO_INT / 2, | 47 | .irqstatus = OMAP_MPUIO_GPIO_INT / 2, |
48 | .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, | 48 | .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, |
49 | .irqenable_inv = true, | 49 | .irqenable_inv = true, |
50 | .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE >> 1, | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { | 53 | static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { |
@@ -88,6 +89,7 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { | |||
88 | .irqstatus = OMAP7XX_GPIO_INT_STATUS, | 89 | .irqstatus = OMAP7XX_GPIO_INT_STATUS, |
89 | .irqenable = OMAP7XX_GPIO_INT_MASK, | 90 | .irqenable = OMAP7XX_GPIO_INT_MASK, |
90 | .irqenable_inv = true, | 91 | .irqenable_inv = true, |
92 | .irqctrl = OMAP7XX_GPIO_INT_CONTROL, | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { | 95 | static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { |
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 914c976b1de0..9e403e54f6f9 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h | |||
@@ -195,6 +195,9 @@ struct omap_gpio_reg_offs { | |||
195 | u16 leveldetect1; | 195 | u16 leveldetect1; |
196 | u16 risingdetect; | 196 | u16 risingdetect; |
197 | u16 fallingdetect; | 197 | u16 fallingdetect; |
198 | u16 irqctrl; | ||
199 | u16 edgectrl1; | ||
200 | u16 edgectrl2; | ||
198 | 201 | ||
199 | bool irqenable_inv; | 202 | bool irqenable_inv; |
200 | }; | 203 | }; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index ceb9edf16dab..f39d9e4967b2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -199,52 +199,32 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, | |||
199 | __raw_writel(val, reg); | 199 | __raw_writel(val, reg); |
200 | } | 200 | } |
201 | 201 | ||
202 | #ifdef CONFIG_ARCH_OMAP2PLUS | 202 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, |
203 | static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | ||
204 | int trigger) | 203 | int trigger) |
205 | { | 204 | { |
206 | void __iomem *base = bank->base; | 205 | void __iomem *base = bank->base; |
207 | u32 gpio_bit = 1 << gpio; | 206 | u32 gpio_bit = 1 << gpio; |
208 | 207 | ||
209 | if (cpu_is_omap44xx()) { | 208 | _gpio_rmw(base, bank->regs->leveldetect0, gpio_bit, |
210 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, | 209 | trigger & IRQ_TYPE_LEVEL_LOW); |
211 | trigger & IRQ_TYPE_LEVEL_LOW); | 210 | _gpio_rmw(base, bank->regs->leveldetect1, gpio_bit, |
212 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, | 211 | trigger & IRQ_TYPE_LEVEL_HIGH); |
213 | trigger & IRQ_TYPE_LEVEL_HIGH); | 212 | _gpio_rmw(base, bank->regs->risingdetect, gpio_bit, |
214 | _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, | 213 | trigger & IRQ_TYPE_EDGE_RISING); |
215 | trigger & IRQ_TYPE_EDGE_RISING); | 214 | _gpio_rmw(base, bank->regs->fallingdetect, gpio_bit, |
216 | _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, | 215 | trigger & IRQ_TYPE_EDGE_FALLING); |
217 | trigger & IRQ_TYPE_EDGE_FALLING); | 216 | |
218 | } else { | 217 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) |
219 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 218 | _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); |
220 | trigger & IRQ_TYPE_LEVEL_LOW); | 219 | |
221 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | ||
222 | trigger & IRQ_TYPE_LEVEL_HIGH); | ||
223 | _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | ||
224 | trigger & IRQ_TYPE_EDGE_RISING); | ||
225 | _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | ||
226 | trigger & IRQ_TYPE_EDGE_FALLING); | ||
227 | } | ||
228 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { | ||
229 | if (cpu_is_omap44xx()) { | ||
230 | _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit, | ||
231 | trigger != 0); | ||
232 | } else { | ||
233 | /* | ||
234 | * GPIO wakeup request can only be generated on edge | ||
235 | * transitions | ||
236 | */ | ||
237 | if (trigger & IRQ_TYPE_EDGE_BOTH) | ||
238 | __raw_writel(1 << gpio, bank->base | ||
239 | + OMAP24XX_GPIO_SETWKUENA); | ||
240 | else | ||
241 | __raw_writel(1 << gpio, bank->base | ||
242 | + OMAP24XX_GPIO_CLEARWKUENA); | ||
243 | } | ||
244 | } | ||
245 | /* This part needs to be executed always for OMAP{34xx, 44xx} */ | 220 | /* This part needs to be executed always for OMAP{34xx, 44xx} */ |
246 | if (cpu_is_omap34xx() || cpu_is_omap44xx() || | 221 | if (!bank->regs->irqctrl) { |
247 | (bank->non_wakeup_gpios & gpio_bit)) { | 222 | /* On omap24xx proceed only when valid GPIO bit is set */ |
223 | if (bank->non_wakeup_gpios) { | ||
224 | if (!(bank->non_wakeup_gpios & gpio_bit)) | ||
225 | goto exit; | ||
226 | } | ||
227 | |||
248 | /* | 228 | /* |
249 | * Log the edge gpio and manually trigger the IRQ | 229 | * Log the edge gpio and manually trigger the IRQ |
250 | * after resume if the input level changes | 230 | * after resume if the input level changes |
@@ -257,11 +237,11 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
257 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; | 237 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; |
258 | } | 238 | } |
259 | 239 | ||
240 | exit: | ||
260 | bank->level_mask = | 241 | bank->level_mask = |
261 | __raw_readl(bank->base + bank->regs->leveldetect0) | | 242 | __raw_readl(bank->base + bank->regs->leveldetect0) | |
262 | __raw_readl(bank->base + bank->regs->leveldetect1); | 243 | __raw_readl(bank->base + bank->regs->leveldetect1); |
263 | } | 244 | } |
264 | #endif | ||
265 | 245 | ||
266 | #ifdef CONFIG_ARCH_OMAP1 | 246 | #ifdef CONFIG_ARCH_OMAP1 |
267 | /* | 247 | /* |
@@ -273,23 +253,10 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) | |||
273 | void __iomem *reg = bank->base; | 253 | void __iomem *reg = bank->base; |
274 | u32 l = 0; | 254 | u32 l = 0; |
275 | 255 | ||
276 | switch (bank->method) { | 256 | if (!bank->regs->irqctrl) |
277 | case METHOD_MPUIO: | ||
278 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; | ||
279 | break; | ||
280 | #ifdef CONFIG_ARCH_OMAP15XX | ||
281 | case METHOD_GPIO_1510: | ||
282 | reg += OMAP1510_GPIO_INT_CONTROL; | ||
283 | break; | ||
284 | #endif | ||
285 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
286 | case METHOD_GPIO_7XX: | ||
287 | reg += OMAP7XX_GPIO_INT_CONTROL; | ||
288 | break; | ||
289 | #endif | ||
290 | default: | ||
291 | return; | 257 | return; |
292 | } | 258 | |
259 | reg += bank->regs->irqctrl; | ||
293 | 260 | ||
294 | l = __raw_readl(reg); | 261 | l = __raw_readl(reg); |
295 | if ((l >> gpio) & 1) | 262 | if ((l >> gpio) & 1) |
@@ -299,31 +266,21 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) | |||
299 | 266 | ||
300 | __raw_writel(l, reg); | 267 | __raw_writel(l, reg); |
301 | } | 268 | } |
269 | #else | ||
270 | static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {} | ||
302 | #endif | 271 | #endif |
303 | 272 | ||
304 | static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | 273 | static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) |
305 | { | 274 | { |
306 | void __iomem *reg = bank->base; | 275 | void __iomem *reg = bank->base; |
276 | void __iomem *base = bank->base; | ||
307 | u32 l = 0; | 277 | u32 l = 0; |
308 | 278 | ||
309 | switch (bank->method) { | 279 | if (bank->regs->leveldetect0 && bank->regs->wkup_en) { |
310 | #ifdef CONFIG_ARCH_OMAP1 | 280 | set_gpio_trigger(bank, gpio, trigger); |
311 | case METHOD_MPUIO: | 281 | } else if (bank->regs->irqctrl) { |
312 | reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride; | 282 | reg += bank->regs->irqctrl; |
313 | l = __raw_readl(reg); | 283 | |
314 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | ||
315 | bank->toggle_mask |= 1 << gpio; | ||
316 | if (trigger & IRQ_TYPE_EDGE_RISING) | ||
317 | l |= 1 << gpio; | ||
318 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | ||
319 | l &= ~(1 << gpio); | ||
320 | else | ||
321 | goto bad; | ||
322 | break; | ||
323 | #endif | ||
324 | #ifdef CONFIG_ARCH_OMAP15XX | ||
325 | case METHOD_GPIO_1510: | ||
326 | reg += OMAP1510_GPIO_INT_CONTROL; | ||
327 | l = __raw_readl(reg); | 284 | l = __raw_readl(reg); |
328 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | 285 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) |
329 | bank->toggle_mask |= 1 << gpio; | 286 | bank->toggle_mask |= 1 << gpio; |
@@ -332,15 +289,15 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
332 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | 289 | else if (trigger & IRQ_TYPE_EDGE_FALLING) |
333 | l &= ~(1 << gpio); | 290 | l &= ~(1 << gpio); |
334 | else | 291 | else |
335 | goto bad; | 292 | return -EINVAL; |
336 | break; | 293 | |
337 | #endif | 294 | __raw_writel(l, reg); |
338 | #ifdef CONFIG_ARCH_OMAP16XX | 295 | } else if (bank->regs->edgectrl1) { |
339 | case METHOD_GPIO_1610: | ||
340 | if (gpio & 0x08) | 296 | if (gpio & 0x08) |
341 | reg += OMAP1610_GPIO_EDGE_CTRL2; | 297 | reg += bank->regs->edgectrl2; |
342 | else | 298 | else |
343 | reg += OMAP1610_GPIO_EDGE_CTRL1; | 299 | reg += bank->regs->edgectrl1; |
300 | |||
344 | gpio &= 0x07; | 301 | gpio &= 0x07; |
345 | l = __raw_readl(reg); | 302 | l = __raw_readl(reg); |
346 | l &= ~(3 << (gpio << 1)); | 303 | l &= ~(3 << (gpio << 1)); |
@@ -348,40 +305,12 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
348 | l |= 2 << (gpio << 1); | 305 | l |= 2 << (gpio << 1); |
349 | if (trigger & IRQ_TYPE_EDGE_FALLING) | 306 | if (trigger & IRQ_TYPE_EDGE_FALLING) |
350 | l |= 1 << (gpio << 1); | 307 | l |= 1 << (gpio << 1); |
351 | if (trigger) | 308 | |
352 | /* Enable wake-up during idle for dynamic tick */ | 309 | /* Enable wake-up during idle for dynamic tick */ |
353 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA); | 310 | _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger); |
354 | else | 311 | __raw_writel(l, reg); |
355 | __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA); | ||
356 | break; | ||
357 | #endif | ||
358 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
359 | case METHOD_GPIO_7XX: | ||
360 | reg += OMAP7XX_GPIO_INT_CONTROL; | ||
361 | l = __raw_readl(reg); | ||
362 | if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) | ||
363 | bank->toggle_mask |= 1 << gpio; | ||
364 | if (trigger & IRQ_TYPE_EDGE_RISING) | ||
365 | l |= 1 << gpio; | ||
366 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | ||
367 | l &= ~(1 << gpio); | ||
368 | else | ||
369 | goto bad; | ||
370 | break; | ||
371 | #endif | ||
372 | #ifdef CONFIG_ARCH_OMAP2PLUS | ||
373 | case METHOD_GPIO_24XX: | ||
374 | case METHOD_GPIO_44XX: | ||
375 | set_24xx_gpio_triggering(bank, gpio, trigger); | ||
376 | return 0; | ||
377 | #endif | ||
378 | default: | ||
379 | goto bad; | ||
380 | } | 312 | } |
381 | __raw_writel(l, reg); | ||
382 | return 0; | 313 | return 0; |
383 | bad: | ||
384 | return -EINVAL; | ||
385 | } | 314 | } |
386 | 315 | ||
387 | static int gpio_irq_type(struct irq_data *d, unsigned type) | 316 | static int gpio_irq_type(struct irq_data *d, unsigned type) |