diff options
| -rw-r--r-- | arch/arm/plat-omap/gpio.c | 93 |
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 | |||
| 1134 | static 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 | |||
| 1147 | static 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 | */ | ||
| 1162 | static 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 | |||
| 1170 | static 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 | |||
| 1179 | static 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 | ||
| 1186 | static inline void mpuio_init(void) {} | ||
| 1187 | #endif /* 16xx */ | ||
| 1188 | |||
| 1119 | #else | 1189 | #else |
| 1120 | 1190 | ||
| 1121 | extern struct irq_chip mpuio_irq_chip; | 1191 | extern struct irq_chip mpuio_irq_chip; |
| 1122 | 1192 | ||
| 1123 | #define bank_is_mpuio(bank) 0 | 1193 | #define bank_is_mpuio(bank) 0 |
| 1194 | static 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) { |
