* [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain
@ 2011-06-15 4:22 Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 03/18] GPIO: OMAP: Make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
` (6 more replies)
0 siblings, 7 replies; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
In omap3, save/restore context is implemented for GPIO banks 2-6 as GPIO bank1
is in wakeup domain. Instead of identifying bank's power domain by bank id,
use 'loses_context' flag which is filled by pwrdm_can_ever_lose_context()
during dev_init.
For getting the powerdomain pointer, omap_hwmod_get_pwrdm() is used.
omap_device_get_pwrdm() could not be used as the pwrdm information needs to be
filled in pdata, whereas omap_device_get_pwrdm() could be used only after
omap_device_build() call.
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/gpio.c | 6 ++++++
arch/arm/plat-omap/include/plat/gpio.h | 1 +
drivers/gpio/gpio-omap.c | 13 ++++++-------
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index f805cda..95195a8 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -24,6 +24,8 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
+#include "powerdomain.h"
+
static struct omap_device_pm_latency omap_gpio_latency[] = {
[0] = {
.deactivate_func = omap_device_idle_hwmods,
@@ -39,6 +41,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
struct omap_gpio_dev_attr *dev_attr;
char *name = "omap_gpio";
int id;
+ struct powerdomain *pwrdm;
/*
* extract the device id from name field available in the
@@ -107,6 +110,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
return -EINVAL;
}
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
+
od = omap_device_build(name, id - 1, oh, pdata,
sizeof(*pdata), omap_gpio_latency,
ARRAY_SIZE(omap_gpio_latency),
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index dd330ed..58d0bf2 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -198,6 +198,7 @@ struct omap_gpio_platform_data {
int bank_width; /* GPIO bank width */
int bank_stride; /* Only needed for omap1 MPUIO */
bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+ bool loses_context; /* whether the bank would ever lose context */
struct omap_gpio_reg_offs *regs;
};
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 4237e25..62c23e6 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -56,6 +56,7 @@ struct gpio_bank {
u32 dbck_enable_mask;
struct device *dev;
bool dbck_flag;
+ bool loses_context;
int stride;
u32 width;
u16 id;
@@ -1170,7 +1171,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->loses_context = pdata->loses_context;
bank->regs = pdata->regs;
if (bank->regs->set_dataout && bank->regs->clr_dataout)
@@ -1326,8 +1327,7 @@ void omap2_gpio_prepare_for_idle(int off_mode)
u32 l1 = 0, l2 = 0;
int j;
- /* TODO: Do not use cpu_is_omap34xx */
- if ((cpu_is_omap34xx()) && (bank->id == 0))
+ if (!bank->loses_context)
continue;
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
@@ -1394,8 +1394,7 @@ void omap2_gpio_resume_after_idle(void)
u32 l = 0, gen, gen0, gen1;
int j;
- /* TODO: Do not use cpu_is_omap34xx */
- if ((cpu_is_omap34xx()) && (bank->id == 0))
+ if (!bank->loses_context)
continue;
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
@@ -1494,7 +1493,7 @@ void omap_gpio_save_context(void)
list_for_each_entry(bank, &omap_gpio_list, node) {
i++;
- if (bank->id == 0)
+ if (!bank->loses_context)
continue;
gpio_context[i].irqenable1 =
@@ -1528,7 +1527,7 @@ void omap_gpio_restore_context(void)
list_for_each_entry(bank, &omap_gpio_list, node) {
i++;
- if (bank->id == 0)
+ if (!bank->loses_context)
continue;
__raw_writel(gpio_context[i].irqenable1,
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 03/18] GPIO: OMAP: Make gpio_context part of gpio_bank structure
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 04/18] GPIO: OMAP: Fix pwrdm_post_transition call sequence Tarun Kanti DebBarma
` (5 subsequent siblings)
6 siblings, 0 replies; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
Currently gpio_context array used to save gpio bank's context, is used only for
OMAP3 architecture. Move gpio_context as part of gpio_bank structure so that it
can be specific to each gpio bank and can be used for any OMAP architecture
Signed-off-by: Charulatha V <charu@ti.com>
---
drivers/gpio/gpio-omap.c | 76 ++++++++++++++++++++-------------------------
1 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 62c23e6..d461558 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -30,6 +30,19 @@
static LIST_HEAD(omap_gpio_list);
+struct gpio_regs {
+ u32 irqenable1;
+ u32 irqenable2;
+ u32 wake_en;
+ u32 ctrl;
+ u32 oe;
+ u32 leveldetect0;
+ u32 leveldetect1;
+ u32 risingdetect;
+ u32 fallingdetect;
+ u32 dataout;
+};
+
struct gpio_bank {
struct list_head node;
unsigned long pbase;
@@ -43,7 +56,7 @@ struct gpio_bank {
#endif
u32 non_wakeup_gpios;
u32 enabled_non_wakeup_gpios;
-
+ struct gpio_regs context;
u32 saved_datain;
u32 saved_fallingdetect;
u32 saved_risingdetect;
@@ -66,23 +79,6 @@ struct gpio_bank {
struct omap_gpio_reg_offs *regs;
};
-#ifdef CONFIG_ARCH_OMAP3
-struct omap3_gpio_regs {
- u32 irqenable1;
- u32 irqenable2;
- u32 wake_en;
- u32 ctrl;
- u32 oe;
- u32 leveldetect0;
- u32 leveldetect1;
- u32 risingdetect;
- u32 fallingdetect;
- u32 dataout;
-};
-
-static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
-#endif
-
#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
@@ -1488,33 +1484,31 @@ void omap2_gpio_resume_after_idle(void)
void omap_gpio_save_context(void)
{
struct gpio_bank *bank;
- int i = 0;
list_for_each_entry(bank, &omap_gpio_list, node) {
- i++;
if (!bank->loses_context)
continue;
- gpio_context[i].irqenable1 =
+ bank->context.irqenable1 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
- gpio_context[i].irqenable2 =
+ bank->context.irqenable2 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
- gpio_context[i].wake_en =
+ bank->context.wake_en =
__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
- gpio_context[i].ctrl =
+ bank->context.ctrl =
__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
- gpio_context[i].oe =
+ bank->context.oe =
__raw_readl(bank->base + OMAP24XX_GPIO_OE);
- gpio_context[i].leveldetect0 =
+ bank->context.leveldetect0 =
__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
- gpio_context[i].leveldetect1 =
+ bank->context.leveldetect1 =
__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
- gpio_context[i].risingdetect =
+ bank->context.risingdetect =
__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
- gpio_context[i].fallingdetect =
+ bank->context.fallingdetect =
__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
- gpio_context[i].dataout =
+ bank->context.dataout =
__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
}
}
@@ -1522,33 +1516,31 @@ void omap_gpio_save_context(void)
void omap_gpio_restore_context(void)
{
struct gpio_bank *bank;
- int i = 0;
list_for_each_entry(bank, &omap_gpio_list, node) {
- i++;
if (!bank->loses_context)
continue;
- __raw_writel(gpio_context[i].irqenable1,
+ __raw_writel(bank->context.irqenable1,
bank->base + OMAP24XX_GPIO_IRQENABLE1);
- __raw_writel(gpio_context[i].irqenable2,
+ __raw_writel(bank->context.irqenable2,
bank->base + OMAP24XX_GPIO_IRQENABLE2);
- __raw_writel(gpio_context[i].wake_en,
+ __raw_writel(bank->context.wake_en,
bank->base + OMAP24XX_GPIO_WAKE_EN);
- __raw_writel(gpio_context[i].ctrl,
+ __raw_writel(bank->context.ctrl,
bank->base + OMAP24XX_GPIO_CTRL);
- __raw_writel(gpio_context[i].oe,
+ __raw_writel(bank->context.oe,
bank->base + OMAP24XX_GPIO_OE);
- __raw_writel(gpio_context[i].leveldetect0,
+ __raw_writel(bank->context.leveldetect0,
bank->base + OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(gpio_context[i].leveldetect1,
+ __raw_writel(bank->context.leveldetect1,
bank->base + OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(gpio_context[i].risingdetect,
+ __raw_writel(bank->context.risingdetect,
bank->base + OMAP24XX_GPIO_RISINGDETECT);
- __raw_writel(gpio_context[i].fallingdetect,
+ __raw_writel(bank->context.fallingdetect,
bank->base + OMAP24XX_GPIO_FALLINGDETECT);
- __raw_writel(gpio_context[i].dataout,
+ __raw_writel(bank->context.dataout,
bank->base + OMAP24XX_GPIO_DATAOUT);
}
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 04/18] GPIO: OMAP: Fix pwrdm_post_transition call sequence
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 03/18] GPIO: OMAP: Make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver Tarun Kanti DebBarma
` (4 subsequent siblings)
6 siblings, 0 replies; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
The context lost count is modified in omap_sram_idle() path when
pwrdm_post_transition() is called. But pwrdm_post_transition() is called
only after omap_gpio_resume_after_idle() is called. Correct this so that
context lost count is modified before calling omap_gpio_resume_after_idle().
This would be useful when OMAP GPIO save/restore context is called by
the OMAP GPIO driver itself.
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/pm34xx.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c155c9d..51d5a5c 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -375,7 +375,6 @@ void omap_sram_idle(void)
printk(KERN_ERR "Invalid mpu state in sram_idle\n");
return;
}
- pwrdm_pre_transition();
/* NEON control */
if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
@@ -398,6 +397,8 @@ void omap_sram_idle(void)
if (!console_trylock())
goto console_still_active;
+ pwrdm_pre_transition();
+
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
@@ -467,6 +468,8 @@ void omap_sram_idle(void)
}
omap3_intc_resume_idle();
+ pwrdm_post_transition();
+
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
@@ -490,8 +493,6 @@ console_still_active:
omap3_disable_io_chain();
}
- pwrdm_post_transition();
-
clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 03/18] GPIO: OMAP: Make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 04/18] GPIO: OMAP: Fix pwrdm_post_transition call sequence Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-16 16:34 ` Kevin Hilman
2011-06-15 4:22 ` [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
` (3 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
Modify omap_gpio_prepare_for_idle() & omap_gpio_resume_after_idle() functions
to handle save context & restore context respectively in the OMAP GPIO driver
itself instead of calling these functions from pm specific files.
For this, in gpio_prepare_for_idle(), call *_get_context_loss_count() and in
gpio_resume_after_idle() call it again. If the count is different, do restore
context. The workaround_enabled flag is no more required and is removed.
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/gpio.c | 12 +++
arch/arm/mach-omap2/pm34xx.c | 14 ----
arch/arm/plat-omap/include/plat/gpio.h | 5 +-
drivers/gpio/gpio-omap.c | 129 ++++++++++++++------------------
4 files changed, 71 insertions(+), 89 deletions(-)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 95195a8..2e65377 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -23,6 +23,7 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
#include "powerdomain.h"
@@ -34,6 +35,16 @@ static struct omap_device_pm_latency omap_gpio_latency[] = {
},
};
+#ifdef CONFIG_PM
+static int omap_gpio_get_context_loss(struct device *dev)
+{
+ return omap_pm_get_dev_context_loss_count(dev);
+}
+
+#else
+#define omap_gpio_get_context_loss NULL
+#endif
+
static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
{
struct omap_device *od;
@@ -63,6 +74,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->bank_width = dev_attr->bank_width;
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;
pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
if (!pdata) {
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 51d5a5c..0aaa32c 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -91,16 +91,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
static struct powerdomain *core_pwrdm, *per_pwrdm;
static struct powerdomain *cam_pwrdm;
-static inline void omap3_per_save_context(void)
-{
- omap_gpio_save_context();
-}
-
-static inline void omap3_per_restore_context(void)
-{
- omap_gpio_restore_context();
-}
-
static void omap3_enable_io_chain(void)
{
int timeout = 0;
@@ -405,8 +395,6 @@ void omap_sram_idle(void)
omap_uart_prepare_idle(2);
omap_uart_prepare_idle(3);
omap2_gpio_prepare_for_idle(per_going_off);
- if (per_next_state == PWRDM_POWER_OFF)
- omap3_per_save_context();
}
/* CORE */
@@ -474,8 +462,6 @@ void omap_sram_idle(void)
if (per_next_state < PWRDM_POWER_ON) {
per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
omap2_gpio_resume_after_idle();
- if (per_prev_state == PWRDM_POWER_OFF)
- omap3_per_restore_context();
omap_uart_resume_idle(2);
omap_uart_resume_idle(3);
}
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 58d0bf2..f7798b5 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -201,14 +201,15 @@ struct omap_gpio_platform_data {
bool loses_context; /* whether the bank would ever lose context */
struct omap_gpio_reg_offs *regs;
+
+ /* Return context loss count due to PM states changing */
+ int (*get_context_loss_count)(struct device *dev);
};
extern void omap2_gpio_prepare_for_idle(int off_mode);
extern void omap2_gpio_resume_after_idle(void);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
-extern void omap_gpio_save_context(void);
-extern void omap_gpio_restore_context(void);
/*-------------------------------------------------------------------------*/
/* Wrappers for "new style" GPIO calls, using the new infrastructure
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index d461558..e7b3391 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -72,9 +72,11 @@ struct gpio_bank {
bool loses_context;
int stride;
u32 width;
+ u32 ctx_loss_count;
u16 id;
void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
+ int (*get_context_loss_count)(struct device *dev);
struct omap_gpio_reg_offs *regs;
};
@@ -1312,11 +1314,11 @@ static struct syscore_ops omap_gpio_syscore_ops = {
#ifdef CONFIG_ARCH_OMAP2PLUS
-static int workaround_enabled;
+static void omap_gpio_save_context(struct gpio_bank *bank);
+static void omap_gpio_restore_context(struct gpio_bank *bank);
void omap2_gpio_prepare_for_idle(int off_mode)
{
- int c = 0;
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
@@ -1336,7 +1338,7 @@ void omap2_gpio_prepare_for_idle(int off_mode)
* non-wakeup GPIOs. Otherwise spurious IRQs will be
* generated. See OMAP2420 Errata item 1.101. */
if (!(bank->enabled_non_wakeup_gpios))
- continue;
+ goto save_gpio_ctx;
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
bank->saved_datain = __raw_readl(bank->base +
@@ -1373,13 +1375,13 @@ void omap2_gpio_prepare_for_idle(int off_mode)
__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
}
- c++;
- }
- if (!c) {
- workaround_enabled = 0;
- return;
+save_gpio_ctx:
+ if (bank->get_context_loss_count)
+ bank->ctx_loss_count =
+ bank->get_context_loss_count(bank->dev);
+
+ omap_gpio_save_context(bank);
}
- workaround_enabled = 1;
}
void omap2_gpio_resume_after_idle(void)
@@ -1387,6 +1389,7 @@ void omap2_gpio_resume_after_idle(void)
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
+ u32 ctx_lost_cnt_after;
u32 l = 0, gen, gen0, gen1;
int j;
@@ -1396,8 +1399,12 @@ void omap2_gpio_resume_after_idle(void)
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_enable(bank->dbck);
- if (!workaround_enabled)
- continue;
+ if (bank->get_context_loss_count) {
+ ctx_lost_cnt_after =
+ bank->get_context_loss_count(bank->dev);
+ if (ctx_lost_cnt_after != bank->ctx_loss_count)
+ omap_gpio_restore_context(bank);
+ }
if (!(bank->enabled_non_wakeup_gpios))
continue;
@@ -1475,74 +1482,50 @@ void omap2_gpio_resume_after_idle(void)
}
}
}
-
}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-void omap_gpio_save_context(void)
+void omap_gpio_save_context(struct gpio_bank *bank)
{
- struct gpio_bank *bank;
-
- list_for_each_entry(bank, &omap_gpio_list, node) {
-
- if (!bank->loses_context)
- continue;
-
- bank->context.irqenable1 =
- __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
- bank->context.irqenable2 =
- __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
- bank->context.wake_en =
- __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
- bank->context.ctrl =
- __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
- bank->context.oe =
- __raw_readl(bank->base + OMAP24XX_GPIO_OE);
- bank->context.leveldetect0 =
- __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
- bank->context.leveldetect1 =
- __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
- bank->context.risingdetect =
- __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
- bank->context.fallingdetect =
- __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
- bank->context.dataout =
- __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
- }
+ bank->context.irqenable1 =
+ __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
+ bank->context.irqenable2 =
+ __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
+ bank->context.wake_en =
+ __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
+ bank->context.ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+ bank->context.oe = __raw_readl(bank->base + OMAP24XX_GPIO_OE);
+ bank->context.leveldetect0 =
+ __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+ bank->context.leveldetect1 =
+ __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+ bank->context.risingdetect =
+ __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+ bank->context.fallingdetect =
+ __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+ bank->context.dataout =
+ __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
}
-void omap_gpio_restore_context(void)
+void omap_gpio_restore_context(struct gpio_bank *bank)
{
- struct gpio_bank *bank;
-
- list_for_each_entry(bank, &omap_gpio_list, node) {
-
- if (!bank->loses_context)
- continue;
-
- __raw_writel(bank->context.irqenable1,
- bank->base + OMAP24XX_GPIO_IRQENABLE1);
- __raw_writel(bank->context.irqenable2,
- bank->base + OMAP24XX_GPIO_IRQENABLE2);
- __raw_writel(bank->context.wake_en,
- bank->base + OMAP24XX_GPIO_WAKE_EN);
- __raw_writel(bank->context.ctrl,
- bank->base + OMAP24XX_GPIO_CTRL);
- __raw_writel(bank->context.oe,
- bank->base + OMAP24XX_GPIO_OE);
- __raw_writel(bank->context.leveldetect0,
- bank->base + OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(bank->context.leveldetect1,
- bank->base + OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(bank->context.risingdetect,
- bank->base + OMAP24XX_GPIO_RISINGDETECT);
- __raw_writel(bank->context.fallingdetect,
- bank->base + OMAP24XX_GPIO_FALLINGDETECT);
- __raw_writel(bank->context.dataout,
- bank->base + OMAP24XX_GPIO_DATAOUT);
- }
+ __raw_writel(bank->context.irqenable1,
+ bank->base + OMAP24XX_GPIO_IRQENABLE1);
+ __raw_writel(bank->context.irqenable2,
+ bank->base + OMAP24XX_GPIO_IRQENABLE2);
+ __raw_writel(bank->context.wake_en,
+ bank->base + OMAP24XX_GPIO_WAKE_EN);
+ __raw_writel(bank->context.ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+ __raw_writel(bank->context.oe, bank->base + OMAP24XX_GPIO_OE);
+ __raw_writel(bank->context.leveldetect0,
+ bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+ __raw_writel(bank->context.leveldetect1,
+ bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+ __raw_writel(bank->context.risingdetect,
+ bank->base + OMAP24XX_GPIO_RISINGDETECT);
+ __raw_writel(bank->context.fallingdetect,
+ bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+ __raw_writel(bank->context.dataout,
+ bank->base + OMAP24XX_GPIO_DATAOUT);
}
#endif
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
` (2 preceding siblings ...)
2011-06-15 4:22 ` [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-16 16:35 ` Kevin Hilman
2011-06-15 4:22 ` [PATCH 07/18] GPIO: OMAP: Avoid cpu checks during module ena/disable Tarun Kanti DebBarma
` (2 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
Non-wakeup GPIOs are available only in OMAP2. Avoid cpu_is checks by making
non_wakeup_gpios as part of pdata.
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/gpio.c | 8 ++++++++
arch/arm/plat-omap/include/plat/gpio.h | 1 +
drivers/gpio/gpio-omap.c | 8 +-------
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 2e65377..4952a9d 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -84,6 +84,14 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
switch (oh->class->rev) {
case 0:
+ if (id == 1)
+ /* non-wakeup GPIO pins for OMAP2 Bank1 */
+ pdata->non_wakeup_gpios = 0xe203ffc0;
+ else if (id == 2)
+ /* non-wakeup GPIO pins for OMAP2 Bank2 */
+ pdata->non_wakeup_gpios = 0x08700040;
+ /* fall through */
+
case 1:
pdata->bank_type = METHOD_GPIO_24XX;
pdata->regs->revision = OMAP24XX_GPIO_REVISION;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index f7798b5..ce417cd 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -199,6 +199,7 @@ struct omap_gpio_platform_data {
int bank_stride; /* Only needed for omap1 MPUIO */
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;
struct omap_gpio_reg_offs *regs;
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index e7b3391..5b55627 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1015,13 +1015,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
/* Initialize interface clk ungated, module enabled */
__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
- } else if (cpu_is_omap24xx()) {
- static const u32 non_wakeup_gpios[] = {
- 0xe203ffc0, 0x08700040
- };
- if (bank->id < ARRAY_SIZE(non_wakeup_gpios))
- bank->non_wakeup_gpios =
- non_wakeup_gpios[bank->id];
}
} else if (cpu_class_is_omap1()) {
if (bank_is_mpuio(bank)) {
@@ -1169,6 +1162,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->non_wakeup_gpios = pdata->non_wakeup_gpios;
bank->loses_context = pdata->loses_context;
bank->regs = pdata->regs;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 07/18] GPIO: OMAP: Avoid cpu checks during module ena/disable
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
` (3 preceding siblings ...)
2011-06-15 4:22 ` [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets Tarun Kanti DebBarma
6 siblings, 0 replies; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
From: Charulatha V <charu@ti.com>
Remove cpu-is checks while enabling/disabling OMAP GPIO module during a gpio
request/free.
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/gpio.c | 2 +
arch/arm/plat-omap/include/plat/gpio.h | 1 +
drivers/gpio/gpio-omap.c | 53 ++++++++++++++------------------
3 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 4952a9d..cdbc728 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -107,6 +107,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
+ pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
break;
case 2:
pdata->bank_type = METHOD_GPIO_44XX;
@@ -123,6 +124,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
+ pdata->regs->ctrl = OMAP4_GPIO_CTRL;
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 ce417cd..cf41743 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -188,6 +188,7 @@ struct omap_gpio_reg_offs {
u16 clr_irqenable;
u16 debounce;
u16 debounce_en;
+ u16 ctrl;
bool irqenable_inv;
};
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 5b55627..5555c5a 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -83,6 +83,7 @@ struct gpio_bank {
#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
+#define GPIO_MOD_CTRL_BIT BIT(0)
static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
{
@@ -580,22 +581,18 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
__raw_writel(__raw_readl(reg) | (1 << offset), reg);
}
#endif
- if (!cpu_class_is_omap1()) {
- if (!bank->mod_usage) {
- void __iomem *reg = bank->base;
- u32 ctrl;
-
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- reg += OMAP24XX_GPIO_CTRL;
- else if (cpu_is_omap44xx())
- reg += OMAP4_GPIO_CTRL;
- ctrl = __raw_readl(reg);
- /* Module is enabled, clocks are not gated */
- ctrl &= 0xFFFFFFFE;
- __raw_writel(ctrl, reg);
- }
- bank->mod_usage |= 1 << offset;
+ if (bank->regs->ctrl && !bank->mod_usage) {
+ void __iomem *reg = bank->base + bank->regs->ctrl;
+ u32 ctrl;
+
+ ctrl = __raw_readl(reg);
+ /* Module is enabled, clocks are not gated */
+ ctrl &= ~GPIO_MOD_CTRL_BIT;
+ __raw_writel(ctrl, reg);
}
+
+ bank->mod_usage |= 1 << offset;
+
spin_unlock_irqrestore(&bank->lock, flags);
return 0;
@@ -628,22 +625,18 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
__raw_writel(1 << offset, reg);
}
#endif
- if (!cpu_class_is_omap1()) {
- bank->mod_usage &= ~(1 << offset);
- if (!bank->mod_usage) {
- void __iomem *reg = bank->base;
- u32 ctrl;
-
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- reg += OMAP24XX_GPIO_CTRL;
- else if (cpu_is_omap44xx())
- reg += OMAP4_GPIO_CTRL;
- ctrl = __raw_readl(reg);
- /* Module is disabled, clocks are gated */
- ctrl |= 1;
- __raw_writel(ctrl, reg);
- }
+ bank->mod_usage &= ~(1 << offset);
+
+ if (bank->regs->ctrl && !bank->mod_usage) {
+ void __iomem *reg = bank->base + bank->regs->ctrl;
+ u32 ctrl;
+
+ ctrl = __raw_readl(reg);
+ /* Module is disabled, clocks are gated */
+ ctrl |= GPIO_MOD_CTRL_BIT;
+ __raw_writel(ctrl, reg);
}
+
_reset_gpio(bank, bank->chip.base + offset);
spin_unlock_irqrestore(&bank->lock, flags);
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
` (4 preceding siblings ...)
2011-06-15 4:22 ` [PATCH 07/18] GPIO: OMAP: Avoid cpu checks during module ena/disable Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-16 16:54 ` Kevin Hilman
2011-06-16 17:38 ` Kevin Hilman
2011-06-15 4:22 ` [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets Tarun Kanti DebBarma
6 siblings, 2 replies; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
Wakeup register offsets are initialized according to OMAP versions
during device registration. These explicit checks are no longer needed.
mpuio_init() function is defined under #ifdefs. It is required only in case
of MPUIO bank type and only when PM operations are supported by it.
This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type.
For all the other cases it is a dummy function. Hence clean up the same
and remove all the OMAP SoC specific #ifdefs.
bank_is_mpuio() is defined as a check to identify if the bank type is MPUIO.
It is not required to define it separately as zero for OMAP2plus. Remove this.
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap1/gpio16xx.c | 8 ++
arch/arm/mach-omap2/gpio.c | 7 ++
arch/arm/plat-omap/include/plat/gpio.h | 4 +
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 9a97e60..d1da7c8 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..8ab72ed 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; /* Bank supports suspend/resume operations or not */
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 5555c5a..0c00ccf 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;
@@ -604,27 +603,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) {
@@ -788,15 +771,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);
@@ -858,17 +834,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
@@ -1010,7 +975,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);
@@ -1060,8 +1025,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;
@@ -1089,9 +1054,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";
@@ -1155,6 +1119,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;
@@ -1200,45 +1165,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);
@@ -1254,36 +1196,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);
@@ -1297,8 +1219,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);
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
` (5 preceding siblings ...)
2011-06-15 4:22 ` [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag Tarun Kanti DebBarma
@ 2011-06-15 4:22 ` Tarun Kanti DebBarma
2011-06-16 17:00 ` Kevin Hilman
6 siblings, 1 reply; 21+ messages in thread
From: Tarun Kanti DebBarma @ 2011-06-15 4:22 UTC (permalink / raw)
To: linux-omap; +Cc: khilman, santosh.shilimkar, tony
By adding level and edge detection register offsets and then initializing them
correctly according to OMAP versions during device registrations we can now remove
lot of revision checks in these functions.
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
---
arch/arm/mach-omap2/gpio.c | 8 ++
arch/arm/plat-omap/include/plat/gpio.h | 4 +
drivers/gpio/gpio-omap.c | 118 ++++++++++----------------------
3 files changed, 48 insertions(+), 82 deletions(-)
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index ea1556b..ea871ce 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -112,6 +112,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->regs->wkup_status = OMAP24XX_GPIO_WAKE_EN;
pdata->regs->wkup_clear = OMAP24XX_GPIO_CLEARWKUENA;
pdata->regs->wkup_set = OMAP24XX_GPIO_SETWKUENA;
+ pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
+ pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
+ pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
+ pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
break;
case 2:
pdata->bank_type = METHOD_GPIO_44XX;
@@ -132,6 +136,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->regs->wkup_status = OMAP4_GPIO_IRQWAKEN0;
pdata->regs->wkup_clear = OMAP4_GPIO_IRQWAKEN0;
pdata->regs->wkup_set = OMAP4_GPIO_IRQWAKEN0;
+ pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
+ pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
+ pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
+ pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
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 8ab72ed..3ae4601 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -192,6 +192,10 @@ struct omap_gpio_reg_offs {
u16 wkup_status;
u16 wkup_clear;
u16 wkup_set;
+ u16 leveldetect0;
+ u16 leveldetect1;
+ u16 risingdetect;
+ u16 fallingdetect;
bool irqenable_inv;
};
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 0c00ccf..29d1f3c 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -261,15 +261,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
bank->enabled_non_wakeup_gpios &= ~gpio_bit;
}
- if (cpu_is_omap44xx()) {
- bank->level_mask =
- __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
- __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
- } else {
- bank->level_mask =
- __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
- __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
- }
+ bank->level_mask =
+ __raw_readl(bank->base + bank->regs->leveldetect0) |
+ __raw_readl(bank->base + bank->regs->leveldetect1);
}
#endif
@@ -409,12 +403,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
if (type & ~IRQ_TYPE_SENSE_MASK)
return -EINVAL;
- /* OMAP1 allows only only edge triggering */
- if (!cpu_class_is_omap2()
- && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
+ bank = irq_data_get_irq_chip_data(d);
+
+ if (bank->regs->leveldetect0 && (type &
+ (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
- bank = irq_data_get_irq_chip_data(d);
spin_lock_irqsave(&bank->lock, flags);
retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
spin_unlock_irqrestore(&bank->lock, flags);
@@ -661,9 +655,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
isr &= 0x0000ffff;
- if (cpu_class_is_omap2()) {
+ if (bank->regs->leveldetect0)
level_mask = bank->level_mask & enabled;
- }
/* clear edge sensitive interrupts before handler(s) are
called so that we don't miss any interrupt occurred while
@@ -1247,40 +1240,18 @@ void omap2_gpio_prepare_for_idle(int off_mode)
if (!(bank->enabled_non_wakeup_gpios))
goto save_gpio_ctx;
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- bank->saved_datain = __raw_readl(bank->base +
- OMAP24XX_GPIO_DATAIN);
- l1 = __raw_readl(bank->base +
- OMAP24XX_GPIO_FALLINGDETECT);
- l2 = __raw_readl(bank->base +
- OMAP24XX_GPIO_RISINGDETECT);
- }
-
- if (cpu_is_omap44xx()) {
- bank->saved_datain = __raw_readl(bank->base +
- OMAP4_GPIO_DATAIN);
- l1 = __raw_readl(bank->base +
- OMAP4_GPIO_FALLINGDETECT);
- l2 = __raw_readl(bank->base +
- OMAP4_GPIO_RISINGDETECT);
- }
+ bank->saved_datain = __raw_readl(bank->base +
+ bank->regs->datain);
+ l1 = __raw_readl(bank->base + bank->regs->fallingdetect);
+ l2 = __raw_readl(bank->base + bank->regs->risingdetect);
bank->saved_fallingdetect = l1;
bank->saved_risingdetect = l2;
l1 &= ~bank->enabled_non_wakeup_gpios;
l2 &= ~bank->enabled_non_wakeup_gpios;
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- __raw_writel(l1, bank->base +
- OMAP24XX_GPIO_FALLINGDETECT);
- __raw_writel(l2, bank->base +
- OMAP24XX_GPIO_RISINGDETECT);
- }
-
- if (cpu_is_omap44xx()) {
- __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
- __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
- }
+ __raw_writel(l1, bank->base + bank->regs->fallingdetect);
+ __raw_writel(l2, bank->base + bank->regs->risingdetect);
save_gpio_ctx:
if (bank->get_context_loss_count)
@@ -1316,21 +1287,11 @@ void omap2_gpio_resume_after_idle(void)
if (!(bank->enabled_non_wakeup_gpios))
continue;
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- __raw_writel(bank->saved_fallingdetect,
- bank->base + OMAP24XX_GPIO_FALLINGDETECT);
- __raw_writel(bank->saved_risingdetect,
- bank->base + OMAP24XX_GPIO_RISINGDETECT);
- l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
- }
-
- if (cpu_is_omap44xx()) {
- __raw_writel(bank->saved_fallingdetect,
- bank->base + OMAP4_GPIO_FALLINGDETECT);
- __raw_writel(bank->saved_risingdetect,
- bank->base + OMAP4_GPIO_RISINGDETECT);
- l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
- }
+ __raw_writel(bank->saved_fallingdetect,
+ bank->base + bank->regs->fallingdetect);
+ __raw_writel(bank->saved_risingdetect,
+ bank->base + bank->regs->risingdetect);
+ l = __raw_readl(bank->base + bank->regs->datain);
/* Check if any of the non-wakeup interrupt GPIOs have changed
* state. If so, generate an IRQ by software. This is
@@ -1358,35 +1319,28 @@ void omap2_gpio_resume_after_idle(void)
if (gen) {
u32 old0, old1;
+ old0 = __raw_readl(bank->base +
+ bank->regs->leveldetect0);
+ old1 = __raw_readl(bank->base +
+ bank->regs->leveldetect1);
+
+ __raw_writel(old0, bank->base +
+ bank->regs->leveldetect0);
+ __raw_writel(old1, bank->base +
+ bank->regs->leveldetect1);
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
- old0 = __raw_readl(bank->base +
- OMAP24XX_GPIO_LEVELDETECT0);
- old1 = __raw_readl(bank->base +
- OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(old0 | gen, bank->base +
- OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(old1 | gen, bank->base +
- OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(old0, bank->base +
- OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(old1, bank->base +
- OMAP24XX_GPIO_LEVELDETECT1);
+ old0 |= gen;
+ old1 |= gen;
}
if (cpu_is_omap44xx()) {
- old0 = __raw_readl(bank->base +
- OMAP4_GPIO_LEVELDETECT0);
- old1 = __raw_readl(bank->base +
- OMAP4_GPIO_LEVELDETECT1);
- __raw_writel(old0 | l, bank->base +
- OMAP4_GPIO_LEVELDETECT0);
- __raw_writel(old1 | l, bank->base +
- OMAP4_GPIO_LEVELDETECT1);
- __raw_writel(old0, bank->base +
- OMAP4_GPIO_LEVELDETECT0);
- __raw_writel(old1, bank->base +
- OMAP4_GPIO_LEVELDETECT1);
+ old0 |= l;
+ old1 |= l;
}
+ __raw_writel(old0, bank->base +
+ bank->regs->leveldetect0);
+ __raw_writel(old1, bank->base +
+ bank->regs->leveldetect1);
}
}
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver
2011-06-15 4:22 ` [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver Tarun Kanti DebBarma
@ 2011-06-16 16:34 ` Kevin Hilman
2011-06-17 5:41 ` DebBarma, Tarun Kanti
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2011-06-16 16:34 UTC (permalink / raw)
To: Tarun Kanti DebBarma; +Cc: linux-omap, santosh.shilimkar, tony
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> From: Charulatha V <charu@ti.com>
>
> Modify omap_gpio_prepare_for_idle() & omap_gpio_resume_after_idle() functions
> to handle save context & restore context respectively in the OMAP GPIO driver
> itself instead of calling these functions from pm specific files.
> For this, in gpio_prepare_for_idle(), call *_get_context_loss_count() and in
> gpio_resume_after_idle() call it again. If the count is different, do restore
> context. The workaround_enabled flag is no more required and is removed.
>
> Signed-off-by: Charulatha V <charu@ti.com>
[...]
> @@ -1396,8 +1399,12 @@ void omap2_gpio_resume_after_idle(void)
> for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
> clk_enable(bank->dbck);
>
> - if (!workaround_enabled)
> - continue;
> + if (bank->get_context_loss_count) {
> + ctx_lost_cnt_after =
> + bank->get_context_loss_count(bank->dev);
> + if (ctx_lost_cnt_after != bank->ctx_loss_count)
> + omap_gpio_restore_context(bank);
> + }
Context should be also be restored if you cant know if it's been lost.
IOW, it should also be restored if !bank->get_context_loss_count.
> if (!(bank->enabled_non_wakeup_gpios))
> continue;
> @@ -1475,74 +1482,50 @@ void omap2_gpio_resume_after_idle(void)
> }
> }
> }
> -
> }
>
> -#endif
> -
> -#ifdef CONFIG_ARCH_OMAP3
> -void omap_gpio_save_context(void)
> +void omap_gpio_save_context(struct gpio_bank *bank)
Should also be made static. Same for restore below.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata
2011-06-15 4:22 ` [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
@ 2011-06-16 16:35 ` Kevin Hilman
0 siblings, 0 replies; 21+ messages in thread
From: Kevin Hilman @ 2011-06-16 16:35 UTC (permalink / raw)
To: Tarun Kanti DebBarma; +Cc: linux-omap, santosh.shilimkar, tony
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> From: Charulatha V <charu@ti.com>
>
> Non-wakeup GPIOs are available only in OMAP2. Avoid cpu_is checks by making
> non_wakeup_gpios as part of pdata.
>
> Signed-off-by: Charulatha V <charu@ti.com>
Nice! I like this approach.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-15 4:22 ` [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag Tarun Kanti DebBarma
@ 2011-06-16 16:54 ` Kevin Hilman
2011-06-17 5:34 ` DebBarma, Tarun Kanti
2011-06-30 13:35 ` DebBarma, Tarun Kanti
2011-06-16 17:38 ` Kevin Hilman
1 sibling, 2 replies; 21+ messages in thread
From: Kevin Hilman @ 2011-06-16 16:54 UTC (permalink / raw)
To: Tarun Kanti DebBarma; +Cc: linux-omap, santosh.shilimkar, tony
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> Wakeup register offsets are initialized according to OMAP versions
> during device registration. These explicit checks are no longer needed.
>
> mpuio_init() function is defined under #ifdefs. It is required only in case
> of MPUIO bank type and only when PM operations are supported by it.
> This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type.
> For all the other cases it is a dummy function. Hence clean up the same
> and remove all the OMAP SoC specific #ifdefs.
>
> bank_is_mpuio() is defined as a check to identify if the bank type is MPUIO.
> It is not required to define it separately as zero for OMAP2plus. Remove this.
Also adds a new suspend_support flag to pdata which is not described
here. This flag is wrongly named and wrongly used throughout. More on
this below...
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Charulatha V <charu@ti.com>
> ---
> arch/arm/mach-omap1/gpio16xx.c | 8 ++
> arch/arm/mach-omap2/gpio.c | 7 ++
> arch/arm/plat-omap/include/plat/gpio.h | 4 +
> 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 9a97e60..d1da7c8 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,
> };
Notice that you add a 'suspend_support = true' everywhere you add a the
wkup_* registers. This suggests to me that checking for the presence of
one of those registers would tell you the same thing.
> 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..8ab72ed 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; /* Bank supports suspend/resume operations or not */
> 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 5555c5a..0c00ccf 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;
> @@ -604,27 +603,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) {
> @@ -788,15 +771,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);
> @@ -858,17 +834,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
> @@ -1010,7 +975,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) {
What does ->suspend_support have to do with MPUIO init?
> __raw_writew(0xffff, bank->base +
> OMAP_MPUIO_GPIO_MASKIT / bank->stride);
> mpuio_init(bank);
> @@ -1060,8 +1025,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;
> @@ -1089,9 +1054,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;
ditto
> bank->chip.base = OMAP_MPUIO(0);
> } else {
> bank->chip.label = "gpio";
> @@ -1155,6 +1119,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;
> @@ -1200,45 +1165,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;
Rather than check the flag here in every suspend, don't add a suspend
method in dev_pm_ops for banks that don't have the wkup_* registers.
> + 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);
> @@ -1254,36 +1196,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;
Same here. Rather than check this flag every time, just don't add a
.resume method to dev_pm_ops for banks that don't have wkup_* registers.
> + 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);
> @@ -1297,8 +1219,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);
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets
2011-06-15 4:22 ` [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets Tarun Kanti DebBarma
@ 2011-06-16 17:00 ` Kevin Hilman
2011-06-17 5:26 ` DebBarma, Tarun Kanti
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2011-06-16 17:00 UTC (permalink / raw)
To: Tarun Kanti DebBarma; +Cc: linux-omap, santosh.shilimkar, tony
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> By adding level and edge detection register offsets and then initializing them
> correctly according to OMAP versions during device registrations we can now remove
> lot of revision checks in these functions.
>
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Charulatha V <charu@ti.com>
Looks mostly good, but...
[...]
> @@ -661,9 +655,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
> if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
> isr &= 0x0000ffff;
>
> - if (cpu_class_is_omap2()) {
> + if (bank->regs->leveldetect0)
Rather than checking for the presence of the register, this should just
be 'if (bank->level_mask)'. bank->level_mask will should already be
zero on platforms without the register.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-15 4:22 ` [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag Tarun Kanti DebBarma
2011-06-16 16:54 ` Kevin Hilman
@ 2011-06-16 17:38 ` Kevin Hilman
2011-06-17 5:24 ` DebBarma, Tarun Kanti
1 sibling, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2011-06-16 17:38 UTC (permalink / raw)
To: Tarun Kanti DebBarma; +Cc: linux-omap, santosh.shilimkar, tony
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> Wakeup register offsets are initialized according to OMAP versions
> during device registration. These explicit checks are no longer needed.
>
> mpuio_init() function is defined under #ifdefs. It is required only in case
> of MPUIO bank type and only when PM operations are supported by it.
> This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type.
> For all the other cases it is a dummy function. Hence clean up the same
> and remove all the OMAP SoC specific #ifdefs.
>
> bank_is_mpuio() is defined as a check to identify if the bank type is MPUIO.
> It is not required to define it separately as zero for OMAP2plus. Remove this.
>
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Charulatha V <charu@ti.com>
[...]
> 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;
This is wrong for OMAP4.
The wkup_clear & wkup_set registers offsets are for the registers
*dedicated* to set and clear. Any usage of these offets assumes that
a single write will either set or clear the register, which is clearly
not the case with IRQWAKEN, which requires a read/modify/write.
For example, in suspend this is done:
__raw_writel(0xffffffff, wake_clear);
__raw_writel(bank->suspend_wakeup, wake_set);
As both the set & clear are set to IRQWAKEN on OMAP4, this means that
wakeups are actually enabled for *all* GPIOs in every bank during
suspend. This is clearly not what's intended. Also, since resume does
something similar, wakeups for *all* GPIOs are left enabled after resume
as well.
Also, the 44xx TRMs recommend not using the set/clear registers at all
for OMAP4, so they should be left blank.
Instead, any usage of the wake set/clear registers in the code should
probably be converted to just use read/modify/writes on wake_status so
it's the same for all SoCs.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-16 17:38 ` Kevin Hilman
@ 2011-06-17 5:24 ` DebBarma, Tarun Kanti
0 siblings, 0 replies; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-17 5:24 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
> -----Original Message-----
> From: Hilman, Kevin
> Sent: Thursday, June 16, 2011 11:09 PM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Shilimkar, Santosh; tony@atomide.com
> Subject: Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend
> support flag
>
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
>
> > Wakeup register offsets are initialized according to OMAP versions
> > during device registration. These explicit checks are no longer needed.
> >
> > mpuio_init() function is defined under #ifdefs. It is required only in
> case
> > of MPUIO bank type and only when PM operations are supported by it.
> > This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type.
> > For all the other cases it is a dummy function. Hence clean up the same
> > and remove all the OMAP SoC specific #ifdefs.
> >
> > bank_is_mpuio() is defined as a check to identify if the bank type is
> MPUIO.
> > It is not required to define it separately as zero for OMAP2plus. Remove
> this.
> >
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Charulatha V <charu@ti.com>
>
> [...]
>
> > 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;
>
> This is wrong for OMAP4.
>
> The wkup_clear & wkup_set registers offsets are for the registers
> *dedicated* to set and clear. Any usage of these offets assumes that
> a single write will either set or clear the register, which is clearly
> not the case with IRQWAKEN, which requires a read/modify/write.
>
> For example, in suspend this is done:
>
> __raw_writel(0xffffffff, wake_clear);
> __raw_writel(bank->suspend_wakeup, wake_set);
>
> As both the set & clear are set to IRQWAKEN on OMAP4, this means that
> wakeups are actually enabled for *all* GPIOs in every bank during
> suspend. This is clearly not what's intended. Also, since resume does
> something similar, wakeups for *all* GPIOs are left enabled after resume
> as well.
Agreed! Thanks.
>
> Also, the 44xx TRMs recommend not using the set/clear registers at all
> for OMAP4, so they should be left blank.
Yes, I will not assign those offsets.
>
> Instead, any usage of the wake set/clear registers in the code should
> probably be converted to just use read/modify/writes on wake_status so
> it's the same for all SoCs.
OK.
--
Tarun
>
> Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets
2011-06-16 17:00 ` Kevin Hilman
@ 2011-06-17 5:26 ` DebBarma, Tarun Kanti
0 siblings, 0 replies; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-17 5:26 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
> -----Original Message-----
> From: Hilman, Kevin
> Sent: Thursday, June 16, 2011 10:31 PM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Shilimkar, Santosh; tony@atomide.com
> Subject: Re: [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg
> offsets
>
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
>
> > By adding level and edge detection register offsets and then
> initializing them
> > correctly according to OMAP versions during device registrations we can
> now remove
> > lot of revision checks in these functions.
> >
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Charulatha V <charu@ti.com>
>
> Looks mostly good, but...
>
> [...]
>
> > @@ -661,9 +655,8 @@ static void gpio_irq_handler(unsigned int irq,
> struct irq_desc *desc)
> > if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
> > isr &= 0x0000ffff;
> >
> > - if (cpu_class_is_omap2()) {
> > + if (bank->regs->leveldetect0)
>
> Rather than checking for the presence of the register, this should just
> be 'if (bank->level_mask)'. bank->level_mask will should already be
> zero on platforms without the register.
Ok. I will make the change.
--
Tarun
>
> Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-16 16:54 ` Kevin Hilman
@ 2011-06-17 5:34 ` DebBarma, Tarun Kanti
2011-06-17 15:52 ` Kevin Hilman
2011-06-30 13:35 ` DebBarma, Tarun Kanti
1 sibling, 1 reply; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-17 5:34 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
> -----Original Message-----
> From: Hilman, Kevin
> Sent: Thursday, June 16, 2011 10:24 PM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Shilimkar, Santosh; tony@atomide.com
> Subject: Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend
> support flag
>
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
>
> > Wakeup register offsets are initialized according to OMAP versions
> > during device registration. These explicit checks are no longer needed.
> >
> > mpuio_init() function is defined under #ifdefs. It is required only in
> case
> > of MPUIO bank type and only when PM operations are supported by it.
> > This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type.
> > For all the other cases it is a dummy function. Hence clean up the same
> > and remove all the OMAP SoC specific #ifdefs.
> >
> > bank_is_mpuio() is defined as a check to identify if the bank type is
> MPUIO.
> > It is not required to define it separately as zero for OMAP2plus. Remove
> this.
>
> Also adds a new suspend_support flag to pdata which is not described
> here. This flag is wrongly named and wrongly used throughout. More on
> this below...
Ok...
>
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Charulatha V <charu@ti.com>
> > ---
> > arch/arm/mach-omap1/gpio16xx.c | 8 ++
> > arch/arm/mach-omap2/gpio.c | 7 ++
> > arch/arm/plat-omap/include/plat/gpio.h | 4 +
> > 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 9a97e60..d1da7c8 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,
> > };
>
> Notice that you add a 'suspend_support = true' everywhere you add a the
> wkup_* registers. This suggests to me that checking for the presence of
> one of those registers would tell you the same thing.
Agreed!
>
> > 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..8ab72ed 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; /* Bank supports suspend/resume operations
> or not */
> > 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 5555c5a..0c00ccf 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;
> > @@ -604,27 +603,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) {
> > @@ -788,15 +771,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);
> > @@ -858,17 +834,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
> > @@ -1010,7 +975,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) {
>
> What does ->suspend_support have to do with MPUIO init?
I will verify and remove.
>
> > __raw_writew(0xffff, bank->base +
> > OMAP_MPUIO_GPIO_MASKIT / bank->stride);
> > mpuio_init(bank);
> > @@ -1060,8 +1025,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;
> > @@ -1089,9 +1054,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;
>
> ditto
Yes, I will verify and remove.
>
> > bank->chip.base = OMAP_MPUIO(0);
> > } else {
> > bank->chip.label = "gpio";
> > @@ -1155,6 +1119,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;
> > @@ -1200,45 +1165,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;
>
> Rather than check the flag here in every suspend, don't add a suspend
> method in dev_pm_ops for banks that don't have the wkup_* registers.
Sounds better approach!
>
> > + 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);
> > @@ -1254,36 +1196,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;
>
> Same here. Rather than check this flag every time, just don't add a
> .resume method to dev_pm_ops for banks that don't have wkup_* registers.
Yes, I will do that.
>
> > + 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);
> > @@ -1297,8 +1219,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);
>
> Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver
2011-06-16 16:34 ` Kevin Hilman
@ 2011-06-17 5:41 ` DebBarma, Tarun Kanti
0 siblings, 0 replies; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-17 5:41 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
> -----Original Message-----
> From: Hilman, Kevin
> Sent: Thursday, June 16, 2011 10:05 PM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Shilimkar, Santosh; tony@atomide.com
> Subject: Re: [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO
> driver
>
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
>
> > From: Charulatha V <charu@ti.com>
> >
> > Modify omap_gpio_prepare_for_idle() & omap_gpio_resume_after_idle()
> functions
> > to handle save context & restore context respectively in the OMAP GPIO
> driver
> > itself instead of calling these functions from pm specific files.
> > For this, in gpio_prepare_for_idle(), call *_get_context_loss_count()
> and in
> > gpio_resume_after_idle() call it again. If the count is different, do
> restore
> > context. The workaround_enabled flag is no more required and is removed.
> >
> > Signed-off-by: Charulatha V <charu@ti.com>
>
> [...]
>
> > @@ -1396,8 +1399,12 @@ void omap2_gpio_resume_after_idle(void)
> > for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
> > clk_enable(bank->dbck);
> >
> > - if (!workaround_enabled)
> > - continue;
> > + if (bank->get_context_loss_count) {
> > + ctx_lost_cnt_after =
> > + bank->get_context_loss_count(bank->dev);
> > + if (ctx_lost_cnt_after != bank->ctx_loss_count)
> > + omap_gpio_restore_context(bank);
> > + }
>
> Context should be also be restored if you cant know if it's been lost.
> IOW, it should also be restored if !bank->get_context_loss_count.
Ok, I will incorporate this condition as well.
>
> > if (!(bank->enabled_non_wakeup_gpios))
> > continue;
> > @@ -1475,74 +1482,50 @@ void omap2_gpio_resume_after_idle(void)
> > }
> > }
> > }
> > -
> > }
> >
> > -#endif
> > -
> > -#ifdef CONFIG_ARCH_OMAP3
> > -void omap_gpio_save_context(void)
> > +void omap_gpio_save_context(struct gpio_bank *bank)
>
> Should also be made static. Same for restore below.
Sure. Thanks.
BTW, there is another bug in this patch which I noticed later.
In *_probe, the following assignment got missed:
bank->get_context_loss_count = pdata->get_context_loss_count;
--
Tarun
>
> Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-17 5:34 ` DebBarma, Tarun Kanti
@ 2011-06-17 15:52 ` Kevin Hilman
2011-06-17 15:53 ` DebBarma, Tarun Kanti
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2011-06-17 15:52 UTC (permalink / raw)
To: DebBarma, Tarun Kanti
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
"DebBarma, Tarun Kanti" <tarun.kanti@ti.com> writes:
[...]
>> > diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-
>> omap1/gpio16xx.c
>> > index 9a97e60..d1da7c8 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,
>> > };
>>
>> Notice that you add a 'suspend_support = true' everywhere you add a the
>> wkup_* registers. This suggests to me that checking for the presence of
>> one of those registers would tell you the same thing.
>
> Agreed!
>
Specifically, I recommend checking for wake_status, since wake_set and
wake_clear are legacy registers and may not be recommended (or present)
on OMAP4+.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-17 15:52 ` Kevin Hilman
@ 2011-06-17 15:53 ` DebBarma, Tarun Kanti
0 siblings, 0 replies; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-17 15:53 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
> -----Original Message-----
> From: Hilman, Kevin
> Sent: Friday, June 17, 2011 9:22 PM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Shilimkar, Santosh; tony@atomide.com
> Subject: Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend
> support flag
>
> "DebBarma, Tarun Kanti" <tarun.kanti@ti.com> writes:
>
> [...]
>
> >> > diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-
> >> omap1/gpio16xx.c
> >> > index 9a97e60..d1da7c8 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,
> >> > };
> >>
> >> Notice that you add a 'suspend_support = true' everywhere you add a the
> >> wkup_* registers. This suggests to me that checking for the presence
> of
> >> one of those registers would tell you the same thing.
> >
> > Agreed!
> >
>
> Specifically, I recommend checking for wake_status, since wake_set and
> wake_clear are legacy registers and may not be recommended (or present)
> on OMAP4+.
OK.
>
> Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-16 16:54 ` Kevin Hilman
2011-06-17 5:34 ` DebBarma, Tarun Kanti
@ 2011-06-30 13:35 ` DebBarma, Tarun Kanti
2011-06-30 22:57 ` Kevin Hilman
1 sibling, 1 reply; 21+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-06-30 13:35 UTC (permalink / raw)
To: Hilman, Kevin
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
Kevin,
[...]
> > -#endif
> > - default:
> > - continue;
> > - }
> > + if (!bank->suspend_support)
> > + return 0;
>
> Rather than check the flag here in every suspend, don't add a suspend
> method in dev_pm_ops for banks that don't have the wkup_* registers.
While trying to implement this comment I am facing issues:
struct device_driver {
...
const struct dev_pm_ops *pm;
...
};
Since *pm is constant we can not assign pm->suspend/resume dynamically.
Also, I am not sure if it is permissible to have following code in probe:
... omap_gpio_probe(...)
{
...
if (bank->regs->wkup_status) {
pdrv->driver.pm->suspend = omap_gpio_suspend;
pdrv->driver.pm->resume = omap_gpio_resume;
}
...
[...]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag
2011-06-30 13:35 ` DebBarma, Tarun Kanti
@ 2011-06-30 22:57 ` Kevin Hilman
0 siblings, 0 replies; 21+ messages in thread
From: Kevin Hilman @ 2011-06-30 22:57 UTC (permalink / raw)
To: DebBarma, Tarun Kanti
Cc: linux-omap@vger.kernel.org, Shilimkar, Santosh, tony@atomide.com
"DebBarma, Tarun Kanti" <tarun.kanti@ti.com> writes:
> Kevin,
> [...]
>> > -#endif
>> > - default:
>> > - continue;
>> > - }
>> > + if (!bank->suspend_support)
>> > + return 0;
>>
>> Rather than check the flag here in every suspend, don't add a suspend
>> method in dev_pm_ops for banks that don't have the wkup_* registers.
> While trying to implement this comment I am facing issues:
>
> struct device_driver {
> ...
> const struct dev_pm_ops *pm;
>
> ...
> };
>
> Since *pm is constant we can not assign pm->suspend/resume dynamically.
Oh, right.
> Also, I am not sure if it is permissible to have following code in probe:
>
> ... omap_gpio_probe(...)
> {
> ...
> if (bank->regs->wkup_status) {
> pdrv->driver.pm->suspend = omap_gpio_suspend;
> pdrv->driver.pm->resume = omap_gpio_resume;
> }
> ...
>
OK, then I guess having a check for regs->wkup_status in the beginning
of the suspend/resume functions will be fine.
Thanks,
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2011-06-30 22:57 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-15 4:22 [PATCH v2 02/18] GPIO: OMAP2+: Use flag to identify wakeup domain Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 03/18] GPIO: OMAP: Make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 04/18] GPIO: OMAP: Fix pwrdm_post_transition call sequence Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 05/18] GPIO: OMAP: Handle save/restore ctx in GPIO driver Tarun Kanti DebBarma
2011-06-16 16:34 ` Kevin Hilman
2011-06-17 5:41 ` DebBarma, Tarun Kanti
2011-06-15 4:22 ` [PATCH v2 06/18] GPIO: OMAP2+: Make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
2011-06-16 16:35 ` Kevin Hilman
2011-06-15 4:22 ` [PATCH 07/18] GPIO: OMAP: Avoid cpu checks during module ena/disable Tarun Kanti DebBarma
2011-06-15 4:22 ` [PATCH v2 08/18] GPIO: OMAP: Use wkup regs off/suspend support flag Tarun Kanti DebBarma
2011-06-16 16:54 ` Kevin Hilman
2011-06-17 5:34 ` DebBarma, Tarun Kanti
2011-06-17 15:52 ` Kevin Hilman
2011-06-17 15:53 ` DebBarma, Tarun Kanti
2011-06-30 13:35 ` DebBarma, Tarun Kanti
2011-06-30 22:57 ` Kevin Hilman
2011-06-16 17:38 ` Kevin Hilman
2011-06-17 5:24 ` DebBarma, Tarun Kanti
2011-06-15 4:22 ` [PATCH v2 09/18] GPIO: OMAP: Use level/edge detect reg offsets Tarun Kanti DebBarma
2011-06-16 17:00 ` Kevin Hilman
2011-06-17 5:26 ` DebBarma, Tarun Kanti
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox