aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-omap/gpio.c93
1 files changed, 83 insertions, 10 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 14a3f7118c73..df0ff0fd881a 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -773,29 +773,35 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
773{ 773{
774 switch (bank->method) { 774 switch (bank->method) {
775#ifdef CONFIG_ARCH_OMAP16XX 775#ifdef CONFIG_ARCH_OMAP16XX
776 case METHOD_MPUIO:
776 case METHOD_GPIO_1610: 777 case METHOD_GPIO_1610:
777 spin_lock(&bank->lock); 778 spin_lock(&bank->lock);
778 if (enable) 779 if (enable) {
779 bank->suspend_wakeup |= (1 << gpio); 780 bank->suspend_wakeup |= (1 << gpio);
780 else 781 enable_irq_wake(bank->irq);
782 } else {
783 disable_irq_wake(bank->irq);
781 bank->suspend_wakeup &= ~(1 << gpio); 784 bank->suspend_wakeup &= ~(1 << gpio);
785 }
782 spin_unlock(&bank->lock); 786 spin_unlock(&bank->lock);
783 return 0; 787 return 0;
784#endif 788#endif
785#ifdef CONFIG_ARCH_OMAP24XX 789#ifdef CONFIG_ARCH_OMAP24XX
786 case METHOD_GPIO_24XX: 790 case METHOD_GPIO_24XX:
791 if (bank->non_wakeup_gpios & (1 << gpio)) {
792 printk(KERN_ERR "Unable to modify wakeup on "
793 "non-wakeup GPIO%d\n",
794 (bank - gpio_bank) * 32 + gpio);
795 return -EINVAL;
796 }
787 spin_lock(&bank->lock); 797 spin_lock(&bank->lock);
788 if (enable) { 798 if (enable) {
789 if (bank->non_wakeup_gpios & (1 << gpio)) {
790 printk(KERN_ERR "Unable to enable wakeup on "
791 "non-wakeup GPIO%d\n",
792 (bank - gpio_bank) * 32 + gpio);
793 spin_unlock(&bank->lock);
794 return -EINVAL;
795 }
796 bank->suspend_wakeup |= (1 << gpio); 799 bank->suspend_wakeup |= (1 << gpio);
797 } else 800 enable_irq_wake(bank->irq);
801 } else {
802 disable_irq_wake(bank->irq);
798 bank->suspend_wakeup &= ~(1 << gpio); 803 bank->suspend_wakeup &= ~(1 << gpio);
804 }
799 spin_unlock(&bank->lock); 805 spin_unlock(&bank->lock);
800 return 0; 806 return 0;
801#endif 807#endif
@@ -1111,16 +1117,81 @@ static struct irq_chip mpuio_irq_chip = {
1111 .mask = mpuio_mask_irq, 1117 .mask = mpuio_mask_irq,
1112 .unmask = mpuio_unmask_irq, 1118 .unmask = mpuio_unmask_irq,
1113 .set_type = gpio_irq_type, 1119 .set_type = gpio_irq_type,
1120#ifdef CONFIG_ARCH_OMAP16XX
1121 /* REVISIT: assuming only 16xx supports MPUIO wake events */
1122 .set_wake = gpio_wake_enable,
1123#endif
1114}; 1124};
1115 1125
1116 1126
1117#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) 1127#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO)
1118 1128
1129
1130#ifdef CONFIG_ARCH_OMAP16XX
1131
1132#include <linux/platform_device.h>
1133
1134static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg)
1135{
1136 struct gpio_bank *bank = platform_get_drvdata(pdev);
1137 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
1138
1139 spin_lock(&bank->lock);
1140 bank->saved_wakeup = __raw_readl(mask_reg);
1141 __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg);
1142 spin_unlock(&bank->lock);
1143
1144 return 0;
1145}
1146
1147static int omap_mpuio_resume_early(struct platform_device *pdev)
1148{
1149 struct gpio_bank *bank = platform_get_drvdata(pdev);
1150 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
1151
1152 spin_lock(&bank->lock);
1153 __raw_writel(bank->saved_wakeup, mask_reg);
1154 spin_unlock(&bank->lock);
1155
1156 return 0;
1157}
1158
1159/* use platform_driver for this, now that there's no longer any
1160 * point to sys_device (other than not disturbing old code).
1161 */
1162static struct platform_driver omap_mpuio_driver = {
1163 .suspend_late = omap_mpuio_suspend_late,
1164 .resume_early = omap_mpuio_resume_early,
1165 .driver = {
1166 .name = "mpuio",
1167 },
1168};
1169
1170static struct platform_device omap_mpuio_device = {
1171 .name = "mpuio",
1172 .id = -1,
1173 .dev = {
1174 .driver = &omap_mpuio_driver.driver,
1175 }
1176 /* could list the /proc/iomem resources */
1177};
1178
1179static inline void mpuio_init(void)
1180{
1181 if (platform_driver_register(&omap_mpuio_driver) == 0)
1182 (void) platform_device_register(&omap_mpuio_device);
1183}
1184
1185#else
1186static inline void mpuio_init(void) {}
1187#endif /* 16xx */
1188
1119#else 1189#else
1120 1190
1121extern struct irq_chip mpuio_irq_chip; 1191extern struct irq_chip mpuio_irq_chip;
1122 1192
1123#define bank_is_mpuio(bank) 0 1193#define bank_is_mpuio(bank) 0
1194static inline void mpuio_init(void) {}
1124 1195
1125#endif 1196#endif
1126 1197
@@ -1487,6 +1558,8 @@ static int __init omap_gpio_sysinit(void)
1487 if (!initialized) 1558 if (!initialized)
1488 ret = _omap_gpio_init(); 1559 ret = _omap_gpio_init();
1489 1560
1561 mpuio_init();
1562
1490#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) 1563#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
1491 if (cpu_is_omap16xx() || cpu_is_omap24xx()) { 1564 if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
1492 if (ret == 0) { 1565 if (ret == 0) {