aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2006-12-06 20:14:11 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-05 05:57:17 -0400
commit11a78b7944963a8b052be46108d07a3ced9e2762 (patch)
treedd93c3f88de3c8047186c5ee43ecc763cf6f7318 /arch
parent58781016c3637caf314ca7f579ce0acd1b0378dc (diff)
ARM: OMAP: MPUIO wake updates
GPIO and MPUIO wake updates: - Hook MPUIOs into the irq wakeup framework too. This uses a platform device to update irq enables during system sleep states, instead of a sys_device, since the latter is no longer needed for such things. - Also forward enable/disable irq wake requests to the relevant GPIO controller, so the top level IRQ dispatcher can (eventually) handle these wakeup events automatically if more than one GPIO pin needs to be a wakeup event source. - Minor tweak to the 24xx non-wakeup gpio stuff: no need to check such read-only data under the spinlock. This assumes (maybe wrongly?) that only 16xx can do GPIO wakeup; without a 15xx I can't test such stuff. Also this expects the top level IRQ dispatcher to properly handle requests to enable/disable irq wake, which is currently known to be wrong: omap1 saves the flags but ignores them, omap2 doesn't even save it. (Wakeup events are, wrongly, hardwired in the relevant mach-omapX/pm.c file ...) So MPUIO irqs won't yet trigger system wakeup. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
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) {