aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap1/gpio16xx.c8
-rw-r--r--arch/arm/mach-omap2/gpio.c7
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h4
-rw-r--r--drivers/gpio/gpio-omap.c124
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);