diff options
author | Dinh Nguyen <Dinh.Nguyen@freescale.com> | 2010-10-23 18:12:48 +0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-10-26 18:24:06 +0400 |
commit | a3484ffd2acc196ca934369395fe9aac63ed1a47 (patch) | |
tree | 92f11daf8ea4419dd9d2d27913211190996fd6cc /arch/arm | |
parent | f2d36ecbca2f7a4cde2821a8a70f6f799442e33f (diff) | |
download | linux-a3484ffd2acc196ca934369395fe9aac63ed1a47.tar.xz |
ARM: imx: Add wake functionality to GPIO
Add function definition for irq_chip.set_wake to enable GPIO to
wake-up the system.
This patch has been tested on a MX51 Babbage system that had suspend
code implemented. The set_wake implementation is necessary for a
GPIO to wake up a system from suspend.
Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/plat-mxc/gpio.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 9d38da077edb..9c3e36232b5b 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -20,6 +20,7 @@ */ #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/gpio.h> @@ -201,11 +202,42 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) } } +/* + * Set interrupt number "irq" in the GPIO as a wake-up source. + * While system is running, all registered GPIO interrupts need to have + * wake-up enabled. When system is suspended, only selected GPIO interrupts + * need to have wake-up enabled. + * @param irq interrupt source number + * @param enable enable as wake-up if equal to non-zero + * @return This function returns 0 on success. + */ +static int gpio_set_wake_irq(u32 irq, u32 enable) +{ + u32 gpio = irq_to_gpio(irq); + u32 gpio_idx = gpio & 0x1F; + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + + if (enable) { + if (port->irq_high && (gpio_idx >= 16)) + enable_irq_wake(port->irq_high); + else + enable_irq_wake(port->irq); + } else { + if (port->irq_high && (gpio_idx >= 16)) + disable_irq_wake(port->irq_high); + else + disable_irq_wake(port->irq); + } + + return 0; +} + static struct irq_chip gpio_irq_chip = { .ack = gpio_ack_irq, .mask = gpio_mask_irq, .unmask = gpio_unmask_irq, .set_type = gpio_set_irq_type, + .set_wake = gpio_set_wake_irq, }; static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, |