diff options
author | Tarun Kanti DebBarma <tarun.kanti@ti.com> | 2011-09-13 05:32:14 -0400 |
---|---|---|
committer | Tarun Kanti DebBarma <tarun.kanti@ti.com> | 2012-02-06 03:43:42 -0500 |
commit | 5e571f38f6a44ef541fac0821631509d787ef0cd (patch) | |
tree | eb19a3db74cae81d503ec8689fcc03bde8c27dfb /drivers/gpio/gpio-omap.c | |
parent | ae10f2336b9c0c8da73da2878eba684ab876eb8f (diff) |
gpio/omap: cleanup set_gpio_triggering function
Getting rid of ifdefs within the function by adding register offset intctrl
and associating OMAPXXXX_GPIO_INT_CONTROL in respective SoC specific files.
Also, use wkup_status register consistently instead of referring to wakeup
clear and wakeup set register offsets. Get rid of cpu_is_xxxx checks in
set_gpio_trigger() using irqctrl.
Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 157 |
1 files changed, 43 insertions, 114 deletions
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) |