linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver
@ 2011-04-22 11:08 Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 01/18] OMAP1: GPIO: Fix mpuio_init() call Charulatha V
                   ` (19 more replies)
  0 siblings, 20 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Modifies the OMAP GPIO driver to avoid usage of cpu_is* checks
for different OMAP architectures. This is done by moving some
architecture specific code to mach-omap* and call them from
plat-omap* using function pointers. Also remove the register offset
macros from OMAP GPIO driver and handle the same in mach-omap*.

Avoid usage of gpio_bank_count and gpio_bank pointer array by
means of maintaining a list. Removes the bank->method flag from
the GPIO driver.

All OMAP1 SoCs has one MPUIO type GPIO bank. OMAP2+ does not have
any MPUIO type GPIO bank. Since MPUIO type GPIO bank is the same for
all OMAP1 CPUs, they are handled in plat-omap/ itself as
there is no common gpio.c file for all cpu types in mach-omap1.
They are identified by using bank->stride flag as it is '0'
for other than MPUIO type banks.

Patch series is based on mainline rc4 following commit:
91e8549bde9e5cc88c5a2e8c8114389279e240b5
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

Compile tested for:
 - omap1_defconfig
 - omap2plus_defconfig

Boot test (success on the following boards):
 - OMAP1710-H3
 - OMAP2420-H4
 - OMAP3430-SDP
 - OMAP3430-Zoom2
 - OMAP3630-Zoom3
 - OMAP4430-SDP
 - OMAP4430-Blaze

GPIO module functionality testing (success on the following boards):
 - OMAP2420-H4
 - OMAP3430-SDP
 - OMAP3430-Zoom2
 - OMAP3630-Zoom3
 - OMAP4430-SDP
 - OMAP4430-Blaze

PM Testing (success as given below):
OMAP3430-SDP: retention, off_mode, system_wide suspend, gpio wakeup
OMAP3630-Zoom3: retention, system_wide suspend
using the following:
	     echo 5 > /sys/devices/platform/omap/omap_uart.0/sleep_timeout
	     echo 5 > /sys/devices/platform/omap/omap_uart.1/sleep_timeout
	     echo 5 > /sys/devices/platform/omap/omap_uart.2/sleep_timeout
	     echo 5 > /sys/devices/platform/omap/omap_uart.3/sleep_timeout
	     echo '5' > /debug/pm_debug/wakeup_timer_seconds
	     echo 1 > /debug/pm_debug/sleep_while_idle
	     echo 1 > /debug/pm_debug/enable_off_mode

Charulatha V (18):
  OMAP1: GPIO: Fix mpuio_init() call
  OMAP: GPIO: remove get_gpio_bank()
  OMAP: GPIO: Move gpio_get_index() to mach-omap
  OMAP: GPIO: Move gpio_valid() to SoC specific files
  OMAP: GPIO: cleanup datain,dataout,set dir funcs
  OMAP: GPIO: cleanup set trigger func
  OMAP: GPIO: cleanup set/get IRQ, clr irqstatus funcs
  OMAP: GPIO: req/free: Remove reg offset macros usage
  OMAP: GPIO: cleanup gpio_irq_handler
  OMAP: GPIO: cleanup set wakeup/suspend/resume funcs
  OMAP: GPIO: Remove dependency on gpio_bank_count
  OMAP: GPIO: cleanup set_debounce, idle/resume_after_idle
  OMAP: GPIO: cleanup save/restore context
  OMAP: GPIO: Remove CONFIG_ARCH_OMAP16XX/OMAP2+ defines
  OMAP: GPIO: cleanup gpio_show_rev
  OMAP: GPIO: move omap_gpio_mod_init to mach-omap
  OMAP: GPIO: use dev_err* instead of printk
  OMAP: GPIO: Remove usage of bank method

 arch/arm/mach-omap1/gpio15xx.c         |  110 ++-
 arch/arm/mach-omap1/gpio16xx.c         |  174 +++-
 arch/arm/mach-omap1/gpio7xx.c          |  132 ++-
 arch/arm/mach-omap2/gpio.c             |  476 +++++++++-
 arch/arm/plat-omap/gpio.c              | 1770 ++++++++------------------------
 arch/arm/plat-omap/include/plat/gpio.h |  108 ++-
 6 files changed, 1380 insertions(+), 1390 deletions(-)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 01/18] OMAP1: GPIO: Fix mpuio_init() call
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 02/18] OMAP: GPIO: remove get_gpio_bank() Charulatha V
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

In OMAP1 GPIO, MPUIO bank's initialization is called as part of
omap_gpio_sysinit() which is an "arch_initcall". mpuio_init()
relies on the gpio_bank pointer of MPUIO bank whose memory is
allocated only during omap_gpio_probe(). Hence move mpuio_init()
call as part of probe after the gpio_bank pointer is initialized.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index d2adcdd..9164bd4 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -1697,6 +1697,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		ret = init_gpio_info(pdev);
 		if (ret)
 			return ret;
+		if (cpu_class_is_omap1())
+			mpuio_init();
 	}
 
 	id = pdev->id;
@@ -2110,8 +2112,6 @@ static int __init omap_gpio_sysinit(void)
 {
 	int ret = 0;
 
-	mpuio_init();
-
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
 		if (ret == 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 02/18] OMAP: GPIO: remove get_gpio_bank()
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 01/18] OMAP1: GPIO: Fix mpuio_init() call Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap Charulatha V
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

use chip info to get the pointer to the struct gpio_bank for a
given GPIO bank and remove get_gpio_bank().

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |   29 ++---------------------------
 1 files changed, 2 insertions(+), 27 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9164bd4..498e1df 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -189,31 +189,6 @@ static int bank_width;
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
 int gpio_bank_count;
 
-static inline struct gpio_bank *get_gpio_bank(int gpio)
-{
-	if (cpu_is_omap15xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1];
-	}
-	if (cpu_is_omap16xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 4)];
-	}
-	if (cpu_is_omap7xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 5)];
-	}
-	if (cpu_is_omap24xx())
-		return &gpio_bank[gpio >> 5];
-	if (cpu_is_omap34xx() || cpu_is_omap44xx())
-		return &gpio_bank[gpio >> 5];
-	BUG();
-	return NULL;
-}
-
 static inline int get_gpio_index(int gpio)
 {
 	if (cpu_is_omap7xx())
@@ -1393,7 +1368,7 @@ static struct platform_device omap_mpuio_device = {
 
 static inline void mpuio_init(void)
 {
-	struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+	struct gpio_bank *bank = &gpio_bank[0];
 	platform_set_drvdata(&omap_mpuio_device, bank);
 
 	if (platform_driver_register(&omap_mpuio_driver) == 0)
@@ -1469,7 +1444,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
 	u32 mask;
 
 	gpio = chip->base + offset;
-	bank = get_gpio_bank(gpio);
+	bank = container_of(chip, struct gpio_bank, chip);
 	reg = bank->base;
 	mask = 1 << get_gpio_index(gpio);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 01/18] OMAP1: GPIO: Fix mpuio_init() call Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 02/18] OMAP: GPIO: remove get_gpio_bank() Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 14:59   ` Kevin Hilman
  2011-04-22 11:08 ` [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files Charulatha V
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

gpio_get_index() uses cpu_is* checks. Move this function from
plat-omap/gpio.c to SoC specific GPIO files in mach-omap*/ and
use pdata to pass the function pointer.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |   14 ++++++++++
 arch/arm/mach-omap1/gpio16xx.c         |   18 +++++++++++++-
 arch/arm/mach-omap1/gpio7xx.c          |   18 +++++++++++++-
 arch/arm/mach-omap2/gpio.c             |   12 +++++++++
 arch/arm/plat-omap/gpio.c              |   42 +++++++++++++-------------------
 arch/arm/plat-omap/include/plat/gpio.h |    5 ++++
 6 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 04c4b04..eb2727a 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -21,6 +21,8 @@
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 #define OMAP1510_GPIO_BASE		0xFFFCE000
 
+#define OMAP1510_GPIO_INDEX_MASK	0x0f
+
 /* gpio1 */
 static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
 	{
@@ -80,6 +82,15 @@ static struct __initdata platform_device omap15xx_gpio = {
 	.resource = omap15xx_gpio_resources,
 };
 
+static int get_gpio_index(int gpio)
+{
+	return gpio & OMAP1510_GPIO_INDEX_MASK;
+}
+
+static struct omap_gpio_func gpio_fn = {
+	.get_index = get_gpio_index,
+};
+
 /*
  * omap15xx_gpio_init needs to be done before
  * machine_init functions access gpio APIs.
@@ -90,7 +101,10 @@ static int __init omap15xx_gpio_init(void)
 	if (!cpu_is_omap15xx())
 		return -EINVAL;
 
+	omap15xx_gpio_config.gpio_fn = &gpio_fn;
 	platform_device_register(&omap15xx_mpu_gpio);
+
+	omap15xx_mpu_gpio_config.gpio_fn = &gpio_fn;
 	platform_device_register(&omap15xx_gpio);
 
 	gpio_bank_count = 2;
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 5dd0d4c..9d8aabc 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -24,6 +24,8 @@
 #define OMAP1610_GPIO4_BASE		0xfffbbc00
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 
+#define OMAP1610_GPIO_INDEX_MASK	0x0f
+
 /* mpu gpio */
 static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
 	{
@@ -178,6 +180,15 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = {
 	&omap16xx_gpio4,
 };
 
+static int get_gpio_index(int gpio)
+{
+	return gpio & OMAP1610_GPIO_INDEX_MASK;
+}
+
+static struct omap_gpio_func gpio_fn = {
+	.get_index = get_gpio_index,
+};
+
 /*
  * omap16xx_gpio_init needs to be done before
  * machine_init functions access gpio APIs.
@@ -190,8 +201,13 @@ static int __init omap16xx_gpio_init(void)
 	if (!cpu_is_omap16xx())
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++)
+	for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
+		struct omap_gpio_platform_data *pdata;
+
+		pdata = omap16xx_gpio_dev[i]->dev.platform_data;
+		pdata->gpio_fn = &gpio_fn;
 		platform_device_register(omap16xx_gpio_dev[i]);
+	}
 
 	gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
 
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 1204c8b..74456a9 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -26,6 +26,8 @@
 #define OMAP7XX_GPIO6_BASE		0xfffbe800
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 
+#define OMAP7XX_GPIO_INDEX_MASK		0x1f
+
 /* mpu gpio */
 static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
 	{
@@ -240,6 +242,15 @@ static struct __initdata platform_device * omap7xx_gpio_dev[] = {
 	&omap7xx_gpio6,
 };
 
+static int get_gpio_index(int gpio)
+{
+	return gpio & OMAP7XX_GPIO_INDEX_MASK;
+}
+
+static struct omap_gpio_func gpio_fn = {
+	.get_index = get_gpio_index,
+};
+
 /*
  * omap7xx_gpio_init needs to be done before
  * machine_init functions access gpio APIs.
@@ -252,8 +263,13 @@ static int __init omap7xx_gpio_init(void)
 	if (!cpu_is_omap7xx())
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++)
+	for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++) {
+		struct omap_gpio_platform_data *pdata;
+
+		pdata = omap7xx_gpio_dev[i]->dev.platform_data;
+		pdata->gpio_fn = &gpio_fn;
 		platform_device_register(omap7xx_gpio_dev[i]);
+	}
 
 	gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
 
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 9529842..498ab92 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>
 
+#define OMAP2_GPIO_INDEX_MASK		0x1f
+
 static struct omap_device_pm_latency omap_gpio_latency[] = {
 	[0] = {
 		.deactivate_func = omap_device_idle_hwmods,
@@ -32,6 +34,15 @@ static struct omap_device_pm_latency omap_gpio_latency[] = {
 	},
 };
 
+static int get_gpio_index(int gpio)
+{
+	return gpio & OMAP2_GPIO_INDEX_MASK;
+}
+
+static struct omap_gpio_func gpio_fn = {
+	.get_index = get_gpio_index,
+};
+
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 {
 	struct omap_device *od;
@@ -60,6 +71,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->gpio_fn = &gpio_fn;
 
 	switch (oh->class->rev) {
 	case 0:
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 498e1df..e70bb6e 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -183,23 +183,13 @@ static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
  * related to all instances of the device
  */
 static struct gpio_bank *gpio_bank;
+static struct omap_gpio_func gpio_fn;
 
 static int bank_width;
 
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
 int gpio_bank_count;
 
-static inline int get_gpio_index(int gpio)
-{
-	if (cpu_is_omap7xx())
-		return gpio & 0x1f;
-	if (cpu_is_omap24xx())
-		return gpio & 0x1f;
-	if (cpu_is_omap34xx() || cpu_is_omap44xx())
-		return gpio & 0x1f;
-	return gpio & 0x0f;
-}
-
 static inline int gpio_valid(int gpio)
 {
 	if (gpio < 0)
@@ -394,7 +384,7 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 		return -EINVAL;
 	}
 	return (__raw_readl(reg)
-			& (1 << get_gpio_index(gpio))) != 0;
+			& (1 << gpio_fn.get_index(gpio))) != 0;
 }
 
 static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
@@ -440,7 +430,7 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
 		return -EINVAL;
 	}
 
-	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+	return (__raw_readl(reg) & (1 << gpio_fn.get_index(gpio))) != 0;
 }
 
 #define MOD_REG_BIT(reg, bit_mask, set)	\
@@ -477,7 +467,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	else
 		debounce = (debounce / 0x1f) - 1;
 
-	l = 1 << get_gpio_index(gpio);
+	l = 1 << gpio_fn.get_index(gpio);
 
 	if (bank->method == METHOD_GPIO_44XX)
 		reg += OMAP4_GPIO_DEBOUNCINGTIME;
@@ -729,7 +719,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 
 	bank = irq_data_get_irq_chip_data(d);
 	spin_lock_irqsave(&bank->lock, flags);
-	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
+	retval = _set_gpio_triggering(bank, gpio_fn.get_index(gpio), type);
 	spin_unlock_irqrestore(&bank->lock, flags);
 
 	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -798,7 +788,7 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
 {
-	_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
+	_clear_gpio_irqbank(bank, 1 << gpio_fn.get_index(gpio));
 }
 
 static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
@@ -932,7 +922,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 
 static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
 {
-	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
+	_enable_gpio_irqbank(bank, 1 << gpio_fn.get_index(gpio), enable);
 }
 
 /*
@@ -985,10 +975,10 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 
 static void _reset_gpio(struct gpio_bank *bank, int gpio)
 {
-	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
+	_set_gpio_direction(bank, gpio_fn.get_index(gpio), 1);
 	_set_gpio_irqenable(bank, gpio, 0);
 	_clear_gpio_irqstatus(bank, gpio);
-	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+	_set_gpio_triggering(bank, gpio_fn.get_index(gpio), IRQ_TYPE_NONE);
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
@@ -1001,7 +991,7 @@ static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
 	if (check_gpio(gpio) < 0)
 		return -ENODEV;
 	bank = irq_data_get_irq_chip_data(d);
-	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
+	retval = _set_gpio_wakeup(bank, gpio_fn.get_index(gpio), enable);
 
 	return retval;
 }
@@ -1180,7 +1170,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 		gpio_irq = bank->virtual_irq_start;
 		for (; isr != 0; isr >>= 1, gpio_irq++) {
-			gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
+			gpio_index = gpio_fn.get_index(irq_to_gpio(gpio_irq));
 
 			if (!(isr & 1))
 				continue;
@@ -1231,18 +1221,18 @@ static void gpio_mask_irq(struct irq_data *d)
 	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
 
 	_set_gpio_irqenable(bank, gpio, 0);
-	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+	_set_gpio_triggering(bank, gpio_fn.get_index(gpio), IRQ_TYPE_NONE);
 }
 
 static void gpio_unmask_irq(struct irq_data *d)
 {
 	unsigned int gpio = d->irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	unsigned int irq_mask = 1 << get_gpio_index(gpio);
+	unsigned int irq_mask = 1 << gpio_fn.get_index(gpio);
 	u32 trigger = irqd_get_trigger_type(d);
 
 	if (trigger)
-		_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
+		_set_gpio_triggering(bank, gpio_fn.get_index(gpio), trigger);
 
 	/* For level-triggered GPIOs, the clearing must be done after
 	 * the HW source is cleared, thus after the handler has run */
@@ -1446,7 +1436,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
 	gpio = chip->base + offset;
 	bank = container_of(chip, struct gpio_bank, chip);
 	reg = bank->base;
-	mask = 1 << get_gpio_index(gpio);
+	mask = 1 << gpio_fn.get_index(gpio);
 
 	if (gpio_is_input(bank, mask))
 		return _get_gpio_datain(bank, gpio);
@@ -1674,6 +1664,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 			return ret;
 		if (cpu_class_is_omap1())
 			mpuio_init();
+
+		gpio_fn.get_index = pdata->gpio_fn->get_index;
 	}
 
 	id = pdev->id;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index cac2e8a..1cfb01b 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -71,8 +71,13 @@ struct omap_gpio_dev_attr {
 	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
 };
 
+struct omap_gpio_func {
+	int (*get_index)(int gpio);
+};
+
 struct omap_gpio_platform_data {
 	u16 virtual_irq_start;
+	struct omap_gpio_func *gpio_fn;
 	int bank_type;
 	int bank_width;		/* GPIO bank width */
 	int bank_stride;	/* Only needed for omap1 MPUIO */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (2 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 15:15   ` Kevin Hilman
  2011-04-22 11:08 ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain,dataout,set dir funcs Charulatha V
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

gpio_valid() implementation is different for different SoCs.
Hence handle them in SoC specific gpio files.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |   26 ++++++++++++++++++++-
 arch/arm/mach-omap1/gpio16xx.c         |   32 ++++++++++++++++++++++----
 arch/arm/mach-omap1/gpio7xx.c          |   38 ++++++++++++++++++++++++++------
 arch/arm/mach-omap2/gpio.c             |   14 +++++++++++-
 arch/arm/plat-omap/gpio.c              |   27 +---------------------
 arch/arm/plat-omap/include/plat/gpio.h |    1 +
 6 files changed, 98 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index eb2727a..9d7a3fa 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -22,6 +22,10 @@
 #define OMAP1510_GPIO_BASE		0xFFFCE000
 
 #define OMAP1510_GPIO_INDEX_MASK	0x0f
+#define OMAP1510_GPIO_WIDTH		16
+#define OMAP1510_GPIO_BANK_CNT		2
+#define OMAP1510_NON_MPUIO_GPIO_VALID	((OMAP1510_GPIO_BANK_CNT - 1) *\
+						OMAP1510_GPIO_WIDTH)
 
 /* gpio1 */
 static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
@@ -39,7 +43,7 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
 static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
 	.bank_type		= METHOD_MPUIO,
-	.bank_width		= 16,
+	.bank_width		= OMAP1510_GPIO_WIDTH,
 	.bank_stride		= 1,
 };
 
@@ -69,7 +73,7 @@ static struct __initdata resource omap15xx_gpio_resources[] = {
 static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
 	.bank_type		= METHOD_GPIO_1510,
-	.bank_width		= 16,
+	.bank_width		= OMAP1510_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap15xx_gpio = {
@@ -87,8 +91,26 @@ static int get_gpio_index(int gpio)
 	return gpio & OMAP1510_GPIO_INDEX_MASK;
 }
 
+static int gpio_valid(int gpio)
+{
+	if (gpio < 0)
+		return -EINVAL;
+
+	if (OMAP_GPIO_IS_MPUIO(gpio)) {
+		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP1510_GPIO_WIDTH)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (gpio < OMAP1510_NON_MPUIO_GPIO_VALID)
+		return 0;
+
+	return -EINVAL;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
+	.gpio_valid = gpio_valid,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 9d8aabc..e6bb080 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -25,6 +25,10 @@
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 
 #define OMAP1610_GPIO_INDEX_MASK	0x0f
+#define OMAP1610_GPIO_WIDTH		16
+#define OMAP1610_GPIO_BANK_CNT		5
+#define OMAP1610_NON_MPUIO_GPIO_VALID	((OMAP1610_GPIO_BANK_CNT - 1) *\
+						OMAP1610_GPIO_WIDTH)
 
 /* mpu gpio */
 static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
@@ -42,7 +46,7 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
 static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
 	.bank_type		= METHOD_MPUIO,
-	.bank_width		= 16,
+	.bank_width		= OMAP1610_GPIO_WIDTH,
 	.bank_stride		= 1,
 };
 
