diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-03-17 05:49:04 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2011-03-14 09:05:15 -0400 |
commit | c84c7c08e320acfd10a0b7e55dbb0bc819b6d284 (patch) | |
tree | f9f4f13608e50c7b85ba5ef664382af6b1723d4d /arch/arm/plat-nomadik | |
parent | d0b543c772af20f576e204cae442ccfd221631a7 (diff) |
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')
-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 { | |||
44 | /* Keep track of configured edges */ | 44 | /* Keep track of configured edges */ |
45 | u32 edge_rising; | 45 | u32 edge_rising; |
46 | u32 edge_falling; | 46 | u32 edge_falling; |
47 | u32 backup[10]; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, | 50 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, |
@@ -792,14 +793,60 @@ out: | |||
792 | return ret; | 793 | return ret; |
793 | } | 794 | } |
794 | 795 | ||
796 | #ifdef CONFIG_PM | ||
797 | static int nmk_gpio_pm(struct platform_device *dev, bool suspend) | ||
798 | { | ||
799 | struct nmk_gpio_chip *nmk_chip = platform_get_drvdata(dev); | ||
800 | int i; | ||
801 | static const unsigned int regs[] = { | ||
802 | NMK_GPIO_DAT, | ||
803 | NMK_GPIO_PDIS, | ||
804 | NMK_GPIO_DIR, | ||
805 | NMK_GPIO_AFSLA, | ||
806 | NMK_GPIO_AFSLB, | ||
807 | NMK_GPIO_SLPC, | ||
808 | NMK_GPIO_RIMSC, | ||
809 | NMK_GPIO_FIMSC, | ||
810 | NMK_GPIO_RWIMSC, | ||
811 | NMK_GPIO_FWIMSC, | ||
812 | }; | ||
813 | |||
814 | BUILD_BUG_ON(ARRAY_SIZE(nmk_chip->backup) != ARRAY_SIZE(regs)); | ||
815 | |||
816 | /* XXX: is this sufficient? what about pull-up/down configuration? */ | ||
817 | |||
818 | for (i = 0; i < ARRAY_SIZE(regs); i++) { | ||
819 | if (suspend) | ||
820 | nmk_chip->backup[i] = readl(nmk_chip->addr + regs[i]); | ||
821 | else | ||
822 | writel(nmk_chip->backup[i], nmk_chip->addr + regs[i]); | ||
823 | } | ||
824 | |||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | static int nmk_gpio_suspend(struct platform_device *dev, pm_message_t state) | ||
829 | { | ||
830 | return nmk_gpio_pm(dev, true); | ||
831 | } | ||
832 | |||
833 | static int nmk_gpio_resume(struct platform_device *dev) | ||
834 | { | ||
835 | return nmk_gpio_pm(dev, false); | ||
836 | } | ||
837 | #else | ||
838 | #define nmk_gpio_suspend NULL | ||
839 | #define nmk_gpio_resume NULL | ||
840 | #endif | ||
841 | |||
795 | static struct platform_driver nmk_gpio_driver = { | 842 | static struct platform_driver nmk_gpio_driver = { |
796 | .driver = { | 843 | .driver = { |
797 | .owner = THIS_MODULE, | 844 | .owner = THIS_MODULE, |
798 | .name = "gpio", | 845 | .name = "gpio", |
799 | }, | 846 | }, |
800 | .probe = nmk_gpio_probe, | 847 | .probe = nmk_gpio_probe, |
801 | .suspend = NULL, /* to be done */ | 848 | .suspend = nmk_gpio_suspend, |
802 | .resume = NULL, | 849 | .resume = nmk_gpio_resume, |
803 | }; | 850 | }; |
804 | 851 | ||
805 | static int __init nmk_gpio_init(void) | 852 | static int __init nmk_gpio_init(void) |