diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-03-17 10:49:04 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2011-03-14 14:05:15 +0100 |
commit | c84c7c08e320acfd10a0b7e55dbb0bc819b6d284 (patch) | |
tree | f9f4f13608e50c7b85ba5ef664382af6b1723d4d /arch/arm/plat-nomadik/gpio.c | |
parent | plat-nomadik: add custom dbg_show for GPIO (diff) | |
download | linux-c84c7c08e320acfd10a0b7e55dbb0bc819b6d284.tar.xz linux-c84c7c08e320acfd10a0b7e55dbb0bc819b6d284.zip |
plat-nomadik: implement suspend/resume for GPIO
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/plat-nomadik/gpio.c')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 5b5fd1ee3c04..46f1af869b7f 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -44,6 +44,7 @@ struct nmk_gpio_chip { /* Keep track of configured edges */ u32 edge_rising; u32 edge_falling; + u32 backup[10]; }; static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, @@ -792,14 +793,60 @@ out: return ret; } +#ifdef CONFIG_PM +static int nmk_gpio_pm(struct platform_device *dev, bool suspend) +{ + struct nmk_gpio_chip *nmk_chip = platform_get_drvdata(dev); + int i; + static const unsigned int regs[] = { + NMK_GPIO_DAT, + NMK_GPIO_PDIS, + NMK_GPIO_DIR, + NMK_GPIO_AFSLA, + NMK_GPIO_AFSLB, + NMK_GPIO_SLPC, + NMK_GPIO_RIMSC, + NMK_GPIO_FIMSC, + NMK_GPIO_RWIMSC, + NMK_GPIO_FWIMSC, + }; + + BUILD_BUG_ON(ARRAY_SIZE(nmk_chip->backup) != ARRAY_SIZE(regs)); + + /* XXX: is this sufficient? what about pull-up/down configuration? */ + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + if (suspend) + nmk_chip->backup[i] = readl(nmk_chip->addr + regs[i]); + else + writel(nmk_chip->backup[i], nmk_chip->addr + regs[i]); + } + + return 0; +} + +static int nmk_gpio_suspend(struct platform_device *dev, pm_message_t state) +{ + return nmk_gpio_pm(dev, true); +} + +static int nmk_gpio_resume(struct platform_device *dev) +{ + return nmk_gpio_pm(dev, false); +} +#else +#define nmk_gpio_suspend NULL +#define nmk_gpio_resume NULL +#endif + static struct platform_driver nmk_gpio_driver = { .driver = { .owner = THIS_MODULE, .name = "gpio", }, .probe = nmk_gpio_probe, - .suspend = NULL, /* to be done */ - .resume = NULL, + .suspend = nmk_gpio_suspend, + .resume = nmk_gpio_resume, }; static int __init nmk_gpio_init(void) |