@@ -72,7 +76,7 @@ static struct __initdata resource omap16xx_gpio1_resources[] = {
 static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
 	.bank_type		= METHOD_GPIO_1610,
-	.bank_width		= 16,
+	.bank_width		= OMAP1610_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap16xx_gpio1 = {
@@ -101,7 +105,7 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {
 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,
+	.bank_width		= OMAP1610_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap16xx_gpio2 = {
@@ -130,7 +134,7 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {
 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,
+	.bank_width		= OMAP1610_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap16xx_gpio3 = {
@@ -159,7 +163,7 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {
 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,
+	.bank_width		= OMAP1610_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap16xx_gpio4 = {
@@ -185,8 +189,26 @@ static int get_gpio_index(int gpio)
 	return gpio & OMAP1610_GPIO_INDEX_MASK;
 }
 
+static int gpio_valid(int gpio)
+{
+	if (gpio < 0)
+		return -EINVAL;
+
+	if (OMAP_GPIO_IS_MPUIO(gpio)) {
+		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP1610_GPIO_WIDTH)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (gpio < OMAP1610_NON_MPUIO_GPIO_VALID)
+		return 0;
+
+	return -EINVAL;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
+	.gpio_valid = gpio_valid,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 74456a9..bd6fc8e 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -28,6 +28,12 @@
 
 #define OMAP7XX_GPIO_INDEX_MASK		0x1f
 
+#define OMAP7XX_GPIO_WIDTH		32
+#define OMAP7XX_MPUIO_GPIO_PIN_CNT	16
+#define OMAP7XX_GPIO_BANK_CNT		7
+#define OMAP7XX_NON_MPUIO_GPIO_VALID	((OMAP7XX_GPIO_BANK_CNT - 1) *\
+						OMAP7XX_GPIO_WIDTH)
+
 /* mpu gpio */
 static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
 	{
@@ -44,7 +50,7 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
 	.bank_type		= METHOD_MPUIO,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 	.bank_stride		= 2,
 };
 
@@ -74,7 +80,7 @@ static struct __initdata resource omap7xx_gpio1_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio1 = {
@@ -103,7 +109,7 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 32,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio2 = {
@@ -132,7 +138,7 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 64,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio3 = {
@@ -161,7 +167,7 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 96,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio4 = {
@@ -190,7 +196,7 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 128,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio5 = {
@@ -219,7 +225,7 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {
 static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 160,
 	.bank_type		= METHOD_GPIO_7XX,
-	.bank_width		= 32,
+	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
 static struct __initdata platform_device omap7xx_gpio6 = {
@@ -247,8 +253,26 @@ static int get_gpio_index(int gpio)
 	return gpio & OMAP7XX_GPIO_INDEX_MASK;
 }
 
+static int gpio_valid(int gpio)
+{
+	if (gpio < 0)
+		return -EINVAL;
+
+	if (OMAP_GPIO_IS_MPUIO(gpio)) {
+		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP7XX_MPUIO_GPIO_PIN_CNT)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (gpio < OMAP7XX_NON_MPUIO_GPIO_VALID)
+		return 0;
+
+	return -EINVAL;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
+	.gpio_valid = gpio_valid,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 498ab92..08ee5f1 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -26,6 +26,8 @@
 
 #define OMAP2_GPIO_INDEX_MASK		0x1f
 
+int bank_width;
+
 static struct omap_device_pm_latency omap_gpio_latency[] = {
 	[0] = {
 		.deactivate_func = omap_device_idle_hwmods,
@@ -39,8 +41,17 @@ static int get_gpio_index(int gpio)
 	return gpio & OMAP2_GPIO_INDEX_MASK;
 }
 
+static int gpio_valid(int gpio)
+{
+	if ((gpio >= 0) && (gpio < (gpio_bank_count * bank_width)))
+		return 0;
+
+	return -EINVAL;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
+	.gpio_valid = gpio_valid,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
@@ -68,7 +79,8 @@ 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;
+	bank_width = dev_attr->bank_width;
+	pdata->bank_width = bank_width;
 	pdata->dbck_flag = dev_attr->dbck_flag;
 	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
 	pdata->gpio_fn = &gpio_fn;
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index e70bb6e..0f1dbbf 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -190,33 +190,9 @@ static int bank_width;
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
 int gpio_bank_count;
 
-static inline int gpio_valid(int gpio)
-{
-	if (gpio < 0)
-		return -1;
-	if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
-		if (gpio >= OMAP_MAX_GPIO_LINES + 16)
-			return -1;
-		return 0;
-	}
-	if (cpu_is_omap15xx() && gpio < 16)
-		return 0;
-	if ((cpu_is_omap16xx()) && gpio < 64)
-		return 0;
-	if (cpu_is_omap7xx() && gpio < 192)
-		return 0;
-	if (cpu_is_omap2420() && gpio < 128)
-		return 0;
-	if (cpu_is_omap2430() && gpio < 160)
-		return 0;
-	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
-		return 0;
-	return -1;
-}
-
 static int check_gpio(int gpio)
 {
-	if (unlikely(gpio_valid(gpio) < 0)) {
+	if (unlikely(gpio_fn.gpio_valid(gpio) < 0)) {
 		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
 		dump_stack();
 		return -1;
@@ -1666,6 +1642,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 			mpuio_init();
 
 		gpio_fn.get_index = pdata->gpio_fn->get_index;
+		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
 	}
 
 	id = pdev->id;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 1cfb01b..00586ad 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -73,6 +73,7 @@ struct omap_gpio_dev_attr {
 
 struct omap_gpio_func {
 	int (*get_index)(int gpio);
+	int (*gpio_valid)(int gpio);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 05/18] OMAP: GPIO: cleanup datain,dataout,set dir funcs
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (3 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 15:22   ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain, dataout, set " Kevin Hilman
  2011-04-22 11:08 ` [RFC PATCH 06/18] OMAP: GPIO: cleanup set trigger func Charulatha V
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

* Define gpio register offsets in SoC specific GPIO files and use
  these register offsets while doing register read/write
* Remove the usage of CONFIG_ARCH_* checks and cpu_is* checks from
  the below functions
	_set_gpio_direction
	_set_gpio_dataout
	_get_gpio_dataout
	_get_gpio_datain
* MPUIO is a common gpio bank->method for OMAP15xx, OMAP16xx and
  OMAP7xx SoCs. Each of these SoCs has one bank with MPUIO type.
  Hence handle MPUIO type GPIO banks in GPIO driver.

Note: After the complete driver is cleaned up, the register offset
macros defined in OMAP GPIO driver would be removed

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |   22 +++
 arch/arm/mach-omap1/gpio16xx.c         |   32 ++++
 arch/arm/mach-omap1/gpio7xx.c          |   21 +++
 arch/arm/mach-omap2/gpio.c             |   72 +++++++++
 arch/arm/plat-omap/gpio.c              |  261 ++++++++++----------------------
 arch/arm/plat-omap/include/plat/gpio.h |   39 +++++
 6 files changed, 265 insertions(+), 182 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 9d7a3fa..26c6c25 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -27,6 +27,16 @@
 #define OMAP1510_NON_MPUIO_GPIO_VALID	((OMAP1510_GPIO_BANK_CNT - 1) *\
 						OMAP1510_GPIO_WIDTH)
 
+static u16 reg_map[] = {
+	[DATAIN]		= 0x00,
+	[DATAOUT]		= 0x04,
+	[OE]			= 0x08,
+	[INT_CTRL]		= 0x0C,
+	[IRQENABLE1]		= 0x10,
+	[IRQSTATUS_REG0]	= 0x14,
+	[CTRL]			= 0x18,
+};
+
 /* gpio1 */
 static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
 	{
@@ -86,6 +96,16 @@ static struct __initdata platform_device omap15xx_gpio = {
 	.resource = omap15xx_gpio_resources,
 };
 
+static inline u32 gpio_read(void __iomem *base, int reg)
+{
+	return __raw_readl(base + reg_map[reg]);
+}
+
+static inline void gpio_write(u32 val, void __iomem *base, int reg)
+{
+	__raw_writel(val, base + reg_map[reg]);
+}
+
 static int get_gpio_index(int gpio)
 {
 	return gpio & OMAP1510_GPIO_INDEX_MASK;
@@ -111,6 +131,8 @@ static int gpio_valid(int gpio)
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
+	.gpio_read = gpio_read,
+	.gpio_write = gpio_write,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index e6bb080..473c889 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -30,6 +30,26 @@
 #define OMAP1610_NON_MPUIO_GPIO_VALID	((OMAP1610_GPIO_BANK_CNT - 1) *\
 						OMAP1610_GPIO_WIDTH)
 
+static u16 reg_map[] = {
+	[REV]			= 0x00,
+	[SYS_CFG]		= 0x10,
+	[SYS_STATUS]		= 0x14,
+	[IRQSTATUS_REG0]	= 0x18,
+	[IRQENABLE1]		= 0x1C,
+	[WAKE_EN]		= 0x28,
+	[DATAIN]		= 0x2C,
+	[DATAOUT]		= 0x30,
+	[OE]			= 0x34,
+	[EDGE_CTRL1]		= 0x38,
+	[EDGE_CTRL2]		= 0x3C,
+	[CLEARIRQENA1]		= 0x9C,
+	[CLEARWKUENA]		= 0xA8,
+	[CLEARDATAOUT]		= 0xB0,
+	[SETIRQENA1]		= 0xDC,
+	[SETWKUENA]		= 0xE8,
+	[SETDATAOUT]		= 0xF0,
+};
+
 /* mpu gpio */
 static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
 	{
@@ -184,6 +204,16 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = {
 	&omap16xx_gpio4,
 };
 
+static inline u32 gpio_read(void __iomem *base, int reg)
+{
+	return __raw_readl(base + reg_map[reg]);
+}
+
+static inline void gpio_write(u32 val, void __iomem *base, int reg)
+{
+	__raw_writel(val, base + reg_map[reg]);
+}
+
 static int get_gpio_index(int gpio)
 {
 	return gpio & OMAP1610_GPIO_INDEX_MASK;
@@ -209,6 +239,8 @@ static int gpio_valid(int gpio)
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
+	.gpio_read = gpio_read,
+	.gpio_write = gpio_write,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index bd6fc8e..a6c2397 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -34,6 +34,15 @@
 #define OMAP7XX_NON_MPUIO_GPIO_VALID	((OMAP7XX_GPIO_BANK_CNT - 1) *\
 						OMAP7XX_GPIO_WIDTH)
 
+static u16 reg_map[] = {
+	[DATAIN]		= 0x00,
+	[DATAOUT]		= 0x04,
+	[OE]			= 0x08,
+	[INT_CTRL]		= 0x0C,
+	[IRQENABLE1]		= 0x10,
+	[IRQSTATUS_REG0]	= 0x14,
+};
+
 /* mpu gpio */
 static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
 	{
@@ -248,6 +257,16 @@ static struct __initdata platform_device * omap7xx_gpio_dev[] = {
 	&omap7xx_gpio6,
 };
 
+static inline u32 gpio_read(void __iomem *base, int reg)
+{
+	return __raw_readl(base + reg_map[reg]);
+}
+
+static inline void gpio_write(u32 val, void __iomem *base, int reg)
+{
+	__raw_writel(val, base + reg_map[reg]);
+}
+
 static int get_gpio_index(int gpio)
 {
 	return gpio & OMAP7XX_GPIO_INDEX_MASK;
@@ -273,6 +292,8 @@ static int gpio_valid(int gpio)
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
+	.gpio_read = gpio_read,
+	.gpio_write = gpio_write,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 08ee5f1..7764ebe 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -27,6 +27,64 @@
 #define OMAP2_GPIO_INDEX_MASK		0x1f
 
 int bank_width;
+static u16 *reg_map;
+static u16 omap2_gpio_reg_offsets[] = {
+	[REV]			= 0x00,
+	[IRQSTATUS_REG0]	= 0x18,
+	[IRQENABLE1]		= 0x1C,
+	[WAKE_EN]		= 0x20,
+	[IRQSTATUS_REG1]	= 0x28,
+	[IRQENABLE2]		= 0x2C,
+	[CTRL]			= 0x30,
+	[OE]			= 0x34,
+	[DATAIN]		= 0x38,
+	[DATAOUT]		= 0x3C,
+	[LEVELDETECT0]		= 0x40,
+	[LEVELDETECT1]		= 0x44,
+	[RISINGDETECT]		= 0x48,
+	[FALLINGDETECT]		= 0x4C,
+	[DEBOUNCE_EN]		= 0x50,
+	[DEBOUNCE_VAL]		= 0x54,
+	[CLEARIRQENA1]		= 0x60,
+	[SETIRQENA1]		= 0x64,
+	[CLEARWKUENA]		= 0x80,
+	[SETWKUENA]		= 0x84,
+	[CLEARDATAOUT]		= 0x90,
+	[SETDATAOUT]		= 0x94,
+};
+
+static u16 omap4_gpio_reg_offsets[] = {
+	[REV]			= 0x0000,
+	[IRQSTATUSRAW0]		= 0x0024,
+	[IRQSTATUSRAW1]		= 0x0028,
+	[IRQSTATUS_REG0]	= 0x002C,
+	[IRQSTATUS_REG1]	= 0x0030,
+	[IRQSTATUSSET0]		= 0x0034,
+	[IRQSTATUSSET1]		= 0x0038,
+	[IRQSTATUSCLR0]		= 0x003C,
+	[IRQSTATUSCLR1]		= 0x0040,
+	[IRQWAKEN0]		= 0x0044,
+	[IRQWAKEN1]		= 0x0048,
+	[IRQENABLE1]		= 0x011C,
+	[WAKE_EN]		= 0x0120,
+	[IRQENABLE2]		= 0x012C,
+	[CTRL]			= 0x0130,
+	[OE]			= 0x0134,
+	[DATAIN]		= 0x0138,
+	[DATAOUT]		= 0x013C,
+	[LEVELDETECT0]		= 0x0140,
+	[LEVELDETECT1]		= 0x0144,
+	[RISINGDETECT]		= 0x0148,
+	[FALLINGDETECT]		= 0x014C,
+	[DEBOUNCE_EN]		= 0x0150,
+	[DEBOUNCE_VAL]		= 0x0154,
+	[CLEARIRQENA1]		= 0x0160,
+	[SETIRQENA1]		= 0x0164,
+	[CLEARWKUENA]		= 0x0180,
+	[SETWKUENA]		= 0x0184,
+	[CLEARDATAOUT]		= 0x0190,
+	[SETDATAOUT]		= 0x0194,
+};
 
 static struct omap_device_pm_latency omap_gpio_latency[] = {
 	[0] = {
@@ -36,6 +94,16 @@ static struct omap_device_pm_latency omap_gpio_latency[] = {
 	},
 };
 
+static inline u32 gpio_read(void __iomem *base, int reg)
+{
+	return __raw_readl(base + reg_map[reg]);
+}
+
+static inline void gpio_write(u32 val, void __iomem *base, int reg)
+{
+	__raw_writel(val, base + reg_map[reg]);
+}
+
 static int get_gpio_index(int gpio)
 {
 	return gpio & OMAP2_GPIO_INDEX_MASK;
@@ -52,6 +120,8 @@ static int gpio_valid(int gpio)
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
+	.gpio_read = gpio_read,
+	.gpio_write = gpio_write,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
@@ -89,9 +159,11 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	case 0:
 	case 1:
 		pdata->bank_type = METHOD_GPIO_24XX;
+		reg_map = omap2_gpio_reg_offsets;
 		break;
 	case 2:
 		pdata->bank_type = METHOD_GPIO_44XX;
+		reg_map = omap4_gpio_reg_offsets;
 		break;
 	default:
 		WARN(1, "Invalid gpio bank_type\n");
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 0f1dbbf..701152b 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -200,213 +200,127 @@ static int check_gpio(int gpio)
 	return 0;
 }
 
+static inline u32 gpio_mpuio_read(void __iomem *base, int reg)
+{
+	return __raw_readl(base + reg);
+}
+
+static inline void gpio_mpuio_write(u32 val, void __iomem *base, int reg)
+{
+	__raw_writel(val, base + reg);
+}
+
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
-	void __iomem *reg = bank->base;
+	void __iomem *base = bank->base;
+	u32 offset;
 	u32 l;
 
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DIR_CONTROL;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DIRECTION;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DIR_CONTROL;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_OE;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_OE;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
+	if (bank->method == METHOD_MPUIO) {
+		offset = OMAP_MPUIO_IO_CNTL / bank->stride;
+		l = gpio_mpuio_read(base, offset);
+	} else {
+		offset = OE;
+		l = gpio_fn.gpio_read(base, offset);
 	}
-	l = __raw_readl(reg);
+
 	if (is_input)
 		l |= 1 << gpio;
 	else
 		l &= ~(1 << gpio);
-	__raw_writel(l, reg);
+
+	if (bank->method == METHOD_MPUIO)
+		gpio_mpuio_write(l, base, offset);
+	else
+		gpio_fn.gpio_write(l, base, offset);
 }
 
 static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 {
-	void __iomem *reg = bank->base;
+	void __iomem *base = bank->base;
+	u32 offset;
 	u32 l = 0;
 
 	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_OUTPUT / bank->stride;
-		l = __raw_readl(reg);
+		offset = OMAP_MPUIO_OUTPUT / bank->stride;
+		l = gpio_mpuio_read(base, offset);
+
 		if (enable)
 			l |= 1 << gpio;
 		else
 			l &= ~(1 << gpio);
+
+		gpio_mpuio_write(l, base, offset);
 		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
+
 	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_DATAOUT;
-		else
-			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
-		l = 1 << gpio;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
+		l = gpio_fn.gpio_read(base, DATAOUT);
+
 		if (enable)
 			l |= 1 << gpio;
 		else
 			l &= ~(1 << gpio);
+
+		gpio_fn.gpio_write(l, base, DATAOUT);
 		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		if (enable)
-			reg += OMAP24XX_GPIO_SETDATAOUT;
-		else
-			reg += OMAP24XX_GPIO_CLEARDATAOUT;
-		l = 1 << gpio;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
+
+	default:
 		if (enable)
-			reg += OMAP4_GPIO_SETDATAOUT;
+			offset = SETDATAOUT;
 		else
-			reg += OMAP4_GPIO_CLEARDATAOUT;
+			offset = CLEARDATAOUT;
+
 		l = 1 << gpio;
+		gpio_fn.gpio_write(l, base, offset);
 		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
 	}
-	__raw_writel(l, reg);
+
 }
 
 static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 {
-	void __iomem *reg;
+	void __iomem *base;
+	int ret = -EINVAL;
+	u32 offset;
 
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-	reg = bank->base;
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_INPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DATAIN;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_INPUT;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_DATAIN;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_DATAIN;
-		break;
-#endif
-	default:
-		return -EINVAL;
+		return ret;
+
+	base = bank->base;
+
+	if (bank->method == METHOD_MPUIO) {
+		offset = OMAP_MPUIO_INPUT_LATCH / bank->stride;
+		ret = gpio_mpuio_read(base, offset);
+	} else {
+		offset = DATAIN;
+		ret = gpio_fn.gpio_read(base, offset);
 	}
-	return (__raw_readl(reg)
-			& (1 << gpio_fn.get_index(gpio))) != 0;
+
+	return (ret & (1 << gpio_fn.get_index(gpio))) != 0;
 }
 
 static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
 {
-	void __iomem *reg;
+	void __iomem *base;
+	int ret = -EINVAL;
+	u32 offset;
 
 	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-	reg = bank->base;
+		return ret;
 
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_OUTPUT / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_OUTPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DATAOUT;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_OUTPUT;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_DATAOUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_DATAOUT;
-		break;
-#endif
-	default:
-		return -EINVAL;
+	base = bank->base;
+
+	if (bank->method == METHOD_MPUIO) {
+		offset = OMAP_MPUIO_OUTPUT / bank->stride;
+		ret = gpio_mpuio_read(base, offset);
+	} else {
+		offset = DATAOUT;
+		ret = gpio_fn.gpio_read(base, offset);
 	}
 
-	return (__raw_readl(reg) & (1 << gpio_fn.get_index(gpio))) != 0;
+	return (ret & (1 << gpio_fn.get_index(gpio))) != 0;
 }
 
 #define MOD_REG_BIT(reg, bit_mask, set)	\
@@ -1374,32 +1288,13 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
 
 static int gpio_is_input(struct gpio_bank *bank, int mask)
 {
-	void __iomem *reg = bank->base;
+	void __iomem *base = bank->base;
 
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DIRECTION;
-		break;
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_OE;
-		break;
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_OE;
-		break;
-	default:
-		WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
-		return -EINVAL;
-	}
-	return __raw_readl(reg) & mask;
+	if (bank->method == METHOD_MPUIO)
+		return gpio_mpuio_read(base, OMAP_MPUIO_IO_CNTL / bank->stride)
+				& mask;
+	else
+		return gpio_fn.gpio_read(base, OE) & mask;
 }
 
 static int gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -1643,6 +1538,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 
 		gpio_fn.get_index = pdata->gpio_fn->get_index;
 		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
+		gpio_fn.gpio_read = pdata->gpio_fn->gpio_read;
+		gpio_fn.gpio_write = pdata->gpio_fn->gpio_write;
 	}
 
 	id = pdev->id;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 00586ad..745515a 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -66,6 +66,43 @@
 #define METHOD_GPIO_24XX	5
 #define METHOD_GPIO_44XX	6
 
+enum omap_gpio_reg_offsets {
+	/* Common Registers*/
+	DATAIN,		DATAOUT,
+	/* Direction Control register/ Output Enable register */
+	OE,
+	IRQSTATUS_REG0,
+	/* Interrupt Mask/ Enable register */
+	IRQENABLE1,
+	CTRL,
+
+	/* OMAP16xx & OMAP2PLUS specific */
+	REV,
+	WAKE_EN,
+	CLEARIRQENA1,	SETIRQENA1,
+	CLEARWKUENA,	SETWKUENA,
+	CLEARDATAOUT,	SETDATAOUT,
+
+	/* OMAP2PLUS specific */
+	IRQSTATUS_REG1,	IRQENABLE2,
+	LEVELDETECT0,	LEVELDETECT1,
+	RISINGDETECT,	FALLINGDETECT,
+	DEBOUNCE_EN,	DEBOUNCE_VAL,
+
+	/* OMAP4 specific */
+	IRQWAKEN0,	IRQWAKEN1,
+	IRQSTATUSSET0,	IRQSTATUSSET1,
+	IRQSTATUSCLR0,	IRQSTATUSCLR1,
+	IRQSTATUSRAW0,	IRQSTATUSRAW1,
+
+	/* OMAP15xx and OMAP7xx specific */
+	INT_CTRL,
+
+	/* OMAP16xx specific */
+	SYS_CFG,	SYS_STATUS,
+	EDGE_CTRL1,	EDGE_CTRL2,
+};
+
 struct omap_gpio_dev_attr {
 	int bank_width;		/* GPIO bank width */
 	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
@@ -74,6 +111,8 @@ struct omap_gpio_dev_attr {
 struct omap_gpio_func {
 	int (*get_index)(int gpio);
 	int (*gpio_valid)(int gpio);
+	u32 (*gpio_read)(void __iomem *base, int reg);
+	void (*gpio_write)(u32 val, void __iomem *base, int reg);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 06/18] OMAP: GPIO: cleanup set trigger func
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (4 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain,dataout,set dir funcs Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 07/18] OMAP: GPIO: cleanup set/get IRQ, clr irqstatus funcs Charulatha V
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Cleanup GPIO set trigger and toggle edge triggering
functions by removing the cpu_is checks and the CONFIG_ARCH_*
checks .

Some part of the code access the gpio_bank structure which
is specific to the OMAP GPIO driver. Therefore such part of the
code are handled by means of gpio->method.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |   17 ++
 arch/arm/mach-omap1/gpio16xx.c         |   37 +++++
 arch/arm/mach-omap1/gpio7xx.c          |   19 +++
 arch/arm/mach-omap2/gpio.c             |   31 ++++
 arch/arm/plat-omap/gpio.c              |  264 ++++++++++++--------------------
 arch/arm/plat-omap/include/plat/gpio.h |    1 +
 6 files changed, 201 insertions(+), 168 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 26c6c25..3c64e69 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/irq.h>
 
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 #define OMAP1510_GPIO_BASE		0xFFFCE000
@@ -128,11 +129,27 @@ static int gpio_valid(int gpio)
 	return -EINVAL;
 }
 
+static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
+{
+	u32 l = gpio_read(base, INT_CTRL);
+
+	if (trigger & IRQ_TYPE_EDGE_RISING)
+		l |= 1 << gpio;
+	else if (trigger & IRQ_TYPE_EDGE_FALLING)
+		l &= ~(1 << gpio);
+	else
+		return -EINVAL;
+
+	gpio_write(l, base, INT_CTRL);
+	return 0;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
+	.gpio_set_trigger = gpio_set_trigger,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 473c889..6b4afa2 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/irq.h>
 
 #define OMAP1610_GPIO1_BASE		0xfffbe400
 #define OMAP1610_GPIO2_BASE		0xfffbec00
@@ -30,6 +31,12 @@
 #define OMAP1610_NON_MPUIO_GPIO_VALID	((OMAP1610_GPIO_BANK_CNT - 1) *\
 						OMAP1610_GPIO_WIDTH)
 
+#define	OMAP1610_GPIO_USE_EDGE_CTRL2_REG	0x08
+#define	OMAP1610_GPIO_SET_FALLING_EDGE		0x01
+#define	OMAP1610_GPIO_SET_RISING_EDGE		0x02
+#define	OMAP1610_GPIO_BOTH_EDGE_SET		0x03
+#define	OMAP1610_GPIO_EDGE_MASK			0x07
+
 static u16 reg_map[] = {
 	[REV]			= 0x00,
 	[SYS_CFG]		= 0x10,
@@ -236,11 +243,41 @@ static int gpio_valid(int gpio)
 	return -EINVAL;
 }
 
+static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
+{
+	u32 offset;
+	u32 l = 0;
+
+	if (gpio & OMAP1610_GPIO_USE_EDGE_CTRL2_REG)
+		offset = EDGE_CTRL2;
+	else
+		offset = EDGE_CTRL1;
+
+	l = gpio_read(base, offset);
+	gpio &= OMAP1610_GPIO_EDGE_MASK;
+	l &= ~(OMAP1610_GPIO_BOTH_EDGE_SET << (gpio << 1));
+
+	if (trigger & IRQ_TYPE_EDGE_RISING)
+		l |= OMAP1610_GPIO_SET_RISING_EDGE << (gpio << 1);
+	if (trigger & IRQ_TYPE_EDGE_FALLING)
+		l |= OMAP1610_GPIO_SET_FALLING_EDGE << (gpio << 1);
+
+	if (trigger)
+		/* Enable wake-up during idle for dynamic tick */
+		gpio_write(1 << gpio, base, SETWKUENA);
+	else
+		gpio_write(1 << gpio, base, CLEARWKUENA);
+
+	gpio_write(l, base, offset);
+	return 0;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
+	.gpio_set_trigger = gpio_set_trigger,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index a6c2397..599067d 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/irq.h>
 
 #define OMAP7XX_GPIO1_BASE		0xfffbc000
 #define OMAP7XX_GPIO2_BASE		0xfffbc800
@@ -289,11 +290,29 @@ static int gpio_valid(int gpio)
 	return -EINVAL;
 }
 
+static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
+{
+	u32 l = 0;
+
+	l = gpio_read(base, INT_CTRL);
+
+	if (trigger & IRQ_TYPE_EDGE_RISING)
+		l |= 1 << gpio;
+	else if (trigger & IRQ_TYPE_EDGE_FALLING)
+		l &= ~(1 << gpio);
+	else
+		return -EINVAL;
+
+	gpio_write(l, base, INT_CTRL);
+	return 0;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
+	.gpio_set_trigger = gpio_set_trigger,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 7764ebe..ff3ea7b 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -16,6 +16,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/err.h>
 #include <linux/slab.h>
@@ -117,11 +118,41 @@ static int gpio_valid(int gpio)
 	return -EINVAL;
 }
 
+static inline void modify_irq_type(void __iomem *base, u32 offset,
+		u32 bit_mask, u32 set)
+{
+	int l = gpio_read(base, offset);
+
+	if (set)
+		l |= bit_mask;
+	else
+		l &= ~bit_mask;
+
+	gpio_write(l, base, offset);
+}
+
+static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
+{
+	u32 gpio_bit = 1 << gpio;
+
+	modify_irq_type(base, LEVELDETECT0, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_LOW);
+	modify_irq_type(base, LEVELDETECT1, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_HIGH);
+	modify_irq_type(base, RISINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_RISING);
+	modify_irq_type(base, FALLINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_FALLING);
+
+	return 0;
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
+	.gpio_set_trigger = gpio_set_trigger,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 701152b..938cc4d 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -323,14 +323,6 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
 	return (ret & (1 << gpio_fn.get_index(gpio))) != 0;
 }
 
-#define MOD_REG_BIT(reg, bit_mask, set)	\
-do {	\
-	int l = __raw_readl(base + reg); \
-	if (set) l |= bit_mask; \
-	else l &= ~bit_mask; \
-	__raw_writel(l, base + reg); \
-} while(0)
-
 /**
  * _set_gpio_debounce - low level gpio debounce time
  * @bank: the gpio bank we're acting upon
@@ -386,131 +378,57 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	__raw_writel(val, reg);
 }
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
-						int trigger)
-{
-	void __iomem *base = bank->base;
-	u32 gpio_bit = 1 << gpio;
-	u32 val;
-
-	if (cpu_is_omap44xx()) {
-		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_LOW);
-		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_HIGH);
-		MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_RISING);
-		MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_FALLING);
-	} else {
-		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_LOW);
-		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_HIGH);
-		MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_RISING);
-		MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_FALLING);
-	}
-	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-		if (cpu_is_omap44xx()) {
-			if (trigger != 0)
-				__raw_writel(1 << gpio, bank->base+
-						OMAP4_GPIO_IRQWAKEN0);
-			else {
-				val = __raw_readl(bank->base +
-							OMAP4_GPIO_IRQWAKEN0);
-				__raw_writel(val & (~(1 << gpio)), bank->base +
-							 OMAP4_GPIO_IRQWAKEN0);
-			}
-		} else {
-			/*
-			 * GPIO wakeup request can only be generated on edge
-			 * transitions
-			 */
-			if (trigger & IRQ_TYPE_EDGE_BOTH)
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_SETWKUENA);
-			else
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_CLEARWKUENA);
-		}
-	}
-	/* This part needs to be executed always for OMAP34xx */
-	if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) {
-		/*
-		 * Log the edge gpio and manually trigger the IRQ
-		 * after resume if the input level changes
-		 * to avoid irq lost during PER RET/OFF mode
-		 * Applies for omap2 non-wakeup gpio and all omap3 gpios
-		 */
-		if (trigger & IRQ_TYPE_EDGE_BOTH)
-			bank->enabled_non_wakeup_gpios |= gpio_bit;
-		else
-			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);
-	}
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1
 /*
  * This only applies to chips that can't do both rising and falling edge
  * detection at once.  For all other chips, this function is a noop.
  */
 static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 {
-	void __iomem *reg = bank->base;
+	void __iomem *base = bank->base;
 	u32 l = 0;
+	u32 offset;
 
 	switch (bank->method) {
 	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		break;
-#ifdef CONFIG_ARCH_OMAP15XX
+		offset = OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
+		l = gpio_mpuio_read(base, offset);
+
+		if ((l >> gpio) & 1)
+			l &= ~(1 << gpio);
+		else
+			l |= 1 << gpio;
+
+		gpio_mpuio_write(l, base, offset);
+		return;
+
 	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		break;
-#endif
+		l = gpio_fn.gpio_read(base, INT_CTRL);
+
+		if ((l >> gpio) & 1)
+			l &= ~(1 << gpio);
+		else
+			l |= 1 << gpio;
+
+		gpio_fn.gpio_write(l, base, INT_CTRL);
+		return;
+
 	default:
 		return;
 	}
-
-	l = __raw_readl(reg);
-	if ((l >> gpio) & 1)
-		l &= ~(1 << gpio);
-	else
-		l |= 1 << gpio;
-
-	__raw_writel(l, reg);
 }
-#endif
 
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
-	void __iomem *reg = bank->base;
+	int ret = 0;
+	void __iomem *base = bank->base;
 	u32 l = 0;
+	u32 offset;
 
 	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		l = __raw_readl(reg);
+		offset = OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
+		l = gpio_mpuio_read(base, offset);
 		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
@@ -518,70 +436,80 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
 			l &= ~(1 << gpio);
 		else
-			goto bad;
+			return -EINVAL;
+
+		gpio_mpuio_write(l, base, offset);
 		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
+
 	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
+	case METHOD_GPIO_7XX:
 		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
+
+		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
 		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
+
 	case METHOD_GPIO_1610:
-		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
-		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
-		gpio &= 0x07;
-		l = __raw_readl(reg);
-		l &= ~(3 << (gpio << 1));
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 2 << (gpio << 1);
-		if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l |= 1 << (gpio << 1);
-		if (trigger)
-			/* Enable wake-up during idle for dynamic tick */
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
-		else
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
+		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
 		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
+
+	case METHOD_GPIO_44XX:
+		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
+
+		if (likely(!(bank->non_wakeup_gpios & (1 << gpio)))) {
+			if (trigger != 0)
+				gpio_fn.gpio_write(1 << gpio, base, IRQWAKEN0);
+			else {
+				u32 val;
+
+				val = gpio_fn.gpio_read(base, IRQWAKEN0);
+				gpio_fn.gpio_write(val & (~(1 << gpio)), base,
+						IRQWAKEN0);
+			}
+
+			bank->level_mask = gpio_fn.gpio_read(base,
+							LEVELDETECT0);
+			bank->level_mask |= gpio_fn.gpio_read(base,
+							LEVELDETECT1);
+		}
 		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
+
 	case METHOD_GPIO_24XX:
-	case METHOD_GPIO_44XX:
-		set_24xx_gpio_triggering(bank, gpio, trigger);
-		return 0;
-#endif
+		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
+
+		if (likely(!(bank->non_wakeup_gpios & (1 << gpio)))) {
+			/*
+			 * GPIO wakeup request can only be generated on edge
+			 * transitions
+			 */
+			if (trigger & IRQ_TYPE_EDGE_BOTH)
+				gpio_fn.gpio_write(1 << gpio, base, SETWKUENA);
+			else
+				gpio_fn.gpio_write(1 << gpio, base,
+							CLEARWKUENA);
+			/*
+			 * Log the edge gpio and manually trigger the IRQ
+			 * after resume if the input level changes
+			 * to avoid irq lost during PER RET/OFF mode
+			 * Applies for omap2 non-wakeup gpio and all omap3 gpios
+			 */
+			if (trigger & IRQ_TYPE_EDGE_BOTH)
+				bank->enabled_non_wakeup_gpios |= (1 << gpio);
+			else
+				bank->enabled_non_wakeup_gpios &= ~(1 << gpio);
+
+			bank->level_mask = gpio_fn.gpio_read(base,
+							LEVELDETECT0);
+			bank->level_mask |= gpio_fn.gpio_read(base,
+							LEVELDETECT1);
+		}
+		break;
 	default:
-		goto bad;
+		ret = -EINVAL;
+		break;
 	}
-	__raw_writel(l, reg);
-	return 0;
-bad:
-	return -EINVAL;
+
+	return ret;
 }
 
 static int gpio_irq_type(struct irq_data *d, unsigned type)
@@ -591,7 +519,9 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 	int retval;
 	unsigned long flags;
 
-	if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE)
+	bank = irq_data_get_irq_chip_data(d);
+
+	if ((bank->method == METHOD_MPUIO) && d->irq > IH_MPUIO_BASE)
 		gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
 	else
 		gpio = d->irq - IH_GPIO_BASE;
@@ -603,11 +533,10 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 		return -EINVAL;
 
 	/* OMAP1 allows only only edge triggering */
-	if (!cpu_class_is_omap2()
+	if ((bank->method < METHOD_GPIO_24XX)
 			&& (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_fn.get_index(gpio), type);
 	spin_unlock_irqrestore(&bank->lock, flags);
@@ -1065,7 +994,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 			if (!(isr & 1))
 				continue;
 
-#ifdef CONFIG_ARCH_OMAP1
 			/*
 			 * Some chips can't respond to both rising and falling
 			 * at the same time.  If this irq was requested with
@@ -1075,7 +1003,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 			 */
 			if (bank->toggle_mask & (1 << gpio_index))
 				_toggle_gpio_edge_triggering(bank, gpio_index);
-#endif
 
 			generic_handle_irq(gpio_irq);
 		}
@@ -1540,6 +1467,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
 		gpio_fn.gpio_read = pdata->gpio_fn->gpio_read;
 		gpio_fn.gpio_write = pdata->gpio_fn->gpio_write;
+		gpio_fn.gpio_set_trigger = pdata->gpio_fn->gpio_set_trigger;
 	}
 
 	id = pdev->id;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 745515a..b7c10bd 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -113,6 +113,7 @@ struct omap_gpio_func {
 	int (*gpio_valid)(int gpio);
 	u32 (*gpio_read)(void __iomem *base, int reg);
 	void (*gpio_write)(u32 val, void __iomem *base, int reg);
+	int (*gpio_set_trigger)(void __iomem *base, int gpio, int trigger);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 07/18] OMAP: GPIO: cleanup set/get IRQ, clr irqstatus funcs
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (5 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 06/18] OMAP: GPIO: cleanup set trigger func Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 08/18] OMAP: GPIO: req/free: Remove reg offset macros usage Charulatha V
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the usage of CONFIG_ARCH* checks in the following
functions of the GPIO driver and move SoC specific code
to SoC specific files.
	_enable_gpio_irqbank
	_get_gpio_irqbank_mask
	_clear_gpio_irqbank

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |   21 ++++
 arch/arm/mach-omap1/gpio16xx.c         |   16 +++
 arch/arm/mach-omap1/gpio7xx.c          |   20 ++++
 arch/arm/mach-omap2/gpio.c             |   26 +++++
 arch/arm/plat-omap/gpio.c              |  187 ++++++--------------------------
 arch/arm/plat-omap/include/plat/gpio.h |    2 +
 6 files changed, 116 insertions(+), 156 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 3c64e69..7a7a123 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -27,6 +27,7 @@
 #define OMAP1510_GPIO_BANK_CNT		2
 #define OMAP1510_NON_MPUIO_GPIO_VALID	((OMAP1510_GPIO_BANK_CNT - 1) *\
 						OMAP1510_GPIO_WIDTH)
+#define OMAP1510_GPIO_IRQENA_MASK	0xffff
 
 static u16 reg_map[] = {
 	[DATAIN]		= 0x00,
@@ -144,12 +145,32 @@ static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
 	return 0;
 }
 
+static u32 gpio_is_irqena(void __iomem *base)
+{
+	return (~gpio_read(base, IRQENABLE1))
+				& OMAP1510_GPIO_IRQENA_MASK;
+}
+
+static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
+{
+	u32 l = gpio_read(base, IRQENABLE1);
+
+	if (enable)
+		l &= ~(gpio_mask);
+	else
+		l |= gpio_mask;
+
+	gpio_write(l, base, IRQENABLE1);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
 	.gpio_set_trigger = gpio_set_trigger,
+	.gpio_is_irqena = gpio_is_irqena,
+	.gpio_enable_irq = gpio_enable_irq,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 6b4afa2..f05e0c7 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -30,6 +30,7 @@
 #define OMAP1610_GPIO_BANK_CNT		5
 #define OMAP1610_NON_MPUIO_GPIO_VALID	((OMAP1610_GPIO_BANK_CNT - 1) *\
 						OMAP1610_GPIO_WIDTH)
+#define OMAP1610_GPIO_IRQENA_MASK	0xffff
 
 #define	OMAP1610_GPIO_USE_EDGE_CTRL2_REG	0x08
 #define	OMAP1610_GPIO_SET_FALLING_EDGE		0x01
@@ -272,12 +273,27 @@ static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
 	return 0;
 }
 
+static u32 gpio_is_irqena(void __iomem *base)
+{
+	return gpio_read(base, IRQENABLE1) & OMAP1610_GPIO_IRQENA_MASK;
+}
+
+static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
+{
+	if (enable)
+		gpio_write(gpio_mask, base, SETIRQENA1);
+	else
+		gpio_write(gpio_mask, base, CLEARIRQENA1);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
 	.gpio_set_trigger = gpio_set_trigger,
+	.gpio_is_irqena = gpio_is_irqena,
+	.gpio_enable_irq = gpio_enable_irq,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 599067d..1103efc 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -34,6 +34,7 @@
 #define OMAP7XX_GPIO_BANK_CNT		7
 #define OMAP7XX_NON_MPUIO_GPIO_VALID	((OMAP7XX_GPIO_BANK_CNT - 1) *\
 						OMAP7XX_GPIO_WIDTH)
+#define OMAP7XX_GPIO_IRQENA_MASK	0xffffffff
 
 static u16 reg_map[] = {
 	[DATAIN]		= 0x00,
@@ -307,12 +308,31 @@ static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
 	return 0;
 }
 
+static u32 gpio_is_irqena(void __iomem *base)
+{
+	return (~gpio_read(base, IRQENABLE1)) & OMAP7XX_GPIO_IRQENA_MASK;
+}
+
+static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
+{
+	u32 l = gpio_read(base, IRQENABLE1);
+
+	if (enable)
+		l &= ~(gpio_mask);
+	else
+		l |= gpio_mask;
+
+	gpio_write(l, base, IRQENABLE1);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
 	.gpio_set_trigger = gpio_set_trigger,
+	.gpio_is_irqena = gpio_is_irqena,
+	.gpio_enable_irq = gpio_enable_irq,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index ff3ea7b..25fe8a4 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -26,6 +26,7 @@
 #include <plat/omap_device.h>
 
 #define OMAP2_GPIO_INDEX_MASK		0x1f
+#define OMAP2_GPIO_IRQENA_MASK		0xffffffff
 
 int bank_width;
 static u16 *reg_map;
@@ -147,12 +148,37 @@ static int gpio_set_trigger(void __iomem *base, int gpio, int trigger)
 	return 0;
 }
 
+static u32 gpio_is_irqena(void __iomem *base)
+{
+	if (cpu_is_omap44xx())
+		return gpio_read(base, IRQSTATUSSET0) & OMAP2_GPIO_IRQENA_MASK;
+	else
+		return gpio_read(base, IRQENABLE1) & OMAP2_GPIO_IRQENA_MASK;
+}
+
+static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
+{
+	if (cpu_is_omap44xx()) {
+		if (enable)
+			return gpio_write(gpio_mask, base, IRQSTATUSSET0);
+		else
+			return gpio_write(gpio_mask, base, IRQSTATUSCLR0);
+	} else {
+		if (enable)
+			return gpio_write(gpio_mask, base, SETIRQENA1);
+		else
+			return gpio_write(gpio_mask, base, CLEARIRQENA1);
+	}
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
 	.gpio_read = gpio_read,
 	.gpio_write = gpio_write,
 	.gpio_set_trigger = gpio_set_trigger,
+	.gpio_is_irqena = gpio_is_irqena,
+	.gpio_enable_irq = gpio_enable_irq,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 938cc4d..115916d 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -30,6 +30,7 @@
 #include <mach/gpio.h>
 #include <asm/mach/irq.h>
 
+#define	MPUIO_GPIO_IRQENA_MASK	0xffff
 /*
  * OMAP1510 GPIO registers
  */
@@ -551,58 +552,31 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 
 static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 {
-	void __iomem *reg = bank->base;
-
 	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 		/* MPUIO irqstatus is reset by reading the status register,
 		 * so do nothing here */
-		return;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_STATUS;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_IRQSTATUS1;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_STATUS;
 		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+
 	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_IRQSTATUS1;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
 	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_IRQSTATUS0;
-		break;
-#endif
+		/* WA for clearing DSP GPIO interrupts to allow retention */
+		gpio_fn.gpio_write(gpio_mask, bank->base, IRQSTATUS_REG1);
+		/*
+		 * Flush posted write for the irq status
+		 * to avoid spurious interrupts
+		 */
+		gpio_fn.gpio_read(bank->base, IRQSTATUS_REG1);
 	default:
-		WARN_ON(1);
-		return;
-	}
-	__raw_writel(gpio_mask, reg);
-
-	/* Workaround for clearing DSP GPIO interrupts to allow retention */
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
-	else if (cpu_is_omap44xx())
-		reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
-
-	if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		__raw_writel(gpio_mask, reg);
-
-	/* Flush posted write for the irq status to avoid spurious interrupts */
-	__raw_readl(reg);
+		gpio_fn.gpio_write(gpio_mask, bank->base, IRQSTATUS_REG0);
+		/*
+		 * Flush posted write for the irq status
+		 * to avoid spurious interrupts
+		 */
+		gpio_fn.gpio_read(bank->base, IRQSTATUS_REG0);
+		break;
 	}
+	return;
 }
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -612,131 +586,30 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
 
 static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 {
-	void __iomem *reg = bank->base;
-	int inv = 0;
-	u32 l;
-	u32 mask;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-		mask = 0xffff;
-		inv = 1;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_MASK;
-		mask = 0xffff;
-		inv = 1;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_IRQENABLE1;
-		mask = 0xffff;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_MASK;
-		mask = 0xffffffff;
-		inv = 1;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_IRQENABLE1;
-		mask = 0xffffffff;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_IRQSTATUSSET0;
-		mask = 0xffffffff;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return 0;
+	if (bank->method == METHOD_MPUIO) {
+		u32 offset = OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+		return (~gpio_mpuio_read(bank->base, offset))
+						& MPUIO_GPIO_IRQENA_MASK;
 	}
 
-	l = __raw_readl(reg);
-	if (inv)
-		l = ~l;
-	l &= mask;
-	return l;
+	return gpio_fn.gpio_is_irqena(bank->base);
 }
 
 static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
 {
-	void __iomem *reg = bank->base;
-	u32 l;
+	if (bank->method == METHOD_MPUIO) {
+		u32 offset = OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+		u32 l = gpio_mpuio_read(bank->base, offset);
 
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_IRQENABLE1;
-		else
-			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
-		l = gpio_mask;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_MASK;
-		l = __raw_readl(reg);
 		if (enable)
 			l &= ~(gpio_mask);
 		else
 			l |= gpio_mask;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		if (enable)
-			reg += OMAP24XX_GPIO_SETIRQENABLE1;
-		else
-			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
-		l = gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		if (enable)
-			reg += OMAP4_GPIO_IRQSTATUSSET0;
-		else
-			reg += OMAP4_GPIO_IRQSTATUSCLR0;
-		l = gpio_mask;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
+
+		gpio_mpuio_write(l, bank->base, offset);
+	} else {
+		gpio_fn.gpio_enable_irq(bank->base, gpio_mask, enable);
 	}
-	__raw_writel(l, reg);
 }
 
 static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
@@ -1468,6 +1341,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_fn.gpio_read = pdata->gpio_fn->gpio_read;
 		gpio_fn.gpio_write = pdata->gpio_fn->gpio_write;
 		gpio_fn.gpio_set_trigger = pdata->gpio_fn->gpio_set_trigger;
+		gpio_fn.gpio_is_irqena = pdata->gpio_fn->gpio_is_irqena;
+		gpio_fn.gpio_enable_irq = pdata->gpio_fn->gpio_enable_irq;
 	}
 
 	id = pdev->id;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index b7c10bd..c21f2e9 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -114,6 +114,8 @@ struct omap_gpio_func {
 	u32 (*gpio_read)(void __iomem *base, int reg);
 	void (*gpio_write)(u32 val, void __iomem *base, int reg);
 	int (*gpio_set_trigger)(void __iomem *base, int gpio, int trigger);
+	u32 (*gpio_is_irqena)(void __iomem *base);
+	void (*gpio_enable_irq)(void __iomem *base, int gpio_mask, int enable);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 08/18] OMAP: GPIO: req/free: Remove reg offset macros usage
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (6 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 07/18] OMAP: GPIO: cleanup set/get IRQ, clr irqstatus funcs Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 09/18] OMAP: GPIO: cleanup gpio_irq_handler Charulatha V
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the usage of register offset macros from
gpio_request/free() APIs.

Instead use the enum omap_gpio_reg_offsets and SoC specific
gpio_read/write functions to access the GPIO registers.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |   65 +++++++++++++-------------------------------
 1 files changed, 19 insertions(+), 46 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 115916d..28f58c6 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -700,28 +700,17 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 	 */
 	_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
 
-#ifdef CONFIG_ARCH_OMAP15XX
 	if (bank->method == METHOD_GPIO_1510) {
-		void __iomem *reg;
-
 		/* Claim the pin for MPU */
-		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
-		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
+		u32 ctrl = gpio_fn.gpio_read(bank->base, CTRL);
+		gpio_fn.gpio_write(ctrl | (1 << offset), bank->base, CTRL);
 	}
-#endif
-	if (!cpu_class_is_omap1()) {
+
+	if (bank->method >= METHOD_GPIO_24XX) {
 		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);
+			u32 ctrl = gpio_fn.gpio_read(bank->base, CTRL);
 			/* Module is enabled, clocks are not gated */
-			ctrl &= 0xFFFFFFFE;
-			__raw_writel(ctrl, reg);
+			gpio_fn.gpio_write(ctrl & ~0x1, bank->base, CTRL);
 		}
 		bank->mod_usage |= 1 << offset;
 	}
@@ -736,43 +725,27 @@ 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) {
+
+	if ((bank->method == METHOD_GPIO_1610) ||
+			(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) {
+		gpio_fn.gpio_write(1 << offset, bank->base, CLEARWKUENA);
+	} else if (bank->method == METHOD_GPIO_44XX) {
 		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
-		__raw_writel(1 << offset, reg);
+		gpio_fn.gpio_write(1 << offset, bank->base, IRQWAKEN0);
 	}
-#endif
-	if (!cpu_class_is_omap1()) {
+
+
+	if (bank->method >= METHOD_GPIO_24XX) {
 		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);
+			u32 ctrl = gpio_fn.gpio_read(bank->base, CTRL);
 			/* Module is disabled, clocks are gated */
-			ctrl |= 1;
-			__raw_writel(ctrl, reg);
+			gpio_fn.gpio_write(ctrl | 1, bank->base, CTRL);
 		}
 	}
+
 	_reset_gpio(bank, bank->chip.base + offset);
 	spin_unlock_irqrestore(&bank->lock, flags);
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 09/18] OMAP: GPIO: cleanup gpio_irq_handler
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (7 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 08/18] OMAP: GPIO: req/free: Remove reg offset macros usage Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 10/18] OMAP: GPIO: cleanup set wakeup/suspend/resume funcs Charulatha V
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Remove CONFIG_ARCH_OMAP* checks from gpio_irq_handler.

Also correct the multi-line comment style in the
gpio_irq_handler.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |   70 +++++++++++++++++---------------------------
 1 files changed, 27 insertions(+), 43 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 28f58c6..5fe6dbf 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -761,7 +761,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
  */
 static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-	void __iomem *isr_reg = NULL;
+	u32 isr_val;
 	u32 isr;
 	unsigned int gpio_irq, gpio_index;
 	struct gpio_bank *bank;
@@ -771,58 +771,41 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	desc->irq_data.chip->irq_ack(&desc->irq_data);
 
 	bank = irq_get_handler_data(irq);
-#ifdef CONFIG_ARCH_OMAP1
-	if (bank->method == METHOD_MPUIO)
-		isr_reg = bank->base +
-				OMAP_MPUIO_GPIO_INT / bank->stride;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	if (bank->method == METHOD_GPIO_1510)
-		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (bank->method == METHOD_GPIO_1610)
-		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	if (bank->method == METHOD_GPIO_7XX)
-		isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	if (bank->method == METHOD_GPIO_24XX)
-		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-	if (bank->method == METHOD_GPIO_44XX)
-		isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
-#endif
-
-	if (WARN_ON(!isr_reg))
-		goto exit;
 
 	while(1) {
 		u32 isr_saved, level_mask = 0;
 		u32 enabled;
 
+		if (bank->method == METHOD_MPUIO)
+			isr_val = gpio_mpuio_read(bank->base,
+					OMAP_MPUIO_GPIO_INT / bank->stride);
+		else
+			isr_val = gpio_fn.gpio_read(bank->base, IRQSTATUS_REG0);
+
 		enabled = _get_gpio_irqbank_mask(bank);
-		isr_saved = isr = __raw_readl(isr_reg) & enabled;
+		isr = isr_val & enabled;
+		isr_saved = isr;
 
-		if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
+		/* Common for all MPUIO banks */
+		if (bank->method == METHOD_MPUIO)
 			isr &= 0x0000ffff;
 
-		if (cpu_class_is_omap2()) {
+		if (bank->method >= METHOD_GPIO_24XX)
 			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
-		executing them */
+		/*
+		 * clear edge sensitive interrupts before handler(s) are
+		 * called so that we don't miss any interrupt occurred
+		 * while executing them
+		 */
 		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
 		_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
 		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
 
-		/* if there is only edge sensitive GPIO pin interrupts
-		configured, we could unmask GPIO bank interrupt immediately */
+		/*
+		 * if there is only edge sensitive GPIO pin interrupts
+		 * configured, we could unmask GPIO bank interrupt immediately
+		 */
 		if (!level_mask && !unmasked) {
 			unmasked = 1;
 			desc->irq_data.chip->irq_unmask(&desc->irq_data);
@@ -853,11 +836,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 			generic_handle_irq(gpio_irq);
 		}
 	}
-	/* if bank has any level sensitive GPIO pin interrupt
-	configured, we must unmask the bank interrupt only after
-	handler(s) are executed in order to avoid spurious bank
-	interrupt */
-exit:
+	/*
+	 * if bank has any level sensitive GPIO pin interrupt
+	 * configured, we must unmask the bank interrupt only after
+	 * handler(s) are executed in order to avoid spurious bank
+	 * interrupt
+	 */
 	if (!unmasked)
 		desc->irq_data.chip->irq_unmask(&desc->irq_data);
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 10/18] OMAP: GPIO: cleanup set wakeup/suspend/resume funcs
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (8 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 09/18] OMAP: GPIO: cleanup gpio_irq_handler Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count Charulatha V
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid the usage of cpu_is* checks and CONFIG_ARCH_OMAP* checks
from _set_gpio_wakeup and gpio suspend/resume functions.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |  109 ++++++++++++++-------------------------------
 1 files changed, 33 insertions(+), 76 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 5fe6dbf..df2414d 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -30,6 +30,7 @@
 #include <mach/gpio.h>
 #include <asm/mach/irq.h>
 
+#define OMAP_GPIO_WAKE_SET_CLR_ALL	0xffffffff
 #define	MPUIO_GPIO_IRQENA_MASK	0xffff
 /*
  * OMAP1510 GPIO registers
@@ -140,10 +141,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;
 
@@ -630,18 +629,6 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 	unsigned long uninitialized_var(flags);
 
 	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_MPUIO:
-	case METHOD_GPIO_1610:
-		spin_lock_irqsave(&bank->lock, flags);
-		if (enable)
-			bank->suspend_wakeup |= (1 << gpio);
-		else
-			bank->suspend_wakeup &= ~(1 << gpio);
-		spin_unlock_irqrestore(&bank->lock, flags);
-		return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_44XX:
 		if (bank->non_wakeup_gpios & (1 << gpio)) {
@@ -650,6 +637,8 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 					(bank - gpio_bank) * 32 + gpio);
 			return -EINVAL;
 		}
+	case METHOD_MPUIO:
+	case METHOD_GPIO_1610:
 		spin_lock_irqsave(&bank->lock, flags);
 		if (enable)
 			bank->suspend_wakeup |= (1 << gpio);
@@ -657,7 +646,6 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 			bank->suspend_wakeup &= ~(1 << gpio);
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
-#endif
 	default:
 		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
 		       bank->method);
@@ -1347,51 +1335,35 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 {
 	int i;
 
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return 0;
-
 	for (i = 0; i < gpio_bank_count; i++) {
 		struct gpio_bank *bank = &gpio_bank[i];
-		void __iomem *wake_status;
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
+		u32 wake_status;
+		u32 wake_clear;
+		u32 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;
+		if ((bank->method <= METHOD_GPIO_1510) ||
+				(bank->method == METHOD_GPIO_7XX)) {
 			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;
+		} else if (bank->method == METHOD_GPIO_44XX) {
+			wake_status = IRQWAKEN0;
+			wake_clear = IRQWAKEN0;
+			wake_set = IRQWAKEN0;
+		} else {
+			wake_status = WAKE_EN;
+			wake_clear = CLEARWKUENA;
+			wake_set = SETWKUENA;
 		}
 
 		spin_lock_irqsave(&bank->lock, flags);
-		bank->saved_wakeup = __raw_readl(wake_status);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->suspend_wakeup, wake_set);
+		bank->saved_wakeup = gpio_fn.gpio_read(bank->base, wake_status);
+		gpio_fn.gpio_write(OMAP_GPIO_WAKE_SET_CLR_ALL, bank->base,
+					wake_clear);
+		gpio_fn.gpio_write(bank->suspend_wakeup, bank->base, wake_set);
 		spin_unlock_irqrestore(&bank->lock, flags);
 	}
 
@@ -1402,41 +1374,27 @@ static int omap_gpio_resume(struct sys_device *dev)
 {
 	int i;
 
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return 0;
-
 	for (i = 0; i < gpio_bank_count; i++) {
 		struct gpio_bank *bank = &gpio_bank[i];
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
+		u32 wake_clear;
+		u32 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;
+		if ((bank->method <= METHOD_GPIO_1510) ||
+				(bank->method == METHOD_GPIO_7XX)) {
 			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;
+		} else if (bank->method == METHOD_GPIO_44XX) {
+			wake_clear = IRQWAKEN0;
+			wake_set = IRQWAKEN0;
+		} else {
+			wake_clear = CLEARWKUENA;
+			wake_set = SETWKUENA;
 		}
 
 		spin_lock_irqsave(&bank->lock, flags);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->saved_wakeup, wake_set);
+		gpio_fn.gpio_write(OMAP_GPIO_WAKE_SET_CLR_ALL, bank->base,
+					wake_clear);
+		gpio_fn.gpio_write(bank->saved_wakeup, bank->base, wake_set);
 		spin_unlock_irqrestore(&bank->lock, flags);
 	}
 
@@ -1454,7 +1412,6 @@ static struct sys_device omap_gpio_device = {
 	.cls		= &omap_gpio_sysclass,
 };
 
-#endif
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (9 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 10/18] OMAP: GPIO: cleanup set wakeup/suspend/resume funcs Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 16:04   ` Kevin Hilman
  2011-04-22 11:08 ` [RFC PATCH 12/18] OMAP: GPIO: cleanup set_debounce, idle/resume_after_idle Charulatha V
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

gpio_bank_count is the count of number of GPIO devices
in a SoC. Remove this dependency from the driver. Also remove
the dependency on array of pointers to gpio_bank struct of
all GPIO devices.

The cpu_is*() checks used in omap2_gpio_prepare_for_idle() and
omap2_gpio_resume_after_idle() would be removed in one of the
patches in this series

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |    1 -
 arch/arm/mach-omap1/gpio16xx.c         |    2 -
 arch/arm/mach-omap1/gpio7xx.c          |    2 -
 arch/arm/mach-omap2/gpio.c             |    1 +
 arch/arm/plat-omap/gpio.c              |  165 ++++++++++++++++----------------
 arch/arm/plat-omap/include/plat/gpio.h |    3 -
 6 files changed, 83 insertions(+), 91 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 7a7a123..3763db3 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -189,7 +189,6 @@ static int __init omap15xx_gpio_init(void)
 	omap15xx_mpu_gpio_config.gpio_fn = &gpio_fn;
 	platform_device_register(&omap15xx_gpio);
 
-	gpio_bank_count = 2;
 	return 0;
 }
 postcore_initcall(omap15xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index f05e0c7..6a99b01 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -316,8 +316,6 @@ static int __init omap16xx_gpio_init(void)
 		platform_device_register(omap16xx_gpio_dev[i]);
 	}
 
-	gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
-
 	return 0;
 }
 postcore_initcall(omap16xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 1103efc..cd6bad7 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -355,8 +355,6 @@ static int __init omap7xx_gpio_init(void)
 		platform_device_register(omap7xx_gpio_dev[i]);
 	}
 
-	gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
-
 	return 0;
 }
 postcore_initcall(omap7xx_gpio_init);
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 25fe8a4..a46f4a5 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -28,6 +28,7 @@
 #define OMAP2_GPIO_INDEX_MASK		0x1f
 #define OMAP2_GPIO_IRQENA_MASK		0xffffffff
 
+int gpio_bank_count;
 int bank_width;
 static u16 *reg_map;
 static u16 omap2_gpio_reg_offsets[] = {
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index df2414d..f2cd2dd 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -14,6 +14,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -135,7 +136,10 @@
 #define OMAP4_GPIO_CLEARDATAOUT		0x0190
 #define OMAP4_GPIO_SETDATAOUT		0x0194
 
+static LIST_HEAD(omap_gpio_list);
+
 struct gpio_bank {
+	struct list_head node;
 	unsigned long pbase;
 	void __iomem *base;
 	u16 irq;
@@ -145,7 +149,7 @@ struct gpio_bank {
 	u32 saved_wakeup;
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
-
+	u16 id;
 	u32 saved_datain;
 	u32 saved_fallingdetect;
 	u32 saved_risingdetect;
@@ -178,18 +182,10 @@ struct omap3_gpio_regs {
 static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
 #endif
 
-/*
- * TODO: Cleanup gpio_bank usage as it is having information
- * related to all instances of the device
- */
-static struct gpio_bank *gpio_bank;
 static struct omap_gpio_func gpio_fn;
 
 static int bank_width;
 
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-int gpio_bank_count;
-
 static int check_gpio(int gpio)
 {
 	if (unlikely(gpio_fn.gpio_valid(gpio) < 0)) {
@@ -634,7 +630,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 		if (bank->non_wakeup_gpios & (1 << gpio)) {
 			printk(KERN_ERR "Unable to modify wakeup on "
 					"non-wakeup GPIO%d\n",
-					(bank - gpio_bank) * 32 + gpio);
+					bank->id * 32 + gpio);
 			return -EINVAL;
 		}
 	case METHOD_MPUIO:
@@ -991,17 +987,23 @@ static struct platform_device omap_mpuio_device = {
 	/* could list the /proc/iomem resources */
 };
 
-static inline void mpuio_init(void)
+static inline void mpuio_init(struct gpio_bank *bank)
 {
-	struct gpio_bank *bank = &gpio_bank[0];
+	static int mpuio_init_done;
+
+	if (mpuio_init_done || (bank->method != METHOD_MPUIO))
+		return;
+
 	platform_set_drvdata(&omap_mpuio_device, bank);
 
-	if (platform_driver_register(&omap_mpuio_driver) == 0)
-		(void) platform_device_register(&omap_mpuio_device);
+	if (!platform_driver_register(&omap_mpuio_driver))
+		platform_device_register(&omap_mpuio_device);
+
+	mpuio_init_done = 1;
 }
 
 #else
-static inline void mpuio_init(void) {}
+static inline void mpuio_init(struct gpio_bank *bank) {}
 #endif	/* 16xx */
 
 #else
@@ -1009,7 +1011,7 @@ static inline void mpuio_init(void) {}
 extern struct irq_chip mpuio_irq_chip;
 
 #define bank_is_mpuio(bank)	0
-static inline void mpuio_init(void) {}
+static inline void mpuio_init(struct gpio_bank *bank) {}
 
 #endif
 
@@ -1137,18 +1139,6 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
  */
 static struct lock_class_key gpio_lock_class;
 
-static inline int init_gpio_info(struct platform_device *pdev)
-{
-	/* TODO: Analyze removing gpio_bank_count usage from driver code */
-	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
-				GFP_KERNEL);
-	if (!gpio_bank) {
-		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
 /* TODO: Cleanup cpu_is_* checks */
 static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
 {
@@ -1264,83 +1254,83 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	static int gpio_init_done;
 	struct omap_gpio_platform_data *pdata;
 	struct resource *res;
-	int id;
 	struct gpio_bank *bank;
 
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
-	pdata = pdev->dev.platform_data;
-
-	if (!gpio_init_done) {
-		int ret;
-
-		ret = init_gpio_info(pdev);
-		if (ret)
-			return ret;
-		if (cpu_class_is_omap1())
-			mpuio_init();
-
-		gpio_fn.get_index = pdata->gpio_fn->get_index;
-		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
-		gpio_fn.gpio_read = pdata->gpio_fn->gpio_read;
-		gpio_fn.gpio_write = pdata->gpio_fn->gpio_write;
-		gpio_fn.gpio_set_trigger = pdata->gpio_fn->gpio_set_trigger;
-		gpio_fn.gpio_is_irqena = pdata->gpio_fn->gpio_is_irqena;
-		gpio_fn.gpio_enable_irq = pdata->gpio_fn->gpio_enable_irq;
+	bank = kzalloc(sizeof(struct gpio_bank), GFP_KERNEL);
+	if (!bank) {
+		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+		return -ENOMEM;
 	}
 
-	id = pdev->id;
-	bank = &gpio_bank[id];
-
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n",
+				pdev->id);
 		return -ENODEV;
 	}
 
 	bank->irq = res->start;
+
+	pdata = pdev->dev.platform_data;
 	bank->virtual_irq_start = pdata->virtual_irq_start;
+
+	bank->id = pdev->id;
 	bank->method = pdata->bank_type;
 	bank->dev = &pdev->dev;
 	bank->dbck_flag = pdata->dbck_flag;
 	bank->stride = pdata->bank_stride;
 	bank_width = pdata->bank_width;
 
+	if (!gpio_init_done) {
+		if (cpu_class_is_omap1())
+			mpuio_init(bank);
+	}
+
 	spin_lock_init(&bank->lock);
 
 	/* Static mapping, never released */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n",
+				bank->id);
 		return -ENODEV;
 	}
 
 	bank->base = ioremap(res->start, resource_size(res));
 	if (!bank->base) {
-		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
+		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n",
+				bank->id);
 		return -ENOMEM;
 	}
 
 	pm_runtime_enable(bank->dev);
 	pm_runtime_get_sync(bank->dev);
 
-	omap_gpio_mod_init(bank, id);
+	omap_gpio_mod_init(bank, pdev->id);
 	omap_gpio_chip_init(bank);
 	omap_gpio_show_rev(bank);
 
-	if (!gpio_init_done)
+	list_add_tail(&bank->node, &omap_gpio_list);
+
+	if (!gpio_init_done) {
+		gpio_fn.get_index = pdata->gpio_fn->get_index;
+		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
+		gpio_fn.gpio_read = pdata->gpio_fn->gpio_read;
+		gpio_fn.gpio_write = pdata->gpio_fn->gpio_write;
+		gpio_fn.gpio_set_trigger = pdata->gpio_fn->gpio_set_trigger;
+		gpio_fn.gpio_is_irqena = pdata->gpio_fn->gpio_is_irqena;
+		gpio_fn.gpio_enable_irq = pdata->gpio_fn->gpio_enable_irq;
 		gpio_init_done = 1;
+	}
 
 	return 0;
 }
 
 static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 {
-	int i;
+	struct gpio_bank *bank;
 
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 wake_status;
 		u32 wake_clear;
 		u32 wake_set;
@@ -1372,10 +1362,9 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 
 static int omap_gpio_resume(struct sys_device *dev)
 {
-	int i;
+	struct gpio_bank *bank;
 
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 wake_clear;
 		u32 wake_set;
 		unsigned long flags;
@@ -1419,17 +1408,17 @@ static int workaround_enabled;
 
 void omap2_gpio_prepare_for_idle(int off_mode)
 {
-	int i, c = 0;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
+	int c = 0;
+	struct gpio_bank *bank;
 
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 l1 = 0, l2 = 0;
 		int j;
 
+		/* TODO: Do not use cpu_is_omap34xx */
+		if ((cpu_is_omap34xx()) && (bank->id == 0))
+			continue;
+
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_disable(bank->dbck);
 
@@ -1488,16 +1477,16 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 
 void omap2_gpio_resume_after_idle(void)
 {
-	int i;
-	int min = 0;
+	struct gpio_bank *bank;
 
-	if (cpu_is_omap34xx())
-		min = 1;
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 l = 0, gen, gen0, gen1;
 		int j;
 
+		/* TODO: Do not use cpu_is_omap34xx */
+		if ((cpu_is_omap34xx()) && (bank->id == 0))
+			continue;
+
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_enable(bank->dbck);
 
@@ -1589,11 +1578,16 @@ void omap2_gpio_resume_after_idle(void)
 /* save the registers of bank 2-6 */
 void omap_gpio_save_context(void)
 {
-	int i;
+	struct gpio_bank *bank;
+	int i = 0;
 
 	/* saving banks from 2-6 only since GPIO1 is in WKUP */
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		i++;
+
+		if (bank->id == 0)
+			continue;
+
 		gpio_context[i].irqenable1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		gpio_context[i].irqenable2 =
@@ -1620,10 +1614,15 @@ void omap_gpio_save_context(void)
 /* restore the required registers of bank 2-6 */
 void omap_gpio_restore_context(void)
 {
-	int i;
+	struct gpio_bank *bank;
+	int i = 0;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		i++;
+
+		if (bank->id == 0)
+			continue;
 
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
 		__raw_writel(gpio_context[i].irqenable1,
 				bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		__raw_writel(gpio_context[i].irqenable2,
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index c21f2e9..331ee4c 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -127,9 +127,6 @@ struct omap_gpio_platform_data {
 	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
 };
 
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-extern int gpio_bank_count;
-
 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);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 12/18] OMAP: GPIO: cleanup set_debounce, idle/resume_after_idle
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (10 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 13/18] OMAP: GPIO: cleanup save/restore context Charulatha V
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

gpio_set_debounce(), gpio_prepare_for_idle() and gpio_resume_after_idle()
are specific to OMAP2PLUS CPUs. These functions rely on "dbck_enable_mask"
which is part of GPIO bank structure.

The above mentioned functions are moved to mach-omap2/gpio.c and the
required information is passed from the OMAP GPIO driver.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap2/gpio.c             |  201 ++++++++++++++++++++++++++++-
 arch/arm/plat-omap/gpio.c              |  223 +++-----------------------------
 arch/arm/plat-omap/include/plat/gpio.h |    6 +
 3 files changed, 222 insertions(+), 208 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index a46f4a5..a0edaeb 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -21,13 +21,31 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
+#include <linux/clk.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
 #define OMAP2_GPIO_INDEX_MASK		0x1f
 #define OMAP2_GPIO_IRQENA_MASK		0xffffffff
+#define OMAP2_GPIO_DEBOUNCE_MIN_CHK	32
+#define OMAP2_GPIO_DEBOUNCE_MAX_CHK	7936
+#define OMAP2_GPIO_DEBOUNCE_MIN_VAL	0x01
+#define OMAP2_GPIO_DEBOUNCE_MAX_VAL	0xff
+#define OMAP2_GPIO_DEBOUNCE_VAL_DIV	0x1f
 
+struct gpio_state {
+	struct list_head node;
+	u32 saved_datain;
+	u32 saved_fallingdetect;
+	u32 saved_risingdetect;
+	u32 dbck_enable_mask;
+	struct clk *dbck;
+	u16 id;
+};
+
+static int workaround_enabled;
+static LIST_HEAD(omap_gpio_ctx_list);
 int gpio_bank_count;
 int bank_width;
 static u16 *reg_map;
@@ -172,6 +190,161 @@ static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
 	}
 }
 
+static void gpio_debounce_set(void __iomem *base, unsigned gpio,
+		unsigned debounce, u16 id)
+{
+	u32 val;
+	u32 l = 0;
+	struct gpio_state *gpio_dev_state;
+
+	if (debounce < OMAP2_GPIO_DEBOUNCE_MIN_CHK)
+		debounce = OMAP2_GPIO_DEBOUNCE_MIN_VAL;
+	else if (debounce > OMAP2_GPIO_DEBOUNCE_MAX_CHK)
+		debounce = OMAP2_GPIO_DEBOUNCE_MAX_VAL;
+	else
+		debounce = (debounce / OMAP2_GPIO_DEBOUNCE_VAL_DIV) - 1;
+
+	gpio_write(debounce, base, DEBOUNCE_VAL);
+
+	val = gpio_read(base, DEBOUNCE_EN);
+	l = 1 << get_gpio_index(gpio);
+
+	list_for_each_entry(gpio_dev_state, &omap_gpio_ctx_list, node) {
+		if (gpio_dev_state->id == id) {
+			if (debounce) {
+				val |= l;
+				clk_enable(gpio_dev_state->dbck);
+			} else {
+				val &= ~l;
+				clk_disable(gpio_dev_state->dbck);
+			}
+			gpio_dev_state->dbck_enable_mask = val;
+			gpio_write(val, base, DEBOUNCE_EN);
+		}
+	}
+}
+
+static void gpio_prepare_for_idle(u32 enabled_non_wakeup_gpios, u16 id,
+		void __iomem *base, int off_mode)
+{
+	int c = 0;
+	struct gpio_state *gpio_dev_state;
+
+	list_for_each_entry(gpio_dev_state, &omap_gpio_ctx_list, node) {
+		u32 l1 = 0, l2 = 0;
+		int j;
+
+		if (!gpio_dev_state->id == id)
+			continue;
+
+		if ((cpu_is_omap34xx()) && (id == 0))
+			continue;
+
+		for (j = 0; j < hweight_long(gpio_dev_state->dbck_enable_mask);
+				j++)
+			clk_disable(gpio_dev_state->dbck);
+
+		if (!off_mode)
+			continue;
+
+		/*
+		 * If going to OFF, remove triggering for all
+		 * non-wakeup GPIOs.  Otherwise spurious IRQs will be
+		 * generated.  See OMAP2420 Errata item 1.101.
+		 */
+		if (!enabled_non_wakeup_gpios)
+			continue;
+
+		gpio_dev_state->saved_datain = gpio_read(base, DATAIN);
+		l1 = gpio_read(base, FALLINGDETECT);
+		l2 = gpio_read(base, RISINGDETECT);
+
+		gpio_dev_state->saved_fallingdetect = l1;
+		gpio_dev_state->saved_risingdetect = l2;
+		l1 &= ~enabled_non_wakeup_gpios;
+		l2 &= ~enabled_non_wakeup_gpios;
+
+		gpio_write(l1, base, FALLINGDETECT);
+		gpio_write(l2, base, RISINGDETECT);
+
+		c++;
+	}
+	if (!c) {
+		workaround_enabled = 0;
+		return;
+	}
+	workaround_enabled = 1;
+}
+
+static void gpio_resume_after_idle(u32 enabled_non_wakeup_gpios, u16 id,
+		void __iomem *base)
+{
+	struct gpio_state *gpio_dev_state;
+
+	list_for_each_entry(gpio_dev_state, &omap_gpio_ctx_list, node) {
+		u32 l = 0, gen, gen0, gen1;
+		int j;
+
+		if (!gpio_dev_state->id == id)
+			continue;
+
+		if ((cpu_is_omap34xx()) && (id == 0))
+			continue;
+
+		for (j = 0; j < hweight_long(gpio_dev_state->dbck_enable_mask);
+				j++)
+			clk_enable(gpio_dev_state->dbck);
+
+		if (!workaround_enabled)
+			continue;
+
+		if (!enabled_non_wakeup_gpios)
+			continue;
+
+		gpio_write(gpio_dev_state->saved_fallingdetect, base,
+				FALLINGDETECT);
+		gpio_write(gpio_dev_state->saved_risingdetect, base,
+				RISINGDETECT);
+
+		l = gpio_read(base, DATAIN);
+		/*
+		 * Check if any of the non-wakeup interrupt GPIOs have changed
+		 * state.  If so, generate an IRQ by software.  This is
+		 * horribly racy, but it's the best we can do to work around
+		 * this silicon bug.
+		 */
+		l ^= gpio_dev_state->saved_datain;
+		l &= enabled_non_wakeup_gpios;
+
+		/*
+		 * No need to generate IRQs for the rising edge for gpio IRQs
+		 * configured with falling edge only; and vice versa.
+		 */
+		gen0 = l & gpio_dev_state->saved_fallingdetect;
+		gen0 &= gpio_dev_state->saved_datain;
+
+		gen1 = l & gpio_dev_state->saved_risingdetect;
+		gen1 &= ~(gpio_dev_state->saved_datain);
+
+		/* FIXME: Consider GPIO IRQs with level detections properly! */
+		gen = l & (~(gpio_dev_state->saved_fallingdetect) &
+				~(gpio_dev_state->saved_risingdetect));
+		/* Consider all GPIO IRQs needed to be updated */
+		gen |= gen0 | gen1;
+
+		if (gen) {
+			u32 old0, old1;
+
+			old0 = gpio_read(base, LEVELDETECT0);
+			old1 = gpio_read(base, LEVELDETECT1);
+			gpio_write(old0 | gen, base, LEVELDETECT0);
+			gpio_write(old1 | gen, base, LEVELDETECT1);
+			gpio_write(old0, base, LEVELDETECT0);
+			gpio_write(old1, base, LEVELDETECT1);
+		}
+	}
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -180,6 +353,9 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_set_trigger = gpio_set_trigger,
 	.gpio_is_irqena = gpio_is_irqena,
 	.gpio_enable_irq = gpio_enable_irq,
+	.gpio_debounce_set = gpio_debounce_set,
+	.gpio_idle = gpio_prepare_for_idle,
+	.gpio_resume_after_idle = gpio_resume_after_idle,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
@@ -189,6 +365,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 gpio_state *gpio_dev_state;
 
 	/*
 	 * extract the device id from name field available in the
@@ -229,19 +406,39 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 		return -EINVAL;
 	}
 
+	gpio_dev_state = kzalloc(sizeof(struct gpio_state), GFP_KERNEL);
+	if (!gpio_dev_state) {
+		pr_err("%s:, Memory alloc failed for gpio_dev_state\n",
+				__func__);
+		kfree(pdata);
+		return -ENOMEM;
+	}
+
+	gpio_dev_state->id = id - 1;
+	list_add_tail(&gpio_dev_state->node, &omap_gpio_ctx_list);
+
 	od = omap_device_build(name, id - 1, oh, pdata,
 				sizeof(*pdata),	omap_gpio_latency,
 				ARRAY_SIZE(omap_gpio_latency),
 				false);
-	kfree(pdata);
-
 	if (IS_ERR(od)) {
 		WARN(1, "Can't build omap_device for %s:%s.\n",
 					name, oh->name);
+		kfree(gpio_dev_state);
+		kfree(pdata);
 		return PTR_ERR(od);
 	}
 
 	gpio_bank_count++;
+	if (pdata->dbck_flag) {
+		gpio_dev_state->dbck = clk_get(&od->pdev.dev, "dbclk");
+		if (IS_ERR(gpio_dev_state->dbck))
+			dev_err(&od->pdev.dev, "Could not get gpio%d dbck\n",
+					id);
+	}
+
+	kfree(pdata);
+
 	return 0;
 }
 
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index f2cd2dd..55115df 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -150,16 +150,11 @@ struct gpio_bank {
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
 	u16 id;
-	u32 saved_datain;
-	u32 saved_fallingdetect;
-	u32 saved_risingdetect;
 	u32 level_mask;
 	u32 toggle_mask;
 	spinlock_t lock;
 	struct gpio_chip chip;
-	struct clk *dbck;
 	u32 mod_usage;
-	u32 dbck_enable_mask;
 	struct device *dev;
 	bool dbck_flag;
 	int stride;
@@ -331,47 +326,12 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
 static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 		unsigned debounce)
 {
-	void __iomem		*reg = bank->base;
-	u32			val;
-	u32			l;
-
 	if (!bank->dbck_flag)
 		return;
 
-	if (debounce < 32)
-		debounce = 0x01;
-	else if (debounce > 7936)
-		debounce = 0xff;
-	else
-		debounce = (debounce / 0x1f) - 1;
-
-	l = 1 << gpio_fn.get_index(gpio);
-
-	if (bank->method == METHOD_GPIO_44XX)
-		reg += OMAP4_GPIO_DEBOUNCINGTIME;
-	else
-		reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
-
-	__raw_writel(debounce, reg);
-
-	reg = bank->base;
-	if (bank->method == METHOD_GPIO_44XX)
-		reg += OMAP4_GPIO_DEBOUNCENABLE;
-	else
-		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
-
-	val = __raw_readl(reg);
-
-	if (debounce) {
-		val |= l;
-		clk_enable(bank->dbck);
-	} else {
-		val &= ~l;
-		clk_disable(bank->dbck);
-	}
-	bank->dbck_enable_mask = val;
-
-	__raw_writel(val, reg);
+	if (!gpio_fn.gpio_debounce_set)
+		gpio_fn.gpio_debounce_set(bank->base, gpio, debounce,
+				bank->id);
 }
 
 /*
@@ -1083,12 +1043,6 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
 
 	bank = container_of(chip, struct gpio_bank, chip);
 
-	if (!bank->dbck) {
-		bank->dbck = clk_get(bank->dev, "dbclk");
-		if (IS_ERR(bank->dbck))
-			dev_err(bank->dev, "Could not get gpio dbck\n");
-	}
-
 	spin_lock_irqsave(&bank->lock, flags);
 	_set_gpio_debounce(bank, offset, debounce);
 	spin_unlock_irqrestore(&bank->lock, flags);
@@ -1320,6 +1274,10 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_fn.gpio_set_trigger = pdata->gpio_fn->gpio_set_trigger;
 		gpio_fn.gpio_is_irqena = pdata->gpio_fn->gpio_is_irqena;
 		gpio_fn.gpio_enable_irq = pdata->gpio_fn->gpio_enable_irq;
+		gpio_fn.gpio_debounce_set = pdata->gpio_fn->gpio_debounce_set;
+		gpio_fn.gpio_idle = pdata->gpio_fn->gpio_idle;
+		gpio_fn.gpio_resume_after_idle =
+			pdata->gpio_fn->gpio_resume_after_idle;
 		gpio_init_done = 1;
 	}
 
@@ -1401,179 +1359,32 @@ static struct sys_device omap_gpio_device = {
 	.cls		= &omap_gpio_sysclass,
 };
 
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
-static int workaround_enabled;
-
 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) {
-		u32 l1 = 0, l2 = 0;
-		int j;
-
-		/* TODO: Do not use cpu_is_omap34xx */
-		if ((cpu_is_omap34xx()) && (bank->id == 0))
-			continue;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_disable(bank->dbck);
-
-		if (!off_mode)
-			continue;
-
-		/* If going to OFF, remove triggering for all
-		 * non-wakeup GPIOs.  Otherwise spurious IRQs will be
-		 * generated.  See OMAP2420 Errata item 1.101. */
-		if (!(bank->enabled_non_wakeup_gpios))
-			continue;
-
-		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_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);
-		}
-
-		c++;
-	}
-	if (!c) {
-		workaround_enabled = 0;
+	if (!gpio_fn.gpio_idle)
 		return;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		gpio_fn.gpio_idle(bank->enabled_non_wakeup_gpios,
+					bank->id, bank->base, off_mode);
 	}
-	workaround_enabled = 1;
 }
 
 void omap2_gpio_resume_after_idle(void)
 {
 	struct gpio_bank *bank;
 
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		u32 l = 0, gen, gen0, gen1;
-		int j;
-
-		/* TODO: Do not use cpu_is_omap34xx */
-		if ((cpu_is_omap34xx()) && (bank->id == 0))
-			continue;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_enable(bank->dbck);
-
-		if (!workaround_enabled)
-			continue;
-
-		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);
-		}
-
-		/* Check if any of the non-wakeup interrupt GPIOs have changed
-		 * state.  If so, generate an IRQ by software.  This is
-		 * horribly racy, but it's the best we can do to work around
-		 * this silicon bug. */
-		l ^= bank->saved_datain;
-		l &= bank->enabled_non_wakeup_gpios;
-
-		/*
-		 * No need to generate IRQs for the rising edge for gpio IRQs
-		 * configured with falling edge only; and vice versa.
-		 */
-		gen0 = l & bank->saved_fallingdetect;
-		gen0 &= bank->saved_datain;
-
-		gen1 = l & bank->saved_risingdetect;
-		gen1 &= ~(bank->saved_datain);
-
-		/* FIXME: Consider GPIO IRQs with level detections properly! */
-		gen = l & (~(bank->saved_fallingdetect) &
-				~(bank->saved_risingdetect));
-		/* Consider all GPIO IRQs needed to be updated */
-		gen |= gen0 | gen1;
-
-		if (gen) {
-			u32 old0, old1;
-
-			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);
-			}
+	if (!gpio_fn.gpio_resume_after_idle)
+		return;
 
-			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);
-			}
-		}
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		gpio_fn.gpio_resume_after_idle(bank->enabled_non_wakeup_gpios,
+					bank->id, bank->base);
 	}
-
 }
 
-#endif
-
 #ifdef CONFIG_ARCH_OMAP3
 /* save the registers of bank 2-6 */
 void omap_gpio_save_context(void)
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 331ee4c..bfd5b6c 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -116,6 +116,12 @@ struct omap_gpio_func {
 	int (*gpio_set_trigger)(void __iomem *base, int gpio, int trigger);
 	u32 (*gpio_is_irqena)(void __iomem *base);
 	void (*gpio_enable_irq)(void __iomem *base, int gpio_mask, int enable);
+	void (*gpio_debounce_set)(void __iomem *base, unsigned gpio,
+			unsigned debounce, u16 id);
+	void (*gpio_idle)(u32 enabled_non_wakeup_gpios, u16 id,
+			void __iomem *base, int offmode);
+	void (*gpio_resume_after_idle)(u32 enabled_non_wakeup_gpios, u16 id,
+			void __iomem *base);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 13/18] OMAP: GPIO: cleanup save/restore context
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (11 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 12/18] OMAP: GPIO: cleanup set_debounce, idle/resume_after_idle Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 14/18] OMAP: GPIO: Remove CONFIG_ARCH_OMAP16XX/OMAP2+ defines Charulatha V
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Move GPIO save/restore context to SoC specific file.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap2/gpio.c             |   78 +++++++++++++++++++++++++++
 arch/arm/plat-omap/gpio.c              |   91 ++++---------------------------
 arch/arm/plat-omap/include/plat/gpio.h |    2 +
 3 files changed, 92 insertions(+), 79 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index a0edaeb..a7bb005 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -34,6 +34,19 @@
 #define OMAP2_GPIO_DEBOUNCE_MAX_VAL	0xff
 #define OMAP2_GPIO_DEBOUNCE_VAL_DIV	0x1f
 
+struct omap_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_state {
 	struct list_head node;
 	u32 saved_datain;
@@ -42,6 +55,7 @@ struct gpio_state {
 	u32 dbck_enable_mask;
 	struct clk *dbck;
 	u16 id;
+	struct omap_gpio_regs gpio_ctx;
 };
 
 static int workaround_enabled;
@@ -345,6 +359,68 @@ static void gpio_resume_after_idle(u32 enabled_non_wakeup_gpios, u16 id,
 	}
 }
 
+static void gpio_save_ctx(void __iomem *base, u32 id)
+{
+	struct gpio_state *gpio_dev_state;
+
+	if (!cpu_is_omap34xx())
+		return;
+
+	list_for_each_entry(gpio_dev_state, &omap_gpio_ctx_list, node) {
+		/* saving banks from 2-6 only since GPIO1 is in WKUP */
+		if ((gpio_dev_state->id == 0) || (gpio_dev_state->id != id))
+			continue;
+
+		gpio_dev_state->gpio_ctx.irqenable1 = gpio_read(base,
+								IRQENABLE1);
+		gpio_dev_state->gpio_ctx.irqenable2 = gpio_read(base,
+								IRQENABLE2);
+		gpio_dev_state->gpio_ctx.wake_en = gpio_read(base, WAKE_EN);
+		gpio_dev_state->gpio_ctx.ctrl = gpio_read(base, CTRL);
+		gpio_dev_state->gpio_ctx.oe = gpio_read(base, OE);
+		gpio_dev_state->gpio_ctx.leveldetect0 = gpio_read(base,
+								LEVELDETECT0);
+		gpio_dev_state->gpio_ctx.leveldetect1 = gpio_read(base,
+								LEVELDETECT1);
+		gpio_dev_state->gpio_ctx.risingdetect = gpio_read(base,
+								RISINGDETECT);
+		gpio_dev_state->gpio_ctx.fallingdetect = gpio_read(base,
+								FALLINGDETECT);
+		gpio_dev_state->gpio_ctx.dataout = gpio_read(base, DATAOUT);
+	}
+}
+
+static void gpio_restore_ctx(void __iomem *base, u32 id)
+{
+	struct gpio_state *gpio_dev_state;
+
+	if (!cpu_is_omap34xx())
+		return;
+
+	list_for_each_entry(gpio_dev_state, &omap_gpio_ctx_list, node) {
+		/* restore the required registers of bank 2-6 */
+		if ((gpio_dev_state->id == 0) || (gpio_dev_state->id != id))
+			continue;
+
+		gpio_write(gpio_dev_state->gpio_ctx.irqenable1, base,
+				IRQENABLE1);
+		gpio_write(gpio_dev_state->gpio_ctx.irqenable2, base,
+				IRQENABLE2);
+		gpio_write(gpio_dev_state->gpio_ctx.wake_en, base, WAKE_EN);
+		gpio_write(gpio_dev_state->gpio_ctx.ctrl, base, CTRL);
+		gpio_write(gpio_dev_state->gpio_ctx.oe, base, OE);
+		gpio_write(gpio_dev_state->gpio_ctx.leveldetect0, base,
+				LEVELDETECT0);
+		gpio_write(gpio_dev_state->gpio_ctx.leveldetect1, base,
+				LEVELDETECT1);
+		gpio_write(gpio_dev_state->gpio_ctx.risingdetect, base,
+				RISINGDETECT);
+		gpio_write(gpio_dev_state->gpio_ctx.fallingdetect, base,
+				FALLINGDETECT);
+		gpio_write(gpio_dev_state->gpio_ctx.dataout, base, DATAOUT);
+	}
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -356,6 +432,8 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_debounce_set = gpio_debounce_set,
 	.gpio_idle = gpio_prepare_for_idle,
 	.gpio_resume_after_idle = gpio_resume_after_idle,
+	.gpio_save_ctx = gpio_save_ctx,
+	.gpio_restore_ctx = gpio_restore_ctx,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 55115df..fd710cd 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -160,25 +160,7 @@ struct gpio_bank {
 	int stride;
 };
 
-#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
-
 static struct omap_gpio_func gpio_fn;
-
 static int bank_width;
 
 static int check_gpio(int gpio)
@@ -1278,6 +1260,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_fn.gpio_idle = pdata->gpio_fn->gpio_idle;
 		gpio_fn.gpio_resume_after_idle =
 			pdata->gpio_fn->gpio_resume_after_idle;
+		gpio_fn.gpio_save_ctx = pdata->gpio_fn->gpio_save_ctx;
+		gpio_fn.gpio_restore_ctx = pdata->gpio_fn->gpio_restore_ctx;
 		gpio_init_done = 1;
 	}
 
@@ -1385,78 +1369,27 @@ void omap2_gpio_resume_after_idle(void)
 	}
 }
 
-#ifdef CONFIG_ARCH_OMAP3
-/* save the registers of bank 2-6 */
 void omap_gpio_save_context(void)
 {
 	struct gpio_bank *bank;
-	int i = 0;
 
-	/* saving banks from 2-6 only since GPIO1 is in WKUP */
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		i++;
-
-		if (bank->id == 0)
-			continue;
-
-		gpio_context[i].irqenable1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		gpio_context[i].irqenable2 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		gpio_context[i].wake_en =
-			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-		gpio_context[i].ctrl =
-			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-		gpio_context[i].oe =
-			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
-		gpio_context[i].leveldetect0 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		gpio_context[i].leveldetect1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		gpio_context[i].risingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		gpio_context[i].fallingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		gpio_context[i].dataout =
-			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
+	if (!gpio_fn.gpio_save_ctx)
+		return;
+
+	list_for_each_entry(bank, &omap_gpio_list, node)
+		gpio_fn.gpio_save_ctx(bank->base, bank->id);
 }
 
-/* restore the required registers of bank 2-6 */
 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->id == 0)
-			continue;
-
-		__raw_writel(gpio_context[i].irqenable1,
-				bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		__raw_writel(gpio_context[i].irqenable2,
-				bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		__raw_writel(gpio_context[i].wake_en,
-				bank->base + OMAP24XX_GPIO_WAKE_EN);
-		__raw_writel(gpio_context[i].ctrl,
-				bank->base + OMAP24XX_GPIO_CTRL);
-		__raw_writel(gpio_context[i].oe,
-				bank->base + OMAP24XX_GPIO_OE);
-		__raw_writel(gpio_context[i].leveldetect0,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		__raw_writel(gpio_context[i].leveldetect1,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		__raw_writel(gpio_context[i].risingdetect,
-				bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		__raw_writel(gpio_context[i].fallingdetect,
-				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(gpio_context[i].dataout,
-				bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
+	if (!gpio_fn.gpio_restore_ctx)
+		return;
+
+	list_for_each_entry(bank, &omap_gpio_list, node)
+		gpio_fn.gpio_restore_ctx(bank->base, bank->id);
 }
-#endif
 
 static struct platform_driver omap_gpio_driver = {
 	.probe		= omap_gpio_probe,
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index bfd5b6c..0925a6c 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -122,6 +122,8 @@ struct omap_gpio_func {
 			void __iomem *base, int offmode);
 	void (*gpio_resume_after_idle)(u32 enabled_non_wakeup_gpios, u16 id,
 			void __iomem *base);
+	void (*gpio_save_ctx)(void __iomem *base, u32 id);
+	void (*gpio_restore_ctx)(void __iomem *base, u32 id);
 };
 
 struct omap_gpio_platform_data {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 14/18] OMAP: GPIO: Remove CONFIG_ARCH_OMAP16XX/OMAP2+ defines
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (12 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 13/18] OMAP: GPIO: cleanup save/restore context Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 15/18] OMAP: GPIO: cleanup gpio_show_rev Charulatha V
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Suspend/resume/wakeup capabilities are supported only in
OMAP16xx and OMAP2PLUS SoCs. Handle this by using a flag
"suspend_resume_support" in pdata.

This requires calling omap_gpio_sysinit() as part of probe
instead of having this function as an arch_initcall

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio16xx.c         |    5 ++
 arch/arm/mach-omap2/gpio.c             |    1 +
 arch/arm/plat-omap/gpio.c              |   96 ++++++++++++++------------------
 arch/arm/plat-omap/include/plat/gpio.h |    1 +
 4 files changed, 48 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 6a99b01..cbac063 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -76,6 +76,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
 	.bank_type		= METHOD_MPUIO,
 	.bank_width		= OMAP1610_GPIO_WIDTH,
 	.bank_stride		= 1,
+	.suspend_resume_support	= true,
 };
 
 static struct __initdata platform_device omap16xx_mpu_gpio = {
@@ -105,6 +106,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
 	.bank_type		= METHOD_GPIO_1610,
 	.bank_width		= OMAP1610_GPIO_WIDTH,
+	.suspend_resume_support	= true,
 };
 
 static struct __initdata platform_device omap16xx_gpio1 = {
@@ -134,6 +136,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		= OMAP1610_GPIO_WIDTH,
+	.suspend_resume_support	= true,
 };
 
 static struct __initdata platform_device omap16xx_gpio2 = {
@@ -163,6 +166,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		= OMAP1610_GPIO_WIDTH,
+	.suspend_resume_support	= true,
 };
 
 static struct __initdata platform_device omap16xx_gpio3 = {
@@ -192,6 +196,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		= OMAP1610_GPIO_WIDTH,
+	.suspend_resume_support	= true,
 };
 
 static struct __initdata platform_device omap16xx_gpio4 = {
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index a7bb005..73b5705 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -467,6 +467,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	pdata->dbck_flag = dev_attr->dbck_flag;
 	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
 	pdata->gpio_fn = &gpio_fn;
+	pdata->suspend_resume_support = true;
 
 	switch (oh->class->rev) {
 	case 0:
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index fd710cd..0f48364 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -158,11 +158,13 @@ struct gpio_bank {
 	struct device *dev;
 	bool dbck_flag;
 	int stride;
+	bool suspend_resume_support;
 };
 
 static struct omap_gpio_func gpio_fn;
 static int bank_width;
 
+static int omap_gpio_sysinit(void);
 static int check_gpio(int gpio)
 {
 	if (unlikely(gpio_fn.gpio_valid(gpio) < 0)) {
@@ -829,8 +831,6 @@ static struct irq_chip gpio_irq_chip = {
 
 /*---------------------------------------------------------------------*/
 
-#ifdef CONFIG_ARCH_OMAP1
-
 /* MPUIO uses the always-on 32k clock */
 
 static void mpuio_ack_irq(struct irq_data *d)
@@ -860,20 +860,8 @@ static struct irq_chip mpuio_irq_chip = {
 	.irq_mask	= mpuio_mask_irq,
 	.irq_unmask	= mpuio_unmask_irq,
 	.irq_set_type	= gpio_irq_type,
-#ifdef CONFIG_ARCH_OMAP16XX
-	/* REVISIT: assuming only 16xx supports MPUIO wake events */
-	.irq_set_wake	= gpio_wake_enable,
-#endif
 };
 
-
-#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);
@@ -944,19 +932,6 @@ static inline void mpuio_init(struct gpio_bank *bank)
 	mpuio_init_done = 1;
 }
 
-#else
-static inline void mpuio_init(struct gpio_bank *bank) {}
-#endif	/* 16xx */
-
-#else
-
-extern struct irq_chip mpuio_irq_chip;
-
-#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
@@ -1104,7 +1079,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
 				bank->non_wakeup_gpios = non_wakeup_gpios[id];
 		}
 	} else if (cpu_class_is_omap1()) {
-		if (bank_is_mpuio(bank))
+		if (bank->method == METHOD_MPUIO)
 			__raw_writew(0xffff, bank->base +
 				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
 		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
@@ -1155,11 +1130,10 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 	bank->chip.set_debounce = gpio_debounce;
 	bank->chip.set = gpio_set;
 	bank->chip.to_irq = gpio_2irq;
-	if (bank_is_mpuio(bank)) {
+	if (bank->method == METHOD_MPUIO) {
 		bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
-		bank->chip.dev = &omap_mpuio_device.dev;
-#endif
+		if (bank->suspend_resume_support)
+			bank->chip.dev = &omap_mpuio_device.dev;
 		bank->chip.base = OMAP_MPUIO(0);
 	} else {
 		bank->chip.label = "gpio";
@@ -1174,8 +1148,16 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 		     j < bank->virtual_irq_start + bank_width; j++) {
 		irq_set_lockdep_class(j, &gpio_lock_class);
 		irq_set_chip_data(j, bank);
-		if (bank_is_mpuio(bank))
+		if (bank->method == METHOD_MPUIO) {
+			if (bank->suspend_resume_support)
+				/*
+				 * REVISIT: assuming only 16xx supports
+				 * MPUIO wake events
+				 */
+				mpuio_irq_chip.irq_set_wake = gpio_wake_enable;
+
 			irq_set_chip(j, &mpuio_irq_chip);
+		}
 		else
 			irq_set_chip(j, &gpio_irq_chip);
 		irq_set_handler(j, handle_simple_irq);
@@ -1215,11 +1197,23 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	bank->dev = &pdev->dev;
 	bank->dbck_flag = pdata->dbck_flag;
 	bank->stride = pdata->bank_stride;
+	bank->suspend_resume_support = pdata->suspend_resume_support;
 	bank_width = pdata->bank_width;
 
-	if (!gpio_init_done) {
-		if (cpu_class_is_omap1())
-			mpuio_init(bank);
+	if (pdata->suspend_resume_support) {
+		mpuio_init(bank);
+
+		if (!gpio_init_done) {
+			int ret = 0;
+
+			ret = omap_gpio_sysinit();
+			if (ret) {
+				dev_err(&pdev->dev,
+					"omap_gpio_sysinit failed with error"
+					" %d\n", ret);
+				return ret;
+			}
+		}
 	}
 
 	spin_lock_init(&bank->lock);
@@ -1343,6 +1337,17 @@ static struct sys_device omap_gpio_device = {
 	.cls		= &omap_gpio_sysclass,
 };
 
+static inline int omap_gpio_sysinit(void)
+{
+	int ret = 0;
+
+	ret = sysdev_class_register(&omap_gpio_sysclass);
+	if (!ret)
+		ret = sysdev_register(&omap_gpio_device);
+
+	return ret;
+}
+
 void omap2_gpio_prepare_for_idle(int off_mode)
 {
 	struct gpio_bank *bank;
@@ -1408,22 +1413,3 @@ static int __init omap_gpio_drv_reg(void)
 	return platform_driver_register(&omap_gpio_driver);
 }
 postcore_initcall(omap_gpio_drv_reg);
-
-static int __init omap_gpio_sysinit(void)
-{
-	int ret = 0;
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-		if (ret == 0) {
-			ret = sysdev_class_register(&omap_gpio_sysclass);
-			if (ret == 0)
-				ret = sysdev_register(&omap_gpio_device);
-		}
-	}
-#endif
-
-	return ret;
-}
-
-arch_initcall(omap_gpio_sysinit);
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 0925a6c..5a0d946 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -133,6 +133,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 suspend_resume_support; /* True for OMAP16XX, OMAP2PLUS */
 };
 
 extern void omap2_gpio_prepare_for_idle(int off_mode);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 15/18] OMAP: GPIO: cleanup gpio_show_rev
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (13 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 14/18] OMAP: GPIO: Remove CONFIG_ARCH_OMAP16XX/OMAP2+ defines Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 16/18] OMAP: GPIO: move omap_gpio_mod_init to mach-omap Charulatha V
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Remove cpu_is* checks from omap_gpio_show_rev.

Also display GPIO IP version only once as it is not
required to print the IP version of all the banks as
they are the same.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 0f48364..637db76 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -1032,12 +1032,10 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
 {
 	u32 rev;
 
-	if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
-		rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
-	else if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
-	else if (cpu_is_omap44xx())
-		rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
+	if ((bank->method == METHOD_GPIO_24XX) ||
+			(bank->method == METHOD_GPIO_44XX) ||
+			(bank->method == METHOD_GPIO_1610))
+		rev = gpio_fn.gpio_read(bank->base, REV);
 	else
 		return;
 
@@ -1170,6 +1168,7 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
 	static int gpio_init_done;
+	static int show_rev;
 	struct omap_gpio_platform_data *pdata;
 	struct resource *res;
 	struct gpio_bank *bank;
@@ -1238,7 +1237,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 
 	omap_gpio_mod_init(bank, pdev->id);
 	omap_gpio_chip_init(bank);
-	omap_gpio_show_rev(bank);
 
 	list_add_tail(&bank->node, &omap_gpio_list);
 
@@ -1259,6 +1257,11 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_init_done = 1;
 	}
 
+	if ((bank->method != METHOD_MPUIO) && (!show_rev)) {
+		omap_gpio_show_rev(bank);
+		show_rev = 1;
+	}
+
 	return 0;
 }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 16/18] OMAP: GPIO: move omap_gpio_mod_init to mach-omap
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (14 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 15/18] OMAP: GPIO: cleanup gpio_show_rev Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 17/18] OMAP: GPIO: use dev_err* instead of printk Charulatha V
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Move omap_gpio_mod_init() from plat-omap/ to mach-omap*/
as this function handles architecture specific GPIO module
initialization.

Provide non_wakeup_gpios information through pdata.

With this change all the cpu_is* checks & #ifdef CONFIG_ARCH_OMAP*
will be removed from OMAP GPIO driver.

Also remove all the unsused register offset macros.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |    7 ++
 arch/arm/mach-omap1/gpio16xx.c         |   24 +++++
 arch/arm/mach-omap1/gpio7xx.c          |    7 ++
 arch/arm/mach-omap2/gpio.c             |   31 +++++-
 arch/arm/plat-omap/gpio.c              |  172 ++------------------------------
 arch/arm/plat-omap/include/plat/gpio.h |    2 +
 6 files changed, 74 insertions(+), 169 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 3763db3..f8303e6 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -163,6 +163,12 @@ static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
 	gpio_write(l, base, IRQENABLE1);
 }
 
+static void gpio_init(void __iomem *base, u32 id)
+{
+	gpio_write(0xffff, base, INT_CTRL);
+	gpio_write(0, base, IRQSTATUS_REG0);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -171,6 +177,7 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_set_trigger = gpio_set_trigger,
 	.gpio_is_irqena = gpio_is_irqena,
 	.gpio_enable_irq = gpio_enable_irq,
+	.gpio_init = gpio_init,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index cbac063..37820ba 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -291,6 +291,29 @@ static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
 		gpio_write(gpio_mask, base, CLEARIRQENA1);
 }
 
+/*
+ * GPIO SYSCONFIG needs to be set expicitly in
+ * the driver code only for OMAP16xx. For OMAP2plus
+ * this is taken care by PM runtime framework.
+ * Hence no specific field is required to defined in
+ * omap_gpio_reg_offsets.
+ */
+#define OMAP1610_GPIO_SYSCONFIG		0x0010
+
+static void gpio_init(void __iomem *base, u32 id)
+{
+	gpio_write(0, base, IRQENABLE1);
+	gpio_write(0xffff, base, IRQSTATUS_REG0);
+	__raw_writew(0x0014, base + OMAP1610_GPIO_SYSCONFIG);
+
+	/*
+	 * Enable system clock for GPIO module.
+	 * The CAM_CLK_CTRL *is* really the right place.
+	 */
+	omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+					ULPD_CAM_CLK_CTRL);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -299,6 +322,7 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_set_trigger = gpio_set_trigger,
 	.gpio_is_irqena = gpio_is_irqena,
 	.gpio_enable_irq = gpio_enable_irq,
+	.gpio_init = gpio_init,
 };
 
 /*
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index cd6bad7..792156c 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -325,6 +325,12 @@ static void gpio_enable_irq(void __iomem *base, int gpio_mask, int enable)
 	gpio_write(l, base, IRQENABLE1);
 }
 
+static void gpio_init(void __iomem *base, u32 id)
+{
+	gpio_write(0xffffffff, base, INT_CTRL);
+	gpio_write(0, base, IRQSTATUS_REG0);
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -333,6 +339,7 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_set_trigger = gpio_set_trigger,
 	.gpio_is_irqena = gpio_is_irqena,
 	.gpio_enable_irq = gpio_enable_irq,
+	.gpio_init = gpio_init,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 73b5705..f5615a7 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -421,6 +421,22 @@ static void gpio_restore_ctx(void __iomem *base, u32 id)
 	}
 }
 
+static void gpio_init(void __iomem *base, u32 id)
+{
+	if (cpu_is_omap44xx()) {
+		gpio_write(0xffffffff, base, IRQSTATUSCLR0);
+		gpio_write(0x00000000, base, DEBOUNCE_EN);
+		/* Initialize interface clk ungated, module enabled */
+		gpio_write(0, base, CTRL);
+	} else if (cpu_is_omap34xx()) {
+		gpio_write(0x00000000, base, IRQENABLE1);
+		gpio_write(0xffffffff, base, IRQSTATUS_REG0);
+		gpio_write(0x00000000, base, DEBOUNCE_EN);
+		/* Initialize interface clk ungated, module enabled */
+		gpio_write(0, base, CTRL);
+	}
+}
+
 static struct omap_gpio_func gpio_fn = {
 	.get_index = get_gpio_index,
 	.gpio_valid = gpio_valid,
@@ -434,6 +450,7 @@ static struct omap_gpio_func gpio_fn = {
 	.gpio_resume_after_idle = gpio_resume_after_idle,
 	.gpio_save_ctx = gpio_save_ctx,
 	.gpio_restore_ctx = gpio_restore_ctx,
+	.gpio_init = gpio_init,
 };
 
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
@@ -442,7 +459,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	struct omap_gpio_platform_data *pdata;
 	struct omap_gpio_dev_attr *dev_attr;
 	char *name = "omap_gpio";
-	int id;
+	int id, i;
 	struct gpio_state *gpio_dev_state;
 
 	/*
@@ -454,6 +471,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	 * or make use of static variable mechanism to handle this.
 	 */
 	sscanf(oh->name, "gpio%d", &id);
+	i = id - 1;
 
 	pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
 	if (!pdata) {
@@ -465,12 +483,17 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	bank_width = dev_attr->bank_width;
 	pdata->bank_width = bank_width;
 	pdata->dbck_flag = dev_attr->dbck_flag;
-	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
+	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
 	pdata->gpio_fn = &gpio_fn;
 	pdata->suspend_resume_support = true;
 
 	switch (oh->class->rev) {
 	case 0:
+		if (!i)
+			pdata->non_wakeup_gpios = 0xe203ffc0;
+		else if (i == 1)
+			pdata->non_wakeup_gpios = 0x08700040;
+		/* FALL THROUGH */
 	case 1:
 		pdata->bank_type = METHOD_GPIO_24XX;
 		reg_map = omap2_gpio_reg_offsets;
@@ -493,10 +516,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 		return -ENOMEM;
 	}
 
-	gpio_dev_state->id = id - 1;
+	gpio_dev_state->id = i;
 	list_add_tail(&gpio_dev_state->node, &omap_gpio_ctx_list);
 
-	od = omap_device_build(name, id - 1, oh, pdata,
+	od = omap_device_build(name, i, oh, pdata,
 				sizeof(*pdata),	omap_gpio_latency,
 				ARRAY_SIZE(omap_gpio_latency),
 				false);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 637db76..9c3e865 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -33,108 +33,6 @@
 
 #define OMAP_GPIO_WAKE_SET_CLR_ALL	0xffffffff
 #define	MPUIO_GPIO_IRQENA_MASK	0xffff
-/*
- * OMAP1510 GPIO registers
- */
-#define OMAP1510_GPIO_DATA_INPUT	0x00
-#define OMAP1510_GPIO_DATA_OUTPUT	0x04
-#define OMAP1510_GPIO_DIR_CONTROL	0x08
-#define OMAP1510_GPIO_INT_CONTROL	0x0c
-#define OMAP1510_GPIO_INT_MASK		0x10
-#define OMAP1510_GPIO_INT_STATUS	0x14
-#define OMAP1510_GPIO_PIN_CONTROL	0x18
-
-#define OMAP1510_IH_GPIO_BASE		64
-
-/*
- * OMAP1610 specific GPIO registers
- */
-#define OMAP1610_GPIO_REVISION		0x0000
-#define OMAP1610_GPIO_SYSCONFIG		0x0010
-#define OMAP1610_GPIO_SYSSTATUS		0x0014
-#define OMAP1610_GPIO_IRQSTATUS1	0x0018
-#define OMAP1610_GPIO_IRQENABLE1	0x001c
-#define OMAP1610_GPIO_WAKEUPENABLE	0x0028
-#define OMAP1610_GPIO_DATAIN		0x002c
-#define OMAP1610_GPIO_DATAOUT		0x0030
-#define OMAP1610_GPIO_DIRECTION		0x0034
-#define OMAP1610_GPIO_EDGE_CTRL1	0x0038
-#define OMAP1610_GPIO_EDGE_CTRL2	0x003c
-#define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
-#define OMAP1610_GPIO_CLEAR_WAKEUPENA	0x00a8
-#define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
-#define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
-#define OMAP1610_GPIO_SET_WAKEUPENA	0x00e8
-#define OMAP1610_GPIO_SET_DATAOUT	0x00f0
-
-/*
- * OMAP7XX specific GPIO registers
- */
-#define OMAP7XX_GPIO_DATA_INPUT		0x00
-#define OMAP7XX_GPIO_DATA_OUTPUT	0x04
-#define OMAP7XX_GPIO_DIR_CONTROL	0x08
-#define OMAP7XX_GPIO_INT_CONTROL	0x0c
-#define OMAP7XX_GPIO_INT_MASK		0x10
-#define OMAP7XX_GPIO_INT_STATUS		0x14
-
-/*
- * omap2+ specific GPIO registers
- */
-#define OMAP24XX_GPIO_REVISION		0x0000
-#define OMAP24XX_GPIO_IRQSTATUS1	0x0018
-#define OMAP24XX_GPIO_IRQSTATUS2	0x0028
-#define OMAP24XX_GPIO_IRQENABLE2	0x002c
-#define OMAP24XX_GPIO_IRQENABLE1	0x001c
-#define OMAP24XX_GPIO_WAKE_EN		0x0020
-#define OMAP24XX_GPIO_CTRL		0x0030
-#define OMAP24XX_GPIO_OE		0x0034
-#define OMAP24XX_GPIO_DATAIN		0x0038
-#define OMAP24XX_GPIO_DATAOUT		0x003c
-#define OMAP24XX_GPIO_LEVELDETECT0	0x0040
-#define OMAP24XX_GPIO_LEVELDETECT1	0x0044
-#define OMAP24XX_GPIO_RISINGDETECT	0x0048
-#define OMAP24XX_GPIO_FALLINGDETECT	0x004c
-#define OMAP24XX_GPIO_DEBOUNCE_EN	0x0050
-#define OMAP24XX_GPIO_DEBOUNCE_VAL	0x0054
-#define OMAP24XX_GPIO_CLEARIRQENABLE1	0x0060
-#define OMAP24XX_GPIO_SETIRQENABLE1	0x0064
-#define OMAP24XX_GPIO_CLEARWKUENA	0x0080
-#define OMAP24XX_GPIO_SETWKUENA		0x0084
-#define OMAP24XX_GPIO_CLEARDATAOUT	0x0090
-#define OMAP24XX_GPIO_SETDATAOUT	0x0094
-
-#define OMAP4_GPIO_REVISION		0x0000
-#define OMAP4_GPIO_EOI			0x0020
-#define OMAP4_GPIO_IRQSTATUSRAW0	0x0024
-#define OMAP4_GPIO_IRQSTATUSRAW1	0x0028
-#define OMAP4_GPIO_IRQSTATUS0		0x002c
-#define OMAP4_GPIO_IRQSTATUS1		0x0030
-#define OMAP4_GPIO_IRQSTATUSSET0	0x0034
-#define OMAP4_GPIO_IRQSTATUSSET1	0x0038
-#define OMAP4_GPIO_IRQSTATUSCLR0	0x003c
-#define OMAP4_GPIO_IRQSTATUSCLR1	0x0040
-#define OMAP4_GPIO_IRQWAKEN0		0x0044
-#define OMAP4_GPIO_IRQWAKEN1		0x0048
-#define OMAP4_GPIO_IRQENABLE1		0x011c
-#define OMAP4_GPIO_WAKE_EN		0x0120
-#define OMAP4_GPIO_IRQSTATUS2		0x0128
-#define OMAP4_GPIO_IRQENABLE2		0x012c
-#define OMAP4_GPIO_CTRL			0x0130
-#define OMAP4_GPIO_OE			0x0134
-#define OMAP4_GPIO_DATAIN		0x0138
-#define OMAP4_GPIO_DATAOUT		0x013c
-#define OMAP4_GPIO_LEVELDETECT0		0x0140
-#define OMAP4_GPIO_LEVELDETECT1		0x0144
-#define OMAP4_GPIO_RISINGDETECT		0x0148
-#define OMAP4_GPIO_FALLINGDETECT	0x014c
-#define OMAP4_GPIO_DEBOUNCENABLE	0x0150
-#define OMAP4_GPIO_DEBOUNCINGTIME	0x0154
-#define OMAP4_GPIO_CLEARIRQENABLE1	0x0160
-#define OMAP4_GPIO_SETIRQENABLE1	0x0164
-#define OMAP4_GPIO_CLEARWKUENA		0x0180
-#define OMAP4_GPIO_SETWKUENA		0x0184
-#define OMAP4_GPIO_CLEARDATAOUT		0x0190
-#define OMAP4_GPIO_SETDATAOUT		0x0194
 
 static LIST_HEAD(omap_gpio_list);
 
@@ -1048,68 +946,6 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
  */
 static struct lock_class_key gpio_lock_class;
 
-/* TODO: Cleanup cpu_is_* checks */
-static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
-{
-	if (cpu_class_is_omap2()) {
-		if (cpu_is_omap44xx()) {
-			__raw_writel(0xffffffff, bank->base +
-					OMAP4_GPIO_IRQSTATUSCLR0);
-			__raw_writel(0x00000000, bank->base +
-					 OMAP4_GPIO_DEBOUNCENABLE);
-			/* Initialize interface clk ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-		} else if (cpu_is_omap34xx()) {
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_IRQENABLE1);
-			__raw_writel(0xffffffff, bank->base +
-					OMAP24XX_GPIO_IRQSTATUS1);
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_DEBOUNCE_EN);
-
-			/* 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 (id < ARRAY_SIZE(non_wakeup_gpios))
-				bank->non_wakeup_gpios = non_wakeup_gpios[id];
-		}
-	} else if (cpu_class_is_omap1()) {
-		if (bank->method == METHOD_MPUIO)
-			__raw_writew(0xffff, bank->base +
-				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
-		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
-			__raw_writew(0xffff, bank->base
-						+ OMAP1510_GPIO_INT_MASK);
-			__raw_writew(0x0000, bank->base
-						+ OMAP1510_GPIO_INT_STATUS);
-		}
-		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
-			__raw_writew(0x0000, bank->base
-						+ OMAP1610_GPIO_IRQENABLE1);
-			__raw_writew(0xffff, bank->base
-						+ OMAP1610_GPIO_IRQSTATUS1);
-			__raw_writew(0x0014, bank->base
-						+ OMAP1610_GPIO_SYSCONFIG);
-
-			/*
-			 * Enable system clock for GPIO module.
-			 * The CAM_CLK_CTRL *is* really the right place.
-			 */
-			omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
-						ULPD_CAM_CLK_CTRL);
-		}
-		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
-			__raw_writel(0xffffffff, bank->base
-						+ OMAP7XX_GPIO_INT_MASK);
-			__raw_writel(0x00000000, bank->base
-						+ OMAP7XX_GPIO_INT_STATUS);
-		}
-	}
-}
-
 static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 {
 	int j;
@@ -1197,6 +1033,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	bank->dbck_flag = pdata->dbck_flag;
 	bank->stride = pdata->bank_stride;
 	bank->suspend_resume_support = pdata->suspend_resume_support;
+	bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
 	bank_width = pdata->bank_width;
 
 	if (pdata->suspend_resume_support) {
@@ -1235,7 +1072,12 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	pm_runtime_enable(bank->dev);
 	pm_runtime_get_sync(bank->dev);
 
-	omap_gpio_mod_init(bank, pdev->id);
+	if (bank->method == METHOD_MPUIO)
+		__raw_writew(0xffff, bank->base +
+			OMAP_MPUIO_GPIO_MASKIT / bank->stride);
+	else
+		pdata->gpio_fn->gpio_init(bank->base, bank->id);
+
 	omap_gpio_chip_init(bank);
 
 	list_add_tail(&bank->node, &omap_gpio_list);
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 5a0d946..87fee8d 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -124,6 +124,7 @@ struct omap_gpio_func {
 			void __iomem *base);
 	void (*gpio_save_ctx)(void __iomem *base, u32 id);
 	void (*gpio_restore_ctx)(void __iomem *base, u32 id);
+	void (*gpio_init)(void __iomem *base, u32 id);
 };
 
 struct omap_gpio_platform_data {
@@ -134,6 +135,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 suspend_resume_support; /* True for OMAP16XX, OMAP2PLUS */
+	u32 non_wakeup_gpios;
 };
 
 extern void omap2_gpio_prepare_for_idle(int off_mode);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 17/18] OMAP: GPIO: use dev_err* instead of printk
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (15 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 16/18] OMAP: GPIO: move omap_gpio_mod_init to mach-omap Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 11:08 ` [RFC PATCH 18/18] OMAP: GPIO: Remove usage of bank method Charulatha V
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use dev_info()/dev_err() instead of printk in OMAP GPIO driver

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/plat-omap/gpio.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9c3e865..7ae9f6f 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -66,7 +66,7 @@ static int omap_gpio_sysinit(void);
 static int check_gpio(int gpio)
 {
 	if (unlikely(gpio_fn.gpio_valid(gpio) < 0)) {
-		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
+		pr_err("omap-gpio: invalid GPIO %d\n", gpio);
 		dump_stack();
 		return -1;
 	}
@@ -470,7 +470,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_44XX:
 		if (bank->non_wakeup_gpios & (1 << gpio)) {
-			printk(KERN_ERR "Unable to modify wakeup on "
+			dev_err(bank->dev, "Unable to modify wakeup on "
 					"non-wakeup GPIO%d\n",
 					bank->id * 32 + gpio);
 			return -EINVAL;
@@ -485,7 +485,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
 	default:
-		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
+		dev_err(bank->dev, "Can't enable GPIO wakeup for method %i\n",
 		       bank->method);
 		return -EINVAL;
 	}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 18/18] OMAP: GPIO: Remove usage of bank method
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (16 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 17/18] OMAP: GPIO: use dev_err* instead of printk Charulatha V
@ 2011-04-22 11:08 ` Charulatha V
  2011-04-22 14:02 ` [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Sascha Hauer
  2011-04-22 22:34 ` Kevin Hilman
  19 siblings, 0 replies; 26+ messages in thread
From: Charulatha V @ 2011-04-22 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Remove usage of bank->method to identify CPU specific OMAP GPIO bank.
Instead identify specific features using flags and accordingly manage.
bank->type MPUIO is common for all OMAP1 SoCs. Use bank->stride to
identify the MPUIO type bank

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |    2 -
 arch/arm/mach-omap1/gpio16xx.c         |   24 ++--
 arch/arm/mach-omap1/gpio7xx.c          |    7 -
 arch/arm/mach-omap2/gpio.c             |   11 ++-
 arch/arm/plat-omap/gpio.c              |  228 +++++++++++++------------------
 arch/arm/plat-omap/include/plat/gpio.h |   46 ++++++-
 6 files changed, 155 insertions(+), 163 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index f8303e6..aa08ebf 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -54,7 +54,6 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
-	.bank_type		= METHOD_MPUIO,
 	.bank_width		= OMAP1510_GPIO_WIDTH,
 	.bank_stride		= 1,
 };
@@ -84,7 +83,6 @@ static struct __initdata resource omap15xx_gpio_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
-	.bank_type		= METHOD_GPIO_1510,
 	.bank_width		= OMAP1510_GPIO_WIDTH,
 };
 
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 37820ba..5f116f6 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -38,6 +38,13 @@
 #define	OMAP1610_GPIO_BOTH_EDGE_SET		0x03
 #define	OMAP1610_GPIO_EDGE_MASK			0x07
 
+#define OMAP16XX_SPECIFIC_SUPPORT\
+	.bank_width		= 16,\
+	.suspend_resume_support	= true,\
+	.features = BIT(OMAP_GPIO_REV_SHOW_FLAG) |\
+			BIT(OMAP_GPIO_DATAOUT_SET_CLR_REGS_FLAG) |\
+			BIT(OMAP_GPIO_DUAL_EDGE_TRIG_FLAG)\
+
 static u16 reg_map[] = {
 	[REV]			= 0x00,
 	[SYS_CFG]		= 0x10,
@@ -73,7 +80,6 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
-	.bank_type		= METHOD_MPUIO,
 	.bank_width		= OMAP1610_GPIO_WIDTH,
 	.bank_stride		= 1,
 	.suspend_resume_support	= true,
@@ -104,9 +110,7 @@ static struct __initdata resource omap16xx_gpio1_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
-	.bank_type		= METHOD_GPIO_1610,
-	.bank_width		= OMAP1610_GPIO_WIDTH,
-	.suspend_resume_support	= true,
+	OMAP16XX_SPECIFIC_SUPPORT,
 };
 
 static struct __initdata platform_device omap16xx_gpio1 = {
@@ -134,9 +138,7 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 16,
-	.bank_type		= METHOD_GPIO_1610,
-	.bank_width		= OMAP1610_GPIO_WIDTH,
-	.suspend_resume_support	= true,
+	OMAP16XX_SPECIFIC_SUPPORT,
 };
 
 static struct __initdata platform_device omap16xx_gpio2 = {
@@ -164,9 +166,7 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 32,
-	.bank_type		= METHOD_GPIO_1610,
-	.bank_width		= OMAP1610_GPIO_WIDTH,
-	.suspend_resume_support	= true,
+	OMAP16XX_SPECIFIC_SUPPORT,
 };
 
 static struct __initdata platform_device omap16xx_gpio3 = {
@@ -194,9 +194,7 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 48,
-	.bank_type		= METHOD_GPIO_1610,
-	.bank_width		= OMAP1610_GPIO_WIDTH,
-	.suspend_resume_support	= true,
+	OMAP16XX_SPECIFIC_SUPPORT,
 };
 
 static struct __initdata platform_device omap16xx_gpio4 = {
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 792156c..28d5917 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -60,7 +60,6 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
 	.virtual_irq_start	= IH_MPUIO_BASE,
-	.bank_type		= METHOD_MPUIO,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 	.bank_stride		= 2,
 };
@@ -90,7 +89,6 @@ static struct __initdata resource omap7xx_gpio1_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
 	.virtual_irq_start	= IH_GPIO_BASE,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
@@ -119,7 +117,6 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 32,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
@@ -148,7 +145,6 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 64,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
@@ -177,7 +173,6 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 96,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
@@ -206,7 +201,6 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 128,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
@@ -235,7 +229,6 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
 	.virtual_irq_start	= IH_GPIO_BASE + 160,
-	.bank_type		= METHOD_GPIO_7XX,
 	.bank_width		= OMAP7XX_GPIO_WIDTH,
 };
 
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index f5615a7..7542c56 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -486,6 +486,12 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
 	pdata->gpio_fn = &gpio_fn;
 	pdata->suspend_resume_support = true;
+	pdata->features = BIT(OMAP_GPIO_LEVEL_TRIGGER_FLAG) |
+				BIT(OMAP_GPIO_CLK_GATING_FLAG) |
+				BIT(OMAP_GPIO_REV_SHOW_FLAG) |
+				BIT(OMAP_GPIO_DATAOUT_SET_CLR_REGS_FLAG) |
+				BIT(OMAP_GPIO_DUAL_EDGE_TRIG_FLAG) |
+				BIT(OMAP_GPIO_WA_CLR_DSP_INT_FLAG);
 
 	switch (oh->class->rev) {
 	case 0:
@@ -493,13 +499,14 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 			pdata->non_wakeup_gpios = 0xe203ffc0;
 		else if (i == 1)
 			pdata->non_wakeup_gpios = 0x08700040;
+
+		pdata->features |= BIT(OMAP_GPIO_HANDLE_IRQ_LOSS_LOW_PWR_FLAG);
 		/* FALL THROUGH */
 	case 1:
-		pdata->bank_type = METHOD_GPIO_24XX;
 		reg_map = omap2_gpio_reg_offsets;
 		break;
 	case 2:
-		pdata->bank_type = METHOD_GPIO_44XX;
+		pdata->features |= BIT(OMAP_GPIO_IRQ_WK_ENA_REG_FLAG);
 		reg_map = omap4_gpio_reg_offsets;
 		break;
 	default:
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 7ae9f6f..d52d427 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -42,7 +42,6 @@ struct gpio_bank {
 	void __iomem *base;
 	u16 irq;
 	u16 virtual_irq_start;
-	int method;
 	u32 suspend_wakeup;
 	u32 saved_wakeup;
 	u32 non_wakeup_gpios;
@@ -57,6 +56,7 @@ struct gpio_bank {
 	bool dbck_flag;
 	int stride;
 	bool suspend_resume_support;
+	u32 features_flag;
 };
 
 static struct omap_gpio_func gpio_fn;
@@ -89,7 +89,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 	u32 offset;
 	u32 l;
 
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		offset = OMAP_MPUIO_IO_CNTL / bank->stride;
 		l = gpio_mpuio_read(base, offset);
 	} else {
@@ -102,7 +102,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 	else
 		l &= ~(1 << gpio);
 
-	if (bank->method == METHOD_MPUIO)
+	if (bank->stride)
 		gpio_mpuio_write(l, base, offset);
 	else
 		gpio_fn.gpio_write(l, base, offset);
@@ -114,8 +114,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 	u32 offset;
 	u32 l = 0;
 
-	switch (bank->method) {
-	case METHOD_MPUIO:
+	if (bank->stride) {
 		offset = OMAP_MPUIO_OUTPUT / bank->stride;
 		l = gpio_mpuio_read(base, offset);
 
@@ -125,10 +124,10 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 			l &= ~(1 << gpio);
 
 		gpio_mpuio_write(l, base, offset);
-		break;
+		return;
+	}
 
-	case METHOD_GPIO_1510:
-	case METHOD_GPIO_7XX:
+	if (!(bank->features_flag & BIT(OMAP_GPIO_DATAOUT_SET_CLR_REGS_FLAG))) {
 		l = gpio_fn.gpio_read(base, DATAOUT);
 
 		if (enable)
@@ -137,9 +136,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 			l &= ~(1 << gpio);
 
 		gpio_fn.gpio_write(l, base, DATAOUT);
-		break;
-
-	default:
+	} else {
 		if (enable)
 			offset = SETDATAOUT;
 		else
@@ -147,7 +144,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 
 		l = 1 << gpio;
 		gpio_fn.gpio_write(l, base, offset);
-		break;
 	}
 
 }
@@ -163,7 +159,7 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 
 	base = bank->base;
 
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		offset = OMAP_MPUIO_INPUT_LATCH / bank->stride;
 		ret = gpio_mpuio_read(base, offset);
 	} else {
@@ -185,7 +181,7 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
 
 	base = bank->base;
 
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		offset = OMAP_MPUIO_OUTPUT / bank->stride;
 		ret = gpio_mpuio_read(base, offset);
 	} else {
@@ -226,8 +222,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 	u32 l = 0;
 	u32 offset;
 
-	switch (bank->method) {
-	case METHOD_MPUIO:
+	if (bank->stride) {
 		offset = OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
 		l = gpio_mpuio_read(base, offset);
 
@@ -237,10 +232,8 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 			l |= 1 << gpio;
 
 		gpio_mpuio_write(l, base, offset);
-		return;
-
-	case METHOD_GPIO_1510:
-	case METHOD_GPIO_7XX:
+	} else if (!(bank->features_flag &
+			BIT(OMAP_GPIO_DUAL_EDGE_TRIG_FLAG))) {
 		l = gpio_fn.gpio_read(base, INT_CTRL);
 
 		if ((l >> gpio) & 1)
@@ -249,10 +242,6 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 			l |= 1 << gpio;
 
 		gpio_fn.gpio_write(l, base, INT_CTRL);
-		return;
-
-	default:
-		return;
 	}
 }
 
@@ -263,8 +252,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 	u32 l = 0;
 	u32 offset;
 
-	switch (bank->method) {
-	case METHOD_MPUIO:
+	if (bank->stride) {
 		offset = OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
 		l = gpio_mpuio_read(base, offset);
 		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
@@ -277,24 +265,32 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 			return -EINVAL;
 
 		gpio_mpuio_write(l, base, offset);
-		break;
 
-	case METHOD_GPIO_1510:
-	case METHOD_GPIO_7XX:
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
+		return ret;
+	}
 
-		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
-		break;
+	if ((!(bank->features_flag & BIT(OMAP_GPIO_DUAL_EDGE_TRIG_FLAG)))
+		&& ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH))
+		bank->toggle_mask |= 1 << gpio;
 
-	case METHOD_GPIO_1610:
-		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
-		break;
+	ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
 
-	case METHOD_GPIO_44XX:
-		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
+	if (!bank->suspend_resume_support)
+		return ret;
 
-		if (likely(!(bank->non_wakeup_gpios & (1 << gpio)))) {
+	if (likely(!(bank->non_wakeup_gpios & (1 << gpio)))) {
+		/*
+		 * GPIO wakeup request can only be generated on edge
+		 * transitions
+		 */
+		if (!(bank->features_flag &
+				BIT(OMAP_GPIO_IRQ_WK_ENA_REG_FLAG))) {
+			if (trigger & IRQ_TYPE_EDGE_BOTH)
+				gpio_fn.gpio_write(1 << gpio, base, SETWKUENA);
+			else
+				gpio_fn.gpio_write(1 << gpio, base,
+								CLEARWKUENA);
+		} else {
 			if (trigger != 0)
 				gpio_fn.gpio_write(1 << gpio, base, IRQWAKEN0);
 			else {
@@ -304,47 +300,23 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 				gpio_fn.gpio_write(val & (~(1 << gpio)), base,
 						IRQWAKEN0);
 			}
-
-			bank->level_mask = gpio_fn.gpio_read(base,
-							LEVELDETECT0);
-			bank->level_mask |= gpio_fn.gpio_read(base,
-							LEVELDETECT1);
 		}
-		break;
-
-	case METHOD_GPIO_24XX:
-		ret = gpio_fn.gpio_set_trigger(base, gpio, trigger);
-
-		if (likely(!(bank->non_wakeup_gpios & (1 << gpio)))) {
-			/*
-			 * GPIO wakeup request can only be generated on edge
-			 * transitions
-			 */
-			if (trigger & IRQ_TYPE_EDGE_BOTH)
-				gpio_fn.gpio_write(1 << gpio, base, SETWKUENA);
-			else
-				gpio_fn.gpio_write(1 << gpio, base,
-							CLEARWKUENA);
-			/*
-			 * Log the edge gpio and manually trigger the IRQ
-			 * after resume if the input level changes
-			 * to avoid irq lost during PER RET/OFF mode
-			 * Applies for omap2 non-wakeup gpio and all omap3 gpios
-			 */
+		/*
+		 * Log the edge gpio and manually trigger the IRQ
+		 * after resume if the input level changes
+		 * to avoid irq lost during PER RET/OFF mode
+		 * Applies for omap2 non-wakeup gpio and all omap3 gpios
+		 */
+		if (bank->features_flag &
+				BIT(OMAP_GPIO_HANDLE_IRQ_LOSS_LOW_PWR_FLAG)) {
 			if (trigger & IRQ_TYPE_EDGE_BOTH)
 				bank->enabled_non_wakeup_gpios |= (1 << gpio);
 			else
 				bank->enabled_non_wakeup_gpios &= ~(1 << gpio);
-
-			bank->level_mask = gpio_fn.gpio_read(base,
-							LEVELDETECT0);
-			bank->level_mask |= gpio_fn.gpio_read(base,
-							LEVELDETECT1);
 		}
-		break;
-	default:
-		ret = -EINVAL;
-		break;
+
+		bank->level_mask = gpio_fn.gpio_read(base, LEVELDETECT0);
+		bank->level_mask |= gpio_fn.gpio_read(base, LEVELDETECT1);
 	}
 
 	return ret;
@@ -359,7 +331,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 
 	bank = irq_data_get_irq_chip_data(d);
 
-	if ((bank->method == METHOD_MPUIO) && d->irq > IH_MPUIO_BASE)
+	if (bank->stride && d->irq > IH_MPUIO_BASE)
 		gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
 	else
 		gpio = d->irq - IH_GPIO_BASE;
@@ -371,7 +343,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 		return -EINVAL;
 
 	/* OMAP1 allows only only edge triggering */
-	if ((bank->method < METHOD_GPIO_24XX)
+	if ((!(bank->features_flag & BIT(OMAP_GPIO_LEVEL_TRIGGER_FLAG)))
 			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
 		return -EINVAL;
 
@@ -389,14 +361,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 
 static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 {
-	switch (bank->method) {
-	case METHOD_MPUIO:
+	if (bank->stride)
 		/* MPUIO irqstatus is reset by reading the status register,
 		 * so do nothing here */
-		break;
+		return;
 
-	case METHOD_GPIO_24XX:
-	case METHOD_GPIO_44XX:
+	if (bank->features_flag & BIT(OMAP_GPIO_WA_CLR_DSP_INT_FLAG)) {
 		/* WA for clearing DSP GPIO interrupts to allow retention */
 		gpio_fn.gpio_write(gpio_mask, bank->base, IRQSTATUS_REG1);
 		/*
@@ -404,16 +374,14 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 		 * to avoid spurious interrupts
 		 */
 		gpio_fn.gpio_read(bank->base, IRQSTATUS_REG1);
-	default:
-		gpio_fn.gpio_write(gpio_mask, bank->base, IRQSTATUS_REG0);
-		/*
-		 * Flush posted write for the irq status
-		 * to avoid spurious interrupts
-		 */
-		gpio_fn.gpio_read(bank->base, IRQSTATUS_REG0);
-		break;
 	}
-	return;
+
+	gpio_fn.gpio_write(gpio_mask, bank->base, IRQSTATUS_REG0);
+	/*
+	 * Flush posted write for the irq status
+	 * to avoid spurious interrupts
+	 */
+	gpio_fn.gpio_read(bank->base, IRQSTATUS_REG0);
 }
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -423,7 +391,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
 
 static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 {
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		u32 offset = OMAP_MPUIO_GPIO_MASKIT / bank->stride;
 		return (~gpio_mpuio_read(bank->base, offset))
 						& MPUIO_GPIO_IRQENA_MASK;
@@ -434,7 +402,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 
 static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
 {
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		u32 offset = OMAP_MPUIO_GPIO_MASKIT / bank->stride;
 		u32 l = gpio_mpuio_read(bank->base, offset);
 
@@ -466,29 +434,27 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 {
 	unsigned long uninitialized_var(flags);
 
-	switch (bank->method) {
-	case METHOD_GPIO_24XX:
-	case METHOD_GPIO_44XX:
+	if (bank->suspend_resume_support) {
 		if (bank->non_wakeup_gpios & (1 << gpio)) {
 			dev_err(bank->dev, "Unable to modify wakeup on "
 					"non-wakeup GPIO%d\n",
-					bank->id * 32 + gpio);
+					bank->id * bank_width + gpio);
 			return -EINVAL;
 		}
-	case METHOD_MPUIO:
-	case METHOD_GPIO_1610:
+
 		spin_lock_irqsave(&bank->lock, flags);
 		if (enable)
 			bank->suspend_wakeup |= (1 << gpio);
 		else
 			bank->suspend_wakeup &= ~(1 << gpio);
 		spin_unlock_irqrestore(&bank->lock, flags);
-		return 0;
-	default:
-		dev_err(bank->dev, "Can't enable GPIO wakeup for method %i\n",
-		       bank->method);
+	} else {
+		dev_err(bank->dev, "Can't enable GPIO%d wakeup\n",
+					bank->id);
 		return -EINVAL;
 	}
+
+	return 0;
 }
 
 static void _reset_gpio(struct gpio_bank *bank, int gpio)
@@ -526,13 +492,13 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 	 */
 	_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
 
-	if (bank->method == METHOD_GPIO_1510) {
+	if (bank->features_flag & BIT(OMAP_GPIO_CLAIM_PIN_FOR_MPU_FLAG)) {
 		/* Claim the pin for MPU */
 		u32 ctrl = gpio_fn.gpio_read(bank->base, CTRL);
 		gpio_fn.gpio_write(ctrl | (1 << offset), bank->base, CTRL);
 	}
 
-	if (bank->method >= METHOD_GPIO_24XX) {
+	if (bank->features_flag & BIT(OMAP_GPIO_CLK_GATING_FLAG)) {
 		if (!bank->mod_usage) {
 			u32 ctrl = gpio_fn.gpio_read(bank->base, CTRL);
 			/* Module is enabled, clocks are not gated */
@@ -552,17 +518,17 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 
 	spin_lock_irqsave(&bank->lock, flags);
 
-	if ((bank->method == METHOD_GPIO_1610) ||
-			(bank->method == METHOD_GPIO_24XX)) {
-		/* Disable wake-up during idle for dynamic tick */
-		gpio_fn.gpio_write(1 << offset, bank->base, CLEARWKUENA);
-	} else if (bank->method == METHOD_GPIO_44XX) {
-		/* Disable wake-up during idle for dynamic tick */
-		gpio_fn.gpio_write(1 << offset, bank->base, IRQWAKEN0);
+	if (bank->suspend_resume_support) {
+		if (!(bank->features_flag & BIT(OMAP_GPIO_IRQ_WK_ENA_REG_FLAG)))
+			/* Disable wake-up during idle for dynamic tick */
+			gpio_fn.gpio_write(1 << offset, bank->base,
+							CLEARWKUENA);
+		else
+			/* Disable wake-up during idle for dynamic tick */
+			gpio_fn.gpio_write(1 << offset, bank->base, IRQWAKEN0);
 	}
 
-
-	if (bank->method >= METHOD_GPIO_24XX) {
+	if (bank->features_flag & BIT(OMAP_GPIO_CLK_GATING_FLAG)) {
 		bank->mod_usage &= ~(1 << offset);
 
 		if (!bank->mod_usage) {
@@ -602,7 +568,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		u32 isr_saved, level_mask = 0;
 		u32 enabled;
 
-		if (bank->method == METHOD_MPUIO)
+		if (bank->stride)
 			isr_val = gpio_mpuio_read(bank->base,
 					OMAP_MPUIO_GPIO_INT / bank->stride);
 		else
@@ -613,10 +579,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		isr_saved = isr;
 
 		/* Common for all MPUIO banks */
-		if (bank->method == METHOD_MPUIO)
+		if (bank->stride)
 			isr &= 0x0000ffff;
 
-		if (bank->method >= METHOD_GPIO_24XX)
+		if (bank->features_flag & BIT(OMAP_GPIO_LEVEL_TRIGGER_FLAG))
 			level_mask = bank->level_mask & enabled;
 
 		/*
@@ -819,7 +785,7 @@ static inline void mpuio_init(struct gpio_bank *bank)
 {
 	static int mpuio_init_done;
 
-	if (mpuio_init_done || (bank->method != METHOD_MPUIO))
+	if (mpuio_init_done || (!bank->stride))
 		return;
 
 	platform_set_drvdata(&omap_mpuio_device, bank);
@@ -852,7 +818,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
 {
 	void __iomem *base = bank->base;
 
-	if (bank->method == METHOD_MPUIO)
+	if (bank->stride)
 		return gpio_mpuio_read(base, OMAP_MPUIO_IO_CNTL / bank->stride)
 				& mask;
 	else
@@ -930,9 +896,7 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
 {
 	u32 rev;
 
-	if ((bank->method == METHOD_GPIO_24XX) ||
-			(bank->method == METHOD_GPIO_44XX) ||
-			(bank->method == METHOD_GPIO_1610))
+	if (bank->features_flag & BIT(OMAP_GPIO_REV_SHOW_FLAG))
 		rev = gpio_fn.gpio_read(bank->base, REV);
 	else
 		return;
@@ -964,7 +928,7 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 	bank->chip.set_debounce = gpio_debounce;
 	bank->chip.set = gpio_set;
 	bank->chip.to_irq = gpio_2irq;
-	if (bank->method == METHOD_MPUIO) {
+	if (bank->stride) {
 		bank->chip.label = "mpuio";
 		if (bank->suspend_resume_support)
 			bank->chip.dev = &omap_mpuio_device.dev;
@@ -982,7 +946,7 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 		     j < bank->virtual_irq_start + bank_width; j++) {
 		irq_set_lockdep_class(j, &gpio_lock_class);
 		irq_set_chip_data(j, bank);
-		if (bank->method == METHOD_MPUIO) {
+		if (bank->stride) {
 			if (bank->suspend_resume_support)
 				/*
 				 * REVISIT: assuming only 16xx supports
@@ -1028,11 +992,11 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	bank->virtual_irq_start = pdata->virtual_irq_start;
 
 	bank->id = pdev->id;
-	bank->method = pdata->bank_type;
 	bank->dev = &pdev->dev;
 	bank->dbck_flag = pdata->dbck_flag;
 	bank->stride = pdata->bank_stride;
 	bank->suspend_resume_support = pdata->suspend_resume_support;
+	bank->features_flag = pdata->features;
 	bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
 	bank_width = pdata->bank_width;
 
@@ -1072,7 +1036,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	pm_runtime_enable(bank->dev);
 	pm_runtime_get_sync(bank->dev);
 
-	if (bank->method == METHOD_MPUIO)
+	if (bank->stride)
 		__raw_writew(0xffff, bank->base +
 			OMAP_MPUIO_GPIO_MASKIT / bank->stride);
 	else
@@ -1099,7 +1063,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 		gpio_init_done = 1;
 	}
 
-	if ((bank->method != METHOD_MPUIO) && (!show_rev)) {
+	if (!show_rev) {
 		omap_gpio_show_rev(bank);
 		show_rev = 1;
 	}
@@ -1117,10 +1081,10 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 		u32 wake_set;
 		unsigned long flags;
 
-		if ((bank->method <= METHOD_GPIO_1510) ||
-				(bank->method == METHOD_GPIO_7XX)) {
+		if (!bank->suspend_resume_support)
 			break;
-		} else if (bank->method == METHOD_GPIO_44XX) {
+
+		if (bank->features_flag & BIT(OMAP_GPIO_IRQ_WK_ENA_REG_FLAG)) {
 			wake_status = IRQWAKEN0;
 			wake_clear = IRQWAKEN0;
 			wake_set = IRQWAKEN0;
@@ -1150,10 +1114,10 @@ static int omap_gpio_resume(struct sys_device *dev)
 		u32 wake_set;
 		unsigned long flags;
 
-		if ((bank->method <= METHOD_GPIO_1510) ||
-				(bank->method == METHOD_GPIO_7XX)) {
+		if (!bank->suspend_resume_support)
 			break;
-		} else if (bank->method == METHOD_GPIO_44XX) {
+
+		if (bank->features_flag & BIT(OMAP_GPIO_IRQ_WK_ENA_REG_FLAG)) {
 			wake_clear = IRQWAKEN0;
 			wake_set = IRQWAKEN0;
 		} else {
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 87fee8d..af1c636 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -59,12 +59,44 @@
 				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
 				 IH_GPIO_BASE + (nr))
 
-#define METHOD_MPUIO		0
-#define METHOD_GPIO_1510	1
-#define METHOD_GPIO_1610	2
-#define METHOD_GPIO_7XX		3
-#define METHOD_GPIO_24XX	5
-#define METHOD_GPIO_44XX	6
+/* OMAP GPIO feature support flags */
+enum omap_gpio_features {
+	/* programmable clk gating at module level. True for OMAP2PLUS */
+	OMAP_GPIO_CLK_GATING_FLAG,
+	/* Revision register is available. True for OMAP16xx and OMAP2PLUS */
+	OMAP_GPIO_REV_SHOW_FLAG,
+	/* Separate IRQ Wakeup Enable Register. True for OMAP4 */
+	OMAP_GPIO_IRQ_WK_ENA_REG_FLAG,
+	/*
+	 * Dataout register is separate for setting and clearing dataout line.
+	 * True for OMAP16XX and OMAP2PLUS.
+	 */
+	OMAP_GPIO_DATAOUT_SET_CLR_REGS_FLAG,
+	/*
+	 * Workaround required for clearing DSP GPIO interrupts to allow
+	 * retention. True for OMAP4
+	 */
+	OMAP_GPIO_WA_CLR_DSP_INT_FLAG,
+	/* OMAP15XX requires claiming GPIO pin for MPU before accessing it */
+	OMAP_GPIO_CLAIM_PIN_FOR_MPU_FLAG,
+	/*
+	 * Log the edge gpio and manually trigger the IRQ after resume if the
+	 * input level changes to avoid irq lost during PER RET/OFF mode. True
+	 * for omap2 non-wakeup gpio and all omap3 gpios
+	 * TODO: Check if this is applicable for OMAP4 as well
+	 */
+	OMAP_GPIO_HANDLE_IRQ_LOSS_LOW_PWR_FLAG,
+	/*
+	 * Level triggering supported. True only for OMAP2PLUS.
+	 * OMAP1 allows only only edge triggering.
+	 */
+	OMAP_GPIO_LEVEL_TRIGGER_FLAG,
+	/*
+	 * Can do both rising and falling edge detection at once.
+	 * True for OMAP16XX and OMAP2PLUS.
+	 */
+	OMAP_GPIO_DUAL_EDGE_TRIG_FLAG,
+};
 
 enum omap_gpio_reg_offsets {
 	/* Common Registers*/
@@ -130,12 +162,12 @@ struct omap_gpio_func {
 struct omap_gpio_platform_data {
 	u16 virtual_irq_start;
 	struct omap_gpio_func *gpio_fn;
-	int bank_type;
 	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 suspend_resume_support; /* True for OMAP16XX, OMAP2PLUS */
 	u32 non_wakeup_gpios;
+	u32 features;		/* see enum omap_gpio_features */
 };
 
 extern void omap2_gpio_prepare_for_idle(int off_mode);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (17 preceding siblings ...)
  2011-04-22 11:08 ` [RFC PATCH 18/18] OMAP: GPIO: Remove usage of bank method Charulatha V
@ 2011-04-22 14:02 ` Sascha Hauer
  2011-04-22 22:34 ` Kevin Hilman
  19 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2011-04-22 14:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Fri, Apr 22, 2011 at 04:38:14PM +0530, Charulatha V wrote:
> Modifies the OMAP GPIO driver to avoid usage of cpu_is* checks
> for different OMAP architectures. This is done by moving some
> architecture specific code to mach-omap* and call them from
> plat-omap* using function pointers. Also remove the register offset
> macros from OMAP GPIO driver and handle the same in mach-omap*.
> 
> Avoid usage of gpio_bank_count and gpio_bank pointer array by
> means of maintaining a list. Removes the bank->method flag from
> the GPIO driver.
> 
> All OMAP1 SoCs has one MPUIO type GPIO bank. OMAP2+ does not have
> any MPUIO type GPIO bank. Since MPUIO type GPIO bank is the same for
> all OMAP1 CPUs, they are handled in plat-omap/ itself as
> there is no common gpio.c file for all cpu types in mach-omap1.
> They are identified by using bank->stride flag as it is '0'
> for other than MPUIO type banks.

The omap gpio code clearly deserves a cleanup, but I think this series
does not go far enough. There are only a handful of possible ways to
implement a gpio hardware, most of them can be abstracted in a similar
way Thomas did for the irq handlers and then we can handle most SoC
specific gpio code in generic code.

Something like the following comes to my mind:

struct gpio_chip_mmio_regs {
	unsigned long output_set_reg;
	unsigned long output_clean_reg;
	unsigned long direction_reg;
	unsigned long status_reg;
};

struct gpio_chip_mmio {
	struct gpio_chip_mmio_regs *regs;
	void __iomem *base;
	void (*direction_output)(struct gpio_chip_mmio *, int);
	void (*direction_input)(struct gpio_chip_mmio *, int);
	struct gpio_chip chip;
};

int gpio_chip_mmio_add(struct gpio_chip_mmio *);

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap
  2011-04-22 11:08 ` [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap Charulatha V
@ 2011-04-22 14:59   ` Kevin Hilman
  0 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-04-22 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

Charulatha V <charu@ti.com> writes:

> gpio_get_index() uses cpu_is* checks. Move this function from
> plat-omap/gpio.c to SoC specific GPIO files in mach-omap*/ and
> use pdata to pass the function pointer.
>
> Signed-off-by: Charulatha V <charu@ti.com>

This one isn't really needed.  The index should be calculated by using
the bank width.

Below is a patch doing the same thing but using bitops and avoiding the
need for pdata function pointers.

Kevin

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files
  2011-04-22 11:08 ` [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files Charulatha V
@ 2011-04-22 15:15   ` Kevin Hilman
  0 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-04-22 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

Charulatha V <charu@ti.com> writes:

> gpio_valid() implementation is different for different SoCs.
> Hence handle them in SoC specific gpio files.
>
> Signed-off-by: Charulatha V <charu@ti.com>

This one is only moving the mess into SoC-specific code.

Looking closer at the gpio_valid() (and check_gpio()) calls, they are
actually pointless.  These functions are only called in a few places,
and where they are called, the GPIO has already been converted from an
IRQ or masked, so these functions will never fail.

Kevin

> ---
>  arch/arm/mach-omap1/gpio15xx.c         |   26 ++++++++++++++++++++-
>  arch/arm/mach-omap1/gpio16xx.c         |   32 ++++++++++++++++++++++----
>  arch/arm/mach-omap1/gpio7xx.c          |   38 ++++++++++++++++++++++++++------
>  arch/arm/mach-omap2/gpio.c             |   14 +++++++++++-
>  arch/arm/plat-omap/gpio.c              |   27 +---------------------
>  arch/arm/plat-omap/include/plat/gpio.h |    1 +
>  6 files changed, 98 insertions(+), 40 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
> index eb2727a..9d7a3fa 100644
> --- a/arch/arm/mach-omap1/gpio15xx.c
> +++ b/arch/arm/mach-omap1/gpio15xx.c
> @@ -22,6 +22,10 @@
>  #define OMAP1510_GPIO_BASE		0xFFFCE000
>  
>  #define OMAP1510_GPIO_INDEX_MASK	0x0f
> +#define OMAP1510_GPIO_WIDTH		16
> +#define OMAP1510_GPIO_BANK_CNT		2
> +#define OMAP1510_NON_MPUIO_GPIO_VALID	((OMAP1510_GPIO_BANK_CNT - 1) *\
> +						OMAP1510_GPIO_WIDTH)
>  
>  /* gpio1 */
>  static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
> @@ -39,7 +43,7 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
>  	.virtual_irq_start	= IH_MPUIO_BASE,
>  	.bank_type		= METHOD_MPUIO,
> -	.bank_width		= 16,
> +	.bank_width		= OMAP1510_GPIO_WIDTH,
>  	.bank_stride		= 1,
>  };
>  
> @@ -69,7 +73,7 @@ static struct __initdata resource omap15xx_gpio_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE,
>  	.bank_type		= METHOD_GPIO_1510,
> -	.bank_width		= 16,
> +	.bank_width		= OMAP1510_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap15xx_gpio = {
> @@ -87,8 +91,26 @@ static int get_gpio_index(int gpio)
>  	return gpio & OMAP1510_GPIO_INDEX_MASK;
>  }
>  
> +static int gpio_valid(int gpio)
> +{
> +	if (gpio < 0)
> +		return -EINVAL;
> +
> +	if (OMAP_GPIO_IS_MPUIO(gpio)) {
> +		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP1510_GPIO_WIDTH)
> +			return -EINVAL;
> +		return 0;
> +	}
> +
> +	if (gpio < OMAP1510_NON_MPUIO_GPIO_VALID)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
>  static struct omap_gpio_func gpio_fn = {
>  	.get_index = get_gpio_index,
> +	.gpio_valid = gpio_valid,
>  };
>  
>  /*
> diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
> index 9d8aabc..e6bb080 100644
> --- a/arch/arm/mach-omap1/gpio16xx.c
> +++ b/arch/arm/mach-omap1/gpio16xx.c
> @@ -25,6 +25,10 @@
>  #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
>  
>  #define OMAP1610_GPIO_INDEX_MASK	0x0f
> +#define OMAP1610_GPIO_WIDTH		16
> +#define OMAP1610_GPIO_BANK_CNT		5
> +#define OMAP1610_NON_MPUIO_GPIO_VALID	((OMAP1610_GPIO_BANK_CNT - 1) *\
> +						OMAP1610_GPIO_WIDTH)
>  
>  /* mpu gpio */
>  static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
> @@ -42,7 +46,7 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
>  	.virtual_irq_start	= IH_MPUIO_BASE,
>  	.bank_type		= METHOD_MPUIO,
> -	.bank_width		= 16,
> +	.bank_width		= OMAP1610_GPIO_WIDTH,
>  	.bank_stride		= 1,
>  };
>  
> @@ -72,7 +76,7 @@ static struct __initdata resource omap16xx_gpio1_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE,
>  	.bank_type		= METHOD_GPIO_1610,
> -	.bank_width		= 16,
> +	.bank_width		= OMAP1610_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap16xx_gpio1 = {
> @@ -101,7 +105,7 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {
>  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,
> +	.bank_width		= OMAP1610_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap16xx_gpio2 = {
> @@ -130,7 +134,7 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {
>  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,
> +	.bank_width		= OMAP1610_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap16xx_gpio3 = {
> @@ -159,7 +163,7 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {
>  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,
> +	.bank_width		= OMAP1610_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap16xx_gpio4 = {
> @@ -185,8 +189,26 @@ static int get_gpio_index(int gpio)
>  	return gpio & OMAP1610_GPIO_INDEX_MASK;
>  }
>  
> +static int gpio_valid(int gpio)
> +{
> +	if (gpio < 0)
> +		return -EINVAL;
> +
> +	if (OMAP_GPIO_IS_MPUIO(gpio)) {
> +		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP1610_GPIO_WIDTH)
> +			return -EINVAL;
> +		return 0;
> +	}
> +
> +	if (gpio < OMAP1610_NON_MPUIO_GPIO_VALID)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
>  static struct omap_gpio_func gpio_fn = {
>  	.get_index = get_gpio_index,
> +	.gpio_valid = gpio_valid,
>  };
>  
>  /*
> diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
> index 74456a9..bd6fc8e 100644
> --- a/arch/arm/mach-omap1/gpio7xx.c
> +++ b/arch/arm/mach-omap1/gpio7xx.c
> @@ -28,6 +28,12 @@
>  
>  #define OMAP7XX_GPIO_INDEX_MASK		0x1f
>  
> +#define OMAP7XX_GPIO_WIDTH		32
> +#define OMAP7XX_MPUIO_GPIO_PIN_CNT	16
> +#define OMAP7XX_GPIO_BANK_CNT		7
> +#define OMAP7XX_NON_MPUIO_GPIO_VALID	((OMAP7XX_GPIO_BANK_CNT - 1) *\
> +						OMAP7XX_GPIO_WIDTH)
> +
>  /* mpu gpio */
>  static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
>  	{
> @@ -44,7 +50,7 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
>  	.virtual_irq_start	= IH_MPUIO_BASE,
>  	.bank_type		= METHOD_MPUIO,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  	.bank_stride		= 2,
>  };
>  
> @@ -74,7 +80,7 @@ static struct __initdata resource omap7xx_gpio1_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio1 = {
> @@ -103,7 +109,7 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE + 32,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio2 = {
> @@ -132,7 +138,7 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE + 64,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio3 = {
> @@ -161,7 +167,7 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE + 96,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio4 = {
> @@ -190,7 +196,7 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE + 128,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio5 = {
> @@ -219,7 +225,7 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {
>  static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
>  	.virtual_irq_start	= IH_GPIO_BASE + 160,
>  	.bank_type		= METHOD_GPIO_7XX,
> -	.bank_width		= 32,
> +	.bank_width		= OMAP7XX_GPIO_WIDTH,
>  };
>  
>  static struct __initdata platform_device omap7xx_gpio6 = {
> @@ -247,8 +253,26 @@ static int get_gpio_index(int gpio)
>  	return gpio & OMAP7XX_GPIO_INDEX_MASK;
>  }
>  
> +static int gpio_valid(int gpio)
> +{
> +	if (gpio < 0)
> +		return -EINVAL;
> +
> +	if (OMAP_GPIO_IS_MPUIO(gpio)) {
> +		if (gpio >= OMAP_MAX_GPIO_LINES + OMAP7XX_MPUIO_GPIO_PIN_CNT)
> +			return -EINVAL;
> +		return 0;
> +	}
> +
> +	if (gpio < OMAP7XX_NON_MPUIO_GPIO_VALID)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
>  static struct omap_gpio_func gpio_fn = {
>  	.get_index = get_gpio_index,
> +	.gpio_valid = gpio_valid,
>  };
>  
>  /*
> diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
> index 498ab92..08ee5f1 100644
> --- a/arch/arm/mach-omap2/gpio.c
> +++ b/arch/arm/mach-omap2/gpio.c
> @@ -26,6 +26,8 @@
>  
>  #define OMAP2_GPIO_INDEX_MASK		0x1f
>  
> +int bank_width;
> +
>  static struct omap_device_pm_latency omap_gpio_latency[] = {
>  	[0] = {
>  		.deactivate_func = omap_device_idle_hwmods,
> @@ -39,8 +41,17 @@ static int get_gpio_index(int gpio)
>  	return gpio & OMAP2_GPIO_INDEX_MASK;
>  }
>  
> +static int gpio_valid(int gpio)
> +{
> +	if ((gpio >= 0) && (gpio < (gpio_bank_count * bank_width)))
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
>  static struct omap_gpio_func gpio_fn = {
>  	.get_index = get_gpio_index,
> +	.gpio_valid = gpio_valid,
>  };
>  
>  static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
> @@ -68,7 +79,8 @@ 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;
> +	bank_width = dev_attr->bank_width;
> +	pdata->bank_width = bank_width;
>  	pdata->dbck_flag = dev_attr->dbck_flag;
>  	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
>  	pdata->gpio_fn = &gpio_fn;
> diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
> index e70bb6e..0f1dbbf 100644
> --- a/arch/arm/plat-omap/gpio.c
> +++ b/arch/arm/plat-omap/gpio.c
> @@ -190,33 +190,9 @@ static int bank_width;
>  /* TODO: Analyze removing gpio_bank_count usage from driver code */
>  int gpio_bank_count;
>  
> -static inline int gpio_valid(int gpio)
> -{
> -	if (gpio < 0)
> -		return -1;
> -	if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
> -		if (gpio >= OMAP_MAX_GPIO_LINES + 16)
> -			return -1;
> -		return 0;
> -	}
> -	if (cpu_is_omap15xx() && gpio < 16)
> -		return 0;
> -	if ((cpu_is_omap16xx()) && gpio < 64)
> -		return 0;
> -	if (cpu_is_omap7xx() && gpio < 192)
> -		return 0;
> -	if (cpu_is_omap2420() && gpio < 128)
> -		return 0;
> -	if (cpu_is_omap2430() && gpio < 160)
> -		return 0;
> -	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
> -		return 0;
> -	return -1;
> -}
> -
>  static int check_gpio(int gpio)
>  {
> -	if (unlikely(gpio_valid(gpio) < 0)) {
> +	if (unlikely(gpio_fn.gpio_valid(gpio) < 0)) {
>  		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
>  		dump_stack();
>  		return -1;
> @@ -1666,6 +1642,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
>  			mpuio_init();
>  
>  		gpio_fn.get_index = pdata->gpio_fn->get_index;
> +		gpio_fn.gpio_valid = pdata->gpio_fn->gpio_valid;
>  	}
>  
>  	id = pdev->id;
> diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
> index 1cfb01b..00586ad 100644
> --- a/arch/arm/plat-omap/include/plat/gpio.h
> +++ b/arch/arm/plat-omap/include/plat/gpio.h
> @@ -73,6 +73,7 @@ struct omap_gpio_dev_attr {
>  
>  struct omap_gpio_func {
>  	int (*get_index)(int gpio);
> +	int (*gpio_valid)(int gpio);
>  };
>  
>  struct omap_gpio_platform_data {

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 05/18] OMAP: GPIO: cleanup datain, dataout, set dir funcs
  2011-04-22 11:08 ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain,dataout,set dir funcs Charulatha V
@ 2011-04-22 15:22   ` Kevin Hilman
  0 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-04-22 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

Charulatha V <charu@ti.com> writes:

> * Define gpio register offsets in SoC specific GPIO files and use
>   these register offsets while doing register read/write
> * Remove the usage of CONFIG_ARCH_* checks and cpu_is* checks from
>   the below functions
> 	_set_gpio_direction
> 	_set_gpio_dataout
> 	_get_gpio_dataout
> 	_get_gpio_datain
> * MPUIO is a common gpio bank->method for OMAP15xx, OMAP16xx and
>   OMAP7xx SoCs. Each of these SoCs has one bank with MPUIO type.
>   Hence handle MPUIO type GPIO banks in GPIO driver.
>
> Note: After the complete driver is cleaned up, the register offset
> macros defined in OMAP GPIO driver would be removed
>
> Signed-off-by: Charulatha V <charu@ti.com>

IMO, this isn't quite the direction we want to go for this cleanup.  

Register offsets should indeed be in SoC specific files, but rather than
the driver calling pdata function pointers for the functions, the
register offsets should instead be passed into the driver so the driver
can have common functions.

Also, MPUIO doesn't need to be treated as a special case.   From the
GPIO driver perspective, it's just another GPIO bank.  On some SoCs, it
happens to have a different width and stride, but the drive should
handle that.

I've also started on a GPIO cleanup (currently posted to linux-omap
only) and I've taken a different approach.

After I finish reviewing your series, I'll have some more ideas on
how we might combine our efforts here.

Kevin

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count
  2011-04-22 11:08 ` [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count Charulatha V
@ 2011-04-22 16:04   ` Kevin Hilman
  0 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-04-22 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

Charulatha V <charu@ti.com> writes:

> gpio_bank_count is the count of number of GPIO devices
> in a SoC. Remove this dependency from the driver. Also remove
> the dependency on array of pointers to gpio_bank struct of
> all GPIO devices.
>
> The cpu_is*() checks used in omap2_gpio_prepare_for_idle() and
> omap2_gpio_resume_after_idle() would be removed in one of the
> patches in this series
>
> Signed-off-by: Charulatha V <charu@ti.com>
> ---
>  arch/arm/mach-omap1/gpio15xx.c         |    1 -
>  arch/arm/mach-omap1/gpio16xx.c         |    2 -
>  arch/arm/mach-omap1/gpio7xx.c          |    2 -
>  arch/arm/mach-omap2/gpio.c             |    1 +
>  arch/arm/plat-omap/gpio.c              |  165 ++++++++++++++++----------------
>  arch/arm/plat-omap/include/plat/gpio.h |    3 -
>  6 files changed, 83 insertions(+), 91 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
> index 7a7a123..3763db3 100644
> --- a/arch/arm/mach-omap1/gpio15xx.c
> +++ b/arch/arm/mach-omap1/gpio15xx.c
> @@ -189,7 +189,6 @@ static int __init omap15xx_gpio_init(void)
>  	omap15xx_mpu_gpio_config.gpio_fn = &gpio_fn;
>  	platform_device_register(&omap15xx_gpio);
>  
> -	gpio_bank_count = 2;
>  	return 0;
>  }
>  postcore_initcall(omap15xx_gpio_init);
> diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
> index f05e0c7..6a99b01 100644
> --- a/arch/arm/mach-omap1/gpio16xx.c
> +++ b/arch/arm/mach-omap1/gpio16xx.c
> @@ -316,8 +316,6 @@ static int __init omap16xx_gpio_init(void)
>  		platform_device_register(omap16xx_gpio_dev[i]);
>  	}
>  
> -	gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
> -
>  	return 0;
>  }
>  postcore_initcall(omap16xx_gpio_init);
> diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
> index 1103efc..cd6bad7 100644
> --- a/arch/arm/mach-omap1/gpio7xx.c
> +++ b/arch/arm/mach-omap1/gpio7xx.c
> @@ -355,8 +355,6 @@ static int __init omap7xx_gpio_init(void)
>  		platform_device_register(omap7xx_gpio_dev[i]);
>  	}
>  
> -	gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
> -
>  	return 0;
>  }
>  postcore_initcall(omap7xx_gpio_init);
> diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
> index 25fe8a4..a46f4a5 100644
> --- a/arch/arm/mach-omap2/gpio.c
> +++ b/arch/arm/mach-omap2/gpio.c
> @@ -28,6 +28,7 @@
>  #define OMAP2_GPIO_INDEX_MASK		0x1f
>  #define OMAP2_GPIO_IRQENA_MASK		0xffffffff
>  
> +int gpio_bank_count;

Why is this needed here?

>  int bank_width;
>  static u16 *reg_map;
>  static u16 omap2_gpio_reg_offsets[] = {

[...]

>  void omap2_gpio_prepare_for_idle(int off_mode)
>  {
> -	int i, c = 0;
> -	int min = 0;
> -
> -	if (cpu_is_omap34xx())
> -		min = 1;
> +	int c = 0;
> +	struct gpio_bank *bank;
>  
> -	for (i = min; i < gpio_bank_count; i++) {
> -		struct gpio_bank *bank = &gpio_bank[i];
> +	list_for_each_entry(bank, &omap_gpio_list, node) {


Note that on 34xx, this isn't an equivalent functional change, since
the for loop starts a 1 and the list traversal covers all banks.

I think your powerdomain 'can lose context' patch is needed before this
one.

Kevin

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver
  2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
                   ` (18 preceding siblings ...)
  2011-04-22 14:02 ` [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Sascha Hauer
@ 2011-04-22 22:34 ` Kevin Hilman
  2011-04-25 14:03   ` Varadarajan, Charulatha
  19 siblings, 1 reply; 26+ messages in thread
From: Kevin Hilman @ 2011-04-22 22:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Charu,

Charulatha V <charu@ti.com> writes:

> Modifies the OMAP GPIO driver to avoid usage of cpu_is* checks
> for different OMAP architectures. This is done by moving some
> architecture specific code to mach-omap* and call them from
> plat-omap* using function pointers. Also remove the register offset
> macros from OMAP GPIO driver and handle the same in mach-omap*.

Thanks for working on this cleanup, this driver really needs a cleanup.

You've hit on all the main areas for cleanup, but unfortunately, it's
not really going in the direction I was hoping.  Rather than moving code
into the SoC specific parts, I was hoping to generalize the driver such
that SoC-specific code would just pass in register offsets/options into
the common driver.  Your current approach isn't really reducing code,
it's just moving it around.

I had started on a similar cleanup as well, and will post that series
shortly to demonstrate the direction I think the cleanups should be
going.  I've tackled most of the same functions/areas that you have
(except the IRQ triggering stuff), but have a rather different approach.
I'll get to the IRQ triggering stuff next (after going on vacation for a
week), but feel free to build on top of my series if you like.

The direction I'd like to go is towards having a generalized driver that
can not only work across all OMAP SoCs, but also hopefully towards
something that can be shared with other SoCs as well.  Of course, the
first step is cleaning up the OMAP driver, but the next step will be
looking for other areas of consolidation.  Towards that end, I'm also
working towards converting the GPIO IRQs in this driver to use the new
generic IRQ chip infrastructure posted by Thomas Gleixner.  In my
series, you'll see that I started that for the MPUIO IRQs, but the GPIO
IRQs will come next.

Kevin

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver
  2011-04-22 22:34 ` Kevin Hilman
@ 2011-04-25 14:03   ` Varadarajan, Charulatha
  0 siblings, 0 replies; 26+ messages in thread
From: Varadarajan, Charulatha @ 2011-04-25 14:03 UTC (permalink / raw)
  To: linux-arm-kernel

Kevin,

Thanks for your comments.

On Sat, Apr 23, 2011 at 04:04, Kevin Hilman <khilman@ti.com> wrote:
> Hi Charu,
>
> Charulatha V <charu@ti.com> writes:
>
>> Modifies the OMAP GPIO driver to avoid usage of cpu_is* checks
>> for different OMAP architectures. This is done by moving some
>> architecture specific code to mach-omap* and call them from
>> plat-omap* using function pointers. Also remove the register offset
>> macros from OMAP GPIO driver and handle the same in mach-omap*.
>
> Thanks for working on this cleanup, this driver really needs a cleanup.
>
> You've hit on all the main areas for cleanup, but unfortunately, it's
> not really going in the direction I was hoping. ?Rather than moving code
> into the SoC specific parts, I was hoping to generalize the driver such
> that SoC-specific code would just pass in register offsets/options into
> the common driver. ?Your current approach isn't really reducing code,
> it's just moving it around.
>
> I had started on a similar cleanup as well, and will post that series
> shortly to demonstrate the direction I think the cleanups should be
> going. ?I've tackled most of the same functions/areas that you have
> (except the IRQ triggering stuff), but have a rather different approach.
> I'll get to the IRQ triggering stuff next (after going on vacation for a
> week), but feel free to build on top of my series if you like.

Sure. I will wait for your series.

-V Charulatha

>
> The direction I'd like to go is towards having a generalized driver that
> can not only work across all OMAP SoCs, but also hopefully towards
> something that can be shared with other SoCs as well. ?Of course, the
> first step is cleaning up the OMAP driver, but the next step will be
> looking for other areas of consolidation. ?Towards that end, I'm also
> working towards converting the GPIO IRQs in this driver to use the new
> generic IRQ chip infrastructure posted by Thomas Gleixner. ?In my
> series, you'll see that I started that for the MPUIO IRQs, but the GPIO
> IRQs will come next.
>
> Kevin
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-04-25 14:03 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-22 11:08 [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Charulatha V
2011-04-22 11:08 ` [RFC PATCH 01/18] OMAP1: GPIO: Fix mpuio_init() call Charulatha V
2011-04-22 11:08 ` [RFC PATCH 02/18] OMAP: GPIO: remove get_gpio_bank() Charulatha V
2011-04-22 11:08 ` [RFC PATCH 03/18] OMAP: GPIO: Move gpio_get_index() to mach-omap Charulatha V
2011-04-22 14:59   ` Kevin Hilman
2011-04-22 11:08 ` [RFC PATCH 04/18] OMAP: GPIO: Move gpio_valid() to SoC specific files Charulatha V
2011-04-22 15:15   ` Kevin Hilman
2011-04-22 11:08 ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain,dataout,set dir funcs Charulatha V
2011-04-22 15:22   ` [RFC PATCH 05/18] OMAP: GPIO: cleanup datain, dataout, set " Kevin Hilman
2011-04-22 11:08 ` [RFC PATCH 06/18] OMAP: GPIO: cleanup set trigger func Charulatha V
2011-04-22 11:08 ` [RFC PATCH 07/18] OMAP: GPIO: cleanup set/get IRQ, clr irqstatus funcs Charulatha V
2011-04-22 11:08 ` [RFC PATCH 08/18] OMAP: GPIO: req/free: Remove reg offset macros usage Charulatha V
2011-04-22 11:08 ` [RFC PATCH 09/18] OMAP: GPIO: cleanup gpio_irq_handler Charulatha V
2011-04-22 11:08 ` [RFC PATCH 10/18] OMAP: GPIO: cleanup set wakeup/suspend/resume funcs Charulatha V
2011-04-22 11:08 ` [RFC PATCH 11/18] OMAP: GPIO: Remove dependency on gpio_bank_count Charulatha V
2011-04-22 16:04   ` Kevin Hilman
2011-04-22 11:08 ` [RFC PATCH 12/18] OMAP: GPIO: cleanup set_debounce, idle/resume_after_idle Charulatha V
2011-04-22 11:08 ` [RFC PATCH 13/18] OMAP: GPIO: cleanup save/restore context Charulatha V
2011-04-22 11:08 ` [RFC PATCH 14/18] OMAP: GPIO: Remove CONFIG_ARCH_OMAP16XX/OMAP2+ defines Charulatha V
2011-04-22 11:08 ` [RFC PATCH 15/18] OMAP: GPIO: cleanup gpio_show_rev Charulatha V
2011-04-22 11:08 ` [RFC PATCH 16/18] OMAP: GPIO: move omap_gpio_mod_init to mach-omap Charulatha V
2011-04-22 11:08 ` [RFC PATCH 17/18] OMAP: GPIO: use dev_err* instead of printk Charulatha V
2011-04-22 11:08 ` [RFC PATCH 18/18] OMAP: GPIO: Remove usage of bank method Charulatha V
2011-04-22 14:02 ` [RFC PATCH 00/18] OMAP: GPIO: cleanup GPIO driver Sascha Hauer
2011-04-22 22:34 ` Kevin Hilman
2011-04-25 14:03   ` Varadarajan, Charulatha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).