diff options
-rw-r--r-- | arch/arm/mach-omap1/gpio16xx.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpio.c | 7 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 124 |
4 files changed, 41 insertions, 102 deletions
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index df4bb44..179cbfb 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -52,6 +52,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { .bank_type = METHOD_MPUIO, .bank_width = 16, .bank_stride = 1, + .suspend_support = true, .regs = &omap16xx_mpuio_regs, }; @@ -89,12 +90,16 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .irqenable = OMAP1610_GPIO_IRQENABLE1, .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, + .wkup_status = OMAP1610_GPIO_WAKEUPENABLE, + .wkup_clear = OMAP1610_GPIO_CLEAR_WAKEUPENA, + .wkup_set = OMAP1610_GPIO_SET_WAKEUPENA, }; static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { .virtual_irq_start = IH_GPIO_BASE, .bank_type = METHOD_GPIO_1610, .bank_width = 16, + .suspend_support = true, .regs = &omap16xx_gpio_regs, }; @@ -125,6 +130,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { .virtual_irq_start = IH_GPIO_BASE + 16, .bank_type = METHOD_GPIO_1610, .bank_width = 16, + .suspend_support = true, .regs = &omap16xx_gpio_regs, }; @@ -155,6 +161,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { .virtual_irq_start = IH_GPIO_BASE + 32, .bank_type = METHOD_GPIO_1610, .bank_width = 16, + .suspend_support = true, .regs = &omap16xx_gpio_regs, }; @@ -185,6 +192,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { .virtual_irq_start = IH_GPIO_BASE + 48, .bank_type = METHOD_GPIO_1610, .bank_width = 16, + .suspend_support = true, .regs = &omap16xx_gpio_regs, }; diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index cdbc728..ea1556b 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -72,6 +72,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; pdata->bank_width = dev_attr->bank_width; + pdata->suspend_support = true; pdata->dbck_flag = dev_attr->dbck_flag; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); pdata->get_context_loss_count = omap_gpio_get_context_loss; @@ -108,6 +109,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; pdata->regs->ctrl = OMAP24XX_GPIO_CTRL; + pdata->regs->wkup_status = OMAP24XX_GPIO_WAKE_EN; + pdata->regs->wkup_clear = OMAP24XX_GPIO_CLEARWKUENA; + pdata->regs->wkup_set = OMAP24XX_GPIO_SETWKUENA; break; case 2: pdata->bank_type = METHOD_GPIO_44XX; @@ -125,6 +129,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; pdata->regs->ctrl = OMAP4_GPIO_CTRL; + pdata->regs->wkup_status = OMAP4_GPIO_IRQWAKEN0; + pdata->regs->wkup_clear = OMAP4_GPIO_IRQWAKEN0; + pdata->regs->wkup_set = OMAP4_GPIO_IRQWAKEN0; break; default: WARN(1, "Invalid gpio bank_type\n"); diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index cf41743..62eeed8 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -189,6 +189,9 @@ struct omap_gpio_reg_offs { u16 debounce; u16 debounce_en; u16 ctrl; + u16 wkup_status; + u16 wkup_clear; + u16 wkup_set; bool irqenable_inv; }; @@ -198,6 +201,7 @@ struct omap_gpio_platform_data { int bank_type; int bank_width; /* GPIO bank width */ int bank_stride; /* Only needed for omap1 MPUIO */ + bool suspend_support; /* If Bank supports suspend/resume operations */ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ bool loses_context; /* whether the bank would ever lose context */ u32 non_wakeup_gpios; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 4ac02b4..1ca8b95 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -50,10 +50,8 @@ struct gpio_bank { u16 irq; u16 virtual_irq_start; int method; -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) u32 suspend_wakeup; u32 saved_wakeup; -#endif u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; struct gpio_regs context; @@ -70,6 +68,7 @@ struct gpio_bank { struct device *dev; bool dbck_flag; bool loses_context; + bool suspend_support; int stride; u32 width; u32 ctx_loss_count; @@ -597,27 +596,11 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) unsigned long flags; spin_lock_irqsave(&bank->lock, flags); -#ifdef CONFIG_ARCH_OMAP16XX - if (bank->method == METHOD_GPIO_1610) { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; - __raw_writel(1 << offset, reg); - } -#endif -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - if (bank->method == METHOD_GPIO_24XX) { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - __raw_writel(1 << offset, reg); - } -#endif -#ifdef CONFIG_ARCH_OMAP4 - if (bank->method == METHOD_GPIO_44XX) { + + if (bank->regs->wkup_clear) /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; - __raw_writel(1 << offset, reg); - } -#endif + __raw_writel(1 << offset, bank->base + bank->regs->wkup_clear); + bank->mod_usage &= ~(1 << offset); if (bank->regs->ctrl && !bank->mod_usage) { @@ -790,15 +773,8 @@ static struct irq_chip gpio_irq_chip = { }; /*---------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_OMAP1 - #define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) -#ifdef CONFIG_ARCH_OMAP16XX - -#include <linux/platform_device.h> - static int omap_mpuio_suspend_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -860,17 +836,6 @@ static inline void mpuio_init(struct gpio_bank *bank) (void) platform_device_register(&omap_mpuio_device); } -#else -static inline void mpuio_init(struct gpio_bank *bank) {} -#endif /* 16xx */ - -#else - -#define bank_is_mpuio(bank) 0 -static inline void mpuio_init(struct gpio_bank *bank) {} - -#endif - /*---------------------------------------------------------------------*/ /* REVISIT these are stupid implementations! replace by ones that @@ -1012,7 +977,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); } } else if (cpu_class_is_omap1()) { - if (bank_is_mpuio(bank)) { + if (bank_is_mpuio(bank) && bank->suspend_support) { __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT / bank->stride); mpuio_init(bank); @@ -1067,8 +1032,8 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, ct->chip.irq_mask = irq_gc_mask_set_bit; ct->chip.irq_unmask = irq_gc_mask_clr_bit; ct->chip.irq_set_type = gpio_irq_type; - /* REVISIT: assuming only 16xx supports MPUIO wake events */ - if (cpu_is_omap16xx()) + + if (bank->suspend_support) ct->chip.irq_set_wake = gpio_wake_enable, ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride; @@ -1096,9 +1061,8 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) bank->chip.to_irq = gpio_2irq; if (bank_is_mpuio(bank)) { bank->chip.label = "mpuio"; -#ifdef CONFIG_ARCH_OMAP16XX - bank->chip.dev = &omap_mpuio_device.dev; -#endif + if (bank->suspend_support) + bank->chip.dev = &omap_mpuio_device.dev; bank->chip.base = OMAP_MPUIO(0); } else { bank->chip.label = "gpio"; @@ -1162,6 +1126,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; + bank->suspend_support = pdata->suspend_support; bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->loses_context = pdata->loses_context; bank->regs = pdata->regs; @@ -1207,45 +1172,22 @@ err_exit: return ret; } -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) static int omap_gpio_suspend(void) { struct gpio_bank *bank; - if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) - return 0; - list_for_each_entry(bank, &omap_gpio_list, node) { void __iomem *wake_status; void __iomem *wake_clear; void __iomem *wake_set; unsigned long flags; - switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP16XX - case METHOD_GPIO_1610: - wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; - wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; - wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; - break; -#endif -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - case METHOD_GPIO_24XX: - wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; - wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; - break; -#endif -#ifdef CONFIG_ARCH_OMAP4 - case METHOD_GPIO_44XX: - wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0; - wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; - wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; - break; -#endif - default: - continue; - } + if (!bank->suspend_support) + return 0; + + wake_status = bank->base + bank->regs->wkup_status; + wake_clear = bank->base + bank->regs->wkup_clear; + wake_set = bank->base + bank->regs->wkup_set; spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(wake_status); @@ -1261,36 +1203,16 @@ static void omap_gpio_resume(void) { struct gpio_bank *bank; - if (!cpu_class_is_omap2() && !cpu_is_omap16xx()) - return; - list_for_each_entry(bank, &omap_gpio_list, node) { void __iomem *wake_clear; void __iomem *wake_set; unsigned long flags; - switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP16XX - case METHOD_GPIO_1610: - wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; - wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; - break; -#endif -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - case METHOD_GPIO_24XX: - wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; - break; -#endif -#ifdef CONFIG_ARCH_OMAP4 - case METHOD_GPIO_44XX: - wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; - wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; - break; -#endif - default: - continue; - } + if (!bank->suspend_support) + return; + + wake_clear = bank->base + bank->regs->wkup_clear; + wake_set = bank->base + bank->regs->wkup_set; spin_lock_irqsave(&bank->lock, flags); __raw_writel(0xffffffff, wake_clear); @@ -1304,8 +1226,6 @@ static struct syscore_ops omap_gpio_syscore_ops = { .resume = omap_gpio_resume, }; -#endif - #ifdef CONFIG_ARCH_OMAP2PLUS static void omap_gpio_save_context(struct gpio_bank *bank); |