diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-06-16 01:09:34 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-06-16 17:29:00 -0400 |
commit | 4d4e20f77c6170eaec61976e0a165bdff6b09d79 (patch) | |
tree | 37241092f837f9c670ea490eef05b67ff68b5959 /arch/arm | |
parent | 33f45ea91706f8fdde04bd6c2245f679403ec63f (diff) |
ARM: 6175/1: nomadik-gpio: implement set_wake
So that set_irq_wake() works.
Cc: Alessandro Rubini <rubini@unipv.it>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 14466519fcc3..9cb717417ba0 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -301,32 +301,41 @@ static void nmk_gpio_irq_ack(unsigned int irq) | |||
301 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); | 301 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); |
302 | } | 302 | } |
303 | 303 | ||
304 | enum nmk_gpio_irq_type { | ||
305 | NORMAL, | ||
306 | WAKE, | ||
307 | }; | ||
308 | |||
304 | static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, | 309 | static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, |
305 | int gpio, bool enable) | 310 | int gpio, enum nmk_gpio_irq_type which, |
311 | bool enable) | ||
306 | { | 312 | { |
313 | u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC; | ||
314 | u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC; | ||
307 | u32 bitmask = nmk_gpio_get_bitmask(gpio); | 315 | u32 bitmask = nmk_gpio_get_bitmask(gpio); |
308 | u32 reg; | 316 | u32 reg; |
309 | 317 | ||
310 | /* we must individually set/clear the two edges */ | 318 | /* we must individually set/clear the two edges */ |
311 | if (nmk_chip->edge_rising & bitmask) { | 319 | if (nmk_chip->edge_rising & bitmask) { |
312 | reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); | 320 | reg = readl(nmk_chip->addr + rimsc); |
313 | if (enable) | 321 | if (enable) |
314 | reg |= bitmask; | 322 | reg |= bitmask; |
315 | else | 323 | else |
316 | reg &= ~bitmask; | 324 | reg &= ~bitmask; |
317 | writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); | 325 | writel(reg, nmk_chip->addr + rimsc); |
318 | } | 326 | } |
319 | if (nmk_chip->edge_falling & bitmask) { | 327 | if (nmk_chip->edge_falling & bitmask) { |
320 | reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); | 328 | reg = readl(nmk_chip->addr + fimsc); |
321 | if (enable) | 329 | if (enable) |
322 | reg |= bitmask; | 330 | reg |= bitmask; |
323 | else | 331 | else |
324 | reg &= ~bitmask; | 332 | reg &= ~bitmask; |
325 | writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); | 333 | writel(reg, nmk_chip->addr + fimsc); |
326 | } | 334 | } |
327 | } | 335 | } |
328 | 336 | ||
329 | static void nmk_gpio_irq_modify(unsigned int irq, bool enable) | 337 | static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which, |
338 | bool enable) | ||
330 | { | 339 | { |
331 | int gpio; | 340 | int gpio; |
332 | struct nmk_gpio_chip *nmk_chip; | 341 | struct nmk_gpio_chip *nmk_chip; |
@@ -337,26 +346,35 @@ static void nmk_gpio_irq_modify(unsigned int irq, bool enable) | |||
337 | nmk_chip = get_irq_chip_data(irq); | 346 | nmk_chip = get_irq_chip_data(irq); |
338 | bitmask = nmk_gpio_get_bitmask(gpio); | 347 | bitmask = nmk_gpio_get_bitmask(gpio); |
339 | if (!nmk_chip) | 348 | if (!nmk_chip) |
340 | return; | 349 | return -EINVAL; |
341 | 350 | ||
342 | spin_lock_irqsave(&nmk_chip->lock, flags); | 351 | spin_lock_irqsave(&nmk_chip->lock, flags); |
343 | __nmk_gpio_irq_modify(nmk_chip, gpio, enable); | 352 | __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable); |
344 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 353 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
354 | |||
355 | return 0; | ||
345 | } | 356 | } |
346 | 357 | ||
347 | static void nmk_gpio_irq_mask(unsigned int irq) | 358 | static void nmk_gpio_irq_mask(unsigned int irq) |
348 | { | 359 | { |
349 | nmk_gpio_irq_modify(irq, false); | 360 | nmk_gpio_irq_modify(irq, NORMAL, false); |
350 | }; | 361 | } |
351 | 362 | ||
352 | static void nmk_gpio_irq_unmask(unsigned int irq) | 363 | static void nmk_gpio_irq_unmask(unsigned int irq) |
353 | { | 364 | { |
354 | nmk_gpio_irq_modify(irq, true); | 365 | nmk_gpio_irq_modify(irq, NORMAL, true); |
366 | } | ||
367 | |||
368 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) | ||
369 | { | ||
370 | return nmk_gpio_irq_modify(irq, WAKE, on); | ||
355 | } | 371 | } |
356 | 372 | ||
357 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | 373 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) |
358 | { | 374 | { |
359 | bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED); | 375 | struct irq_desc *desc = irq_to_desc(irq); |
376 | bool enabled = !(desc->status & IRQ_DISABLED); | ||
377 | bool wake = desc->wake_depth; | ||
360 | int gpio; | 378 | int gpio; |
361 | struct nmk_gpio_chip *nmk_chip; | 379 | struct nmk_gpio_chip *nmk_chip; |
362 | unsigned long flags; | 380 | unsigned long flags; |
@@ -376,7 +394,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
376 | spin_lock_irqsave(&nmk_chip->lock, flags); | 394 | spin_lock_irqsave(&nmk_chip->lock, flags); |
377 | 395 | ||
378 | if (enabled) | 396 | if (enabled) |
379 | __nmk_gpio_irq_modify(nmk_chip, gpio, false); | 397 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false); |
398 | |||
399 | if (wake) | ||
400 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false); | ||
380 | 401 | ||
381 | nmk_chip->edge_rising &= ~bitmask; | 402 | nmk_chip->edge_rising &= ~bitmask; |
382 | if (type & IRQ_TYPE_EDGE_RISING) | 403 | if (type & IRQ_TYPE_EDGE_RISING) |
@@ -387,7 +408,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
387 | nmk_chip->edge_falling |= bitmask; | 408 | nmk_chip->edge_falling |= bitmask; |
388 | 409 | ||
389 | if (enabled) | 410 | if (enabled) |
390 | __nmk_gpio_irq_modify(nmk_chip, gpio, true); | 411 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true); |
412 | |||
413 | if (wake) | ||
414 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); | ||
391 | 415 | ||
392 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 416 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
393 | 417 | ||
@@ -400,6 +424,7 @@ static struct irq_chip nmk_gpio_irq_chip = { | |||
400 | .mask = nmk_gpio_irq_mask, | 424 | .mask = nmk_gpio_irq_mask, |
401 | .unmask = nmk_gpio_irq_unmask, | 425 | .unmask = nmk_gpio_irq_unmask, |
402 | .set_type = nmk_gpio_irq_set_type, | 426 | .set_type = nmk_gpio_irq_set_type, |
427 | .set_wake = nmk_gpio_irq_set_wake, | ||
403 | }; | 428 | }; |
404 | 429 | ||
405 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 430 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |