All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13 v5] OMAP: GPIO: Implement GPIO in HWMOD way
@ 2010-08-06 12:34 Charulatha V
  2010-08-06 12:34 ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Charulatha V
  0 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V

This patch series makes OMAP2PLUS specific GPIO implemented in HWMOD
FW way. This is done by implementing GPIO module in platform device model.

This patch series is generated on "origin/pm-wip/hwmods-omap4".

This patch series is created on top of the following two patches:
- OMAP4: HWMOD: Do omap_hwmod_late_init for OMAP4
- musb: Kill board specific pinmux from driver file
	http://marc.info/?l=linux-usb&m=127858711304301&w=2
- Revert the following patch:
	OMAP: bus-level PM: enable use of runtime PM API for suspend/resume
	http://dev.omapzoom.org/?p=swarch/linux-omap-adv.git;a=commitdiff;h=8041359e18e49bf8a3d41f15894db9e476f3a8fc
	(or)
  Remove the locking in the omap_hwmod_for_each* function

This patch series is tested on OMAP4430 SDP board and OMAP3430 SDP board.
It would be of great help if someone could test the same on OMAP1
and OMAP2 boards.

Links to related discussions:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32833.html

Version History:
---------------
Comments Fixed in V5:
- Use dev_pm_ops instead of sys_dev_class
- Use runtime suspend/resume hooks for GPIO device
- extend the usage of mod_usage flag to all cpu classes.( Earlier it was
   used only for OMAP2PLUS)
- Make gpio_context as part of gpio_bank structure

v4 Series:
Some link for v4 series:
https://patchwork.kernel.org/patch/107411/

Comments Fixed in v4:
- Remove gpio_bank_count from dev_attr field and derive it from
   hwmod class iteration count
- Add TODOs for future omap gpio code cleanup related activity
- Rename gpio's platform_data 'method' to 'bank_type'
- Rename gpio's platform_data 'gpio_bank_bits' to 'gpio_bank_width'
- Add 'rev' field to gpio class in hwmod datbase and get 'bank_type'
   based on 'rev' field
- Filename removed from file description when a new file is created

Comments Fixed in v3:
- .module_offs populated in hwmod structures
- If not defined CONFIG_PM_RUNTIME is not handled in GPIO driver
- No changes to mach-omap2/clockxxxx-data.c to handle clocks by dev ptr
    as it is taken care using clock get by name in hwmod & omap_device layer
- Using "ick" instead of "arm_gpio_ck" for OMAP15xx clock
- SoC base addresses moved to plat-omap/omapXXXX.h that should be
    used only by the omap_hwmod_xxxx_data.c file
- OMAP2/3 hwmod structures naming convention changed as it is
    followed in OMAP4
- omap24xx_gpio_init() uses cpu_is_omap24xx() instead of separate
    checks for 2420 & 2430 in OMAP2 specific init call (mach-omap layer)
- Reason for using postcore_initcall is added to patch description for
    the patch "OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init"
- Comments added for usage of dbck_flag and other elements
    in dev_attr structure
- Uses dev_dbg() and dev_err() instead of pr_dbg() and pr_err()
- Corrects the gpio clock details in OMAP4 hwmod database


v2 series:
Some important links to patch v2 series and comments:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30262.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28787.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30263.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30295.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30259.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28933.html
Comments Fixed in V2:
- GPIO dev attr was added for SoC specific chip info (eg., gpio bank count)
- Removed omap_gpio_init() usage from board files 
- platform_get_resource() used instead of pdata->base for
    OMAP2+ base addresses
- postcore_initcall used for gpio init instead of making
    GPIO as an early platform device. SoC specific gpio_init
    needs to be done before machine_init functions access gpio
    APIs. Hence making SoC specific gpio_init as postcore_initcall.
- getting gpio dbck is moved to omap_set_gpio_debounce()
    instead of doing it in probe


v1 series:
Some important links to patch v1 series and comments:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg26934.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg27860.html
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg28183.html
Highlights in v1:
- Introduces SoC specific functions at mach-omap layer
- Implements GPIO as a platform device
- Make gpio an early device and make it implemented in
    HWMOD FW adapted way for OMAP2PLUS

Charulatha V (13):
  OMAP: GPIO: Modify init() in preparation for platform device
    implementation
  OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init
  OMAP: GPIO: Introduce support for OMAP16xx chip GPIO init
  OMAP: GPIO: Introduce support for OMAP7xx chip GPIO init
  OMAP: GPIO: add GPIO hwmods structures for OMAP3
  OMAP: GPIO: add GPIO hwmods structures for OMAP242X
  OMAP: GPIO: add GPIO hwmods structures for OMAP243X
  OMAP: GPIO: Add gpio dev_attr and correct clks in OMAP4 hwmod struct
  OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init
  OMAP: GPIO: Implement GPIO as a platform device
  OMAP: GPIO: Make gpio_context as part of gpio_bank structure
  OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  OMAP: GPIO: Remove omap_gpio_init()

 arch/arm/mach-omap1/Makefile               |    6 +
 arch/arm/mach-omap1/board-ams-delta.c      |    1 -
 arch/arm/mach-omap1/board-fsample.c        |    1 -
 arch/arm/mach-omap1/board-h2.c             |    1 -
 arch/arm/mach-omap1/board-h3.c             |    1 -
 arch/arm/mach-omap1/board-htcherald.c      |    1 -
 arch/arm/mach-omap1/board-innovator.c      |    1 -
 arch/arm/mach-omap1/board-nokia770.c       |    1 -
 arch/arm/mach-omap1/board-osk.c            |    1 -
 arch/arm/mach-omap1/board-palmte.c         |    1 -
 arch/arm/mach-omap1/board-palmz71.c        |    1 -
 arch/arm/mach-omap1/board-perseus2.c       |    1 -
 arch/arm/mach-omap1/board-sx1.c            |    1 -
 arch/arm/mach-omap1/board-voiceblue.c      |    1 -
 arch/arm/mach-omap1/clock_data.c           |    4 +-
 arch/arm/mach-omap1/gpio15xx.c             |  101 +++
 arch/arm/mach-omap1/gpio16xx.c             |  208 +++++
 arch/arm/mach-omap1/gpio7xx.c              |  274 ++++++
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/board-2430sdp.c        |    1 -
 arch/arm/mach-omap2/board-3430sdp.c        |    1 -
 arch/arm/mach-omap2/board-3630sdp.c        |    1 -
 arch/arm/mach-omap2/board-4430sdp.c        |    1 -
 arch/arm/mach-omap2/board-am3517evm.c      |    1 -
 arch/arm/mach-omap2/board-apollon.c        |    1 -
 arch/arm/mach-omap2/board-cm-t35.c         |    1 -
 arch/arm/mach-omap2/board-devkit8000.c     |    1 -
 arch/arm/mach-omap2/board-h4.c             |    1 -
 arch/arm/mach-omap2/board-igep0020.c       |    1 -
 arch/arm/mach-omap2/board-ldp.c            |    1 -
 arch/arm/mach-omap2/board-n8x0.c           |    1 -
 arch/arm/mach-omap2/board-omap3beagle.c    |    1 -
 arch/arm/mach-omap2/board-omap3evm.c       |    1 -
 arch/arm/mach-omap2/board-omap3pandora.c   |    1 -
 arch/arm/mach-omap2/board-omap3stalker.c   |    1 -
 arch/arm/mach-omap2/board-omap3touchbook.c |    1 -
 arch/arm/mach-omap2/board-omap4panda.c     |    1 -
 arch/arm/mach-omap2/board-overo.c          |    1 -
 arch/arm/mach-omap2/board-rx51.c           |    1 -
 arch/arm/mach-omap2/board-zoom2.c          |    1 -
 arch/arm/mach-omap2/board-zoom3.c          |    1 -
 arch/arm/mach-omap2/gpio.c                 |  120 +++
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  234 ++++++
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  290 +++++++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  382 +++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   40 +-
 arch/arm/mach-omap2/pm24xx.c               |    4 +-
 arch/arm/mach-omap2/pm34xx.c               |   23 +-
 arch/arm/plat-omap/gpio.c                  | 1259 ++++++++++++----------------
 arch/arm/plat-omap/include/plat/gpio.h     |   29 +-
 50 files changed, 2208 insertions(+), 803 deletions(-)
 create mode 100644 arch/arm/mach-omap1/gpio15xx.c
 create mode 100644 arch/arm/mach-omap1/gpio16xx.c
 create mode 100644 arch/arm/mach-omap1/gpio7xx.c
 create mode 100644 arch/arm/mach-omap2/gpio.c


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

* [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-06 12:34 [PATCH 00/13 v5] OMAP: GPIO: Implement GPIO in HWMOD way Charulatha V
@ 2010-08-06 12:34 ` Charulatha V
  2010-08-06 12:34   ` [PATCH 02/13 v5] OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init Charulatha V
  2010-08-09 22:20   ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Kevin Hilman
  0 siblings, 2 replies; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This is in prepartion for implementing GPIO as a platform device.
gpio bank's base addresses are moved from gpio.c to plat/gpio.h.

This patch also modifies omap_gpio_init() to make use of
omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init() does
the module init by clearing the status register and initializing the
GPIO control register. omap_gpio_chip_init() initializes the chip request,
free, get, set and other function pointers and sets the gpio irq handler.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/plat-omap/gpio.c |  235 +++++++++++++++++++++++----------------------
 1 files changed, 120 insertions(+), 115 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 7951eef..d013b45 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -190,14 +190,12 @@ struct gpio_bank {
 	u32 suspend_wakeup;
 	u32 saved_wakeup;
 #endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
 
 	u32 saved_datain;
 	u32 saved_fallingdetect;
 	u32 saved_risingdetect;
-#endif
 	u32 level_mask;
 	u32 toggle_mask;
 	spinlock_t lock;
@@ -1713,6 +1711,124 @@ static void __init omap_gpio_show_rev(void)
  */
 static struct lock_class_key gpio_lock_class;
 
+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);
+			/* Enable autoidle for the OCP interface */
+			omap_writel(1 << 0, 0x48306814);
+		} 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];
+
+			/* Enable autoidle for the OCP interface */
+			omap_writel(1 << 0, 0x48019010);
+		}
+	} else if (cpu_class_is_omap1()) {
+		if (bank_is_mpuio(bank))
+			__raw_writew(0xffff, bank->base
+						+ OMAP_MPUIO_GPIO_MASKIT);
+		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, bank_width = 16;
+	static int gpio;
+
+	if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
+		bank_width = 32; /* 7xx has 32-bit GPIOs */
+
+	if ((bank->method == METHOD_GPIO_24XX) ||
+			(bank->method == METHOD_GPIO_44XX))
+		bank_width = 32;
+
+	bank->mod_usage = 0;
+	/* REVISIT eventually switch from OMAP-specific gpio structs
+	 * over to the generic ones
+	 */
+	bank->chip.request = omap_gpio_request;
+	bank->chip.free = omap_gpio_free;
+	bank->chip.direction_input = gpio_input;
+	bank->chip.get = gpio_get;
+	bank->chip.direction_output = gpio_output;
+	bank->chip.set_debounce = gpio_debounce;
+	bank->chip.set = gpio_set;
+	bank->chip.to_irq = gpio_2irq;
+	if (bank_is_mpuio(bank)) {
+		bank->chip.label = "mpuio";
+#ifdef CONFIG_ARCH_OMAP16XX
+		bank->chip.dev = &omap_mpuio_device.dev;
+#endif
+		bank->chip.base = OMAP_MPUIO(0);
+	} else {
+		bank->chip.label = "gpio";
+		bank->chip.base = gpio;
+		gpio += bank_width;
+	}
+	bank->chip.ngpio = bank_width;
+
+	gpiochip_add(&bank->chip);
+
+	for (j = bank->virtual_irq_start;
+		     j < bank->virtual_irq_start + bank_width; j++) {
+		lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
+		set_irq_chip_data(j, bank);
+		if (bank_is_mpuio(bank))
+			set_irq_chip(j, &mpuio_irq_chip);
+		else
+			set_irq_chip(j, &gpio_irq_chip);
+		set_irq_handler(j, handle_simple_irq);
+		set_irq_flags(j, IRQF_VALID);
+	}
+	set_irq_chained_handler(bank->irq, gpio_irq_handler);
+	set_irq_data(bank->irq, bank);
+}
+
 static int __init _omap_gpio_init(void)
 {
 	int i;
@@ -1823,7 +1939,6 @@ static int __init _omap_gpio_init(void)
 	}
 #endif
 	for (i = 0; i < gpio_bank_count; i++) {
-		int j, gpio_count = 16;
 
 		bank = &gpio_bank[i];
 		spin_lock_init(&bank->lock);
@@ -1835,107 +1950,8 @@ static int __init _omap_gpio_init(void)
 			continue;
 		}
 
-		if (bank_is_mpuio(bank))
-			__raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
-		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);
-		}
-		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);
-
-			gpio_count = 32; /* 7xx has 32-bit GPIOs */
-		}
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-		if ((bank->method == METHOD_GPIO_24XX) ||
-				(bank->method == METHOD_GPIO_44XX)) {
-			static const u32 non_wakeup_gpios[] = {
-				0xe203ffc0, 0x08700040
-			};
-
-			if (cpu_is_omap44xx()) {
-				__raw_writel(0xffffffff, bank->base +
-						OMAP4_GPIO_IRQSTATUSCLR0);
-				__raw_writew(0x0015, bank->base +
-						OMAP4_GPIO_SYSCONFIG);
-				__raw_writel(0x00000000, bank->base +
-						 OMAP4_GPIO_DEBOUNCENABLE);
-				/*
-				 * Initialize interface clock ungated,
-				 * module enabled
-				 */
-				__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-			} else {
-				__raw_writel(0x00000000, bank->base +
-						OMAP24XX_GPIO_IRQENABLE1);
-				__raw_writel(0xffffffff, bank->base +
-						OMAP24XX_GPIO_IRQSTATUS1);
-				__raw_writew(0x0015, bank->base +
-						OMAP24XX_GPIO_SYSCONFIG);
-				__raw_writel(0x00000000, bank->base +
-						OMAP24XX_GPIO_DEBOUNCE_EN);
-
-				/*
-				 * Initialize interface clock ungated,
-				 * module enabled
-				 */
-				__raw_writel(0, bank->base +
-						OMAP24XX_GPIO_CTRL);
-			}
-			if (cpu_is_omap24xx() &&
-			    i < ARRAY_SIZE(non_wakeup_gpios))
-				bank->non_wakeup_gpios = non_wakeup_gpios[i];
-			gpio_count = 32;
-		}
-#endif
-
-		bank->mod_usage = 0;
-		/* REVISIT eventually switch from OMAP-specific gpio structs
-		 * over to the generic ones
-		 */
-		bank->chip.request = omap_gpio_request;
-		bank->chip.free = omap_gpio_free;
-		bank->chip.direction_input = gpio_input;
-		bank->chip.get = gpio_get;
-		bank->chip.direction_output = gpio_output;
-		bank->chip.set_debounce = gpio_debounce;
-		bank->chip.set = gpio_set;
-		bank->chip.to_irq = gpio_2irq;
-		if (bank_is_mpuio(bank)) {
-			bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
-			bank->chip.dev = &omap_mpuio_device.dev;
-#endif
-			bank->chip.base = OMAP_MPUIO(0);
-		} else {
-			bank->chip.label = "gpio";
-			bank->chip.base = gpio;
-			gpio += gpio_count;
-		}
-		bank->chip.ngpio = gpio_count;
-
-		gpiochip_add(&bank->chip);
-
-		for (j = bank->virtual_irq_start;
-		     j < bank->virtual_irq_start + gpio_count; j++) {
-			lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
-			set_irq_chip_data(j, bank);
-			if (bank_is_mpuio(bank))
-				set_irq_chip(j, &mpuio_irq_chip);
-			else
-				set_irq_chip(j, &gpio_irq_chip);
-			set_irq_handler(j, handle_simple_irq);
-			set_irq_flags(j, IRQF_VALID);
-		}
-		set_irq_chained_handler(bank->irq, gpio_irq_handler);
-		set_irq_data(bank->irq, bank);
+		omap_gpio_mod_init(bank, i);
+		omap_gpio_chip_init(bank);
 
 		if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 			sprintf(clk_name, "gpio%d_dbck", i + 1);
@@ -1945,17 +1961,6 @@ static int __init _omap_gpio_init(void)
 		}
 	}
 
-	/* Enable system clock for GPIO module.
-	 * The CAM_CLK_CTRL *is* really the right place. */
-	if (cpu_is_omap16xx())
-		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
-
-	/* Enable autoidle for the OCP interface */
-	if (cpu_is_omap24xx())
-		omap_writel(1 << 0, 0x48019010);
-	if (cpu_is_omap34xx())
-		omap_writel(1 << 0, 0x48306814);
-
 	omap_gpio_show_rev();
 
 	return 0;
-- 
1.6.3.3


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

* [PATCH 02/13 v5] OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init
  2010-08-06 12:34 ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Charulatha V
@ 2010-08-06 12:34   ` Charulatha V
  2010-08-06 12:34     ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " Charulatha V
  2010-08-09 22:20   ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Kevin Hilman
  1 sibling, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch introduces platform_data structure for GPIO
so that GPIO module can be implemented in platform device model.

This patch also adds support for handling OMAP15xx specific gpio_init
by providing platform device data and doing device registration.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap1/gpio15xx.c         |  101 ++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/gpio.c              |    7 --
 arch/arm/plat-omap/include/plat/gpio.h |   20 ++++++
 3 files changed, 121 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/mach-omap1/gpio15xx.c

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
new file mode 100644
index 0000000..b2daa66
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -0,0 +1,101 @@
+/*
+ * OMAP15XX-specific gpio code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ *	Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
+#define OMAP1510_GPIO_BASE		0xfffce000
+
+static struct omap_gpio_dev_attr omap15xx_gpio_attr = {
+	.bank_width = 16,
+};
+
+/*
+ * OMAP15XX GPIO1 interface data
+ */
+static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
+	{
+		.start	= OMAP1_MPUIO_VBASE,
+		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_MPUIO,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
+	.virtual_irq_start	= IH_MPUIO_BASE,
+	.bank_type		= METHOD_MPUIO,
+	.gpio_attr		= &omap15xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap15xx_mpu_gpio = {
+	.name           = "omap-gpio",
+	.id             = 0,
+	.dev            = {
+		.platform_data = &omap15xx_mpu_gpio_config,
+	},
+	.num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources),
+	.resource = omap15xx_mpu_gpio_resources,
+};
+
+/*
+ * OMAP15XX GPIO2 interface data
+ */
+static struct __initdata resource omap15xx_gpio_resources[] = {
+	{
+		.start	= OMAP1510_GPIO_BASE,
+		.end	= OMAP1510_GPIO_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_GPIO_BANK1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
+	.virtual_irq_start	= IH_GPIO_BASE,
+	.bank_type		= METHOD_GPIO_1510,
+	.gpio_attr		= &omap15xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap15xx_gpio = {
+	.name           = "omap-gpio",
+	.id             = 1,
+	.dev            = {
+		.platform_data = &omap15xx_gpio_config,
+	},
+	.num_resources = ARRAY_SIZE(omap15xx_gpio_resources),
+	.resource = omap15xx_gpio_resources,
+};
+
+/*
+ * omap15xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap15xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap15xx_gpio_init(void)
+{
+	if (!cpu_is_omap15xx())
+		return -EINVAL;
+
+	platform_device_register(&omap15xx_mpu_gpio);
+	platform_device_register(&omap15xx_gpio);
+
+	gpio_bank_count = 2,
+	return 0;
+}
+postcore_initcall(omap15xx_gpio_init);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index d013b45..dfe4b9e 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -205,13 +205,6 @@ struct gpio_bank {
 	u32 dbck_enable_mask;
 };
 
-#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
-
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
 	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index de1c604..67d0086 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -28,6 +28,7 @@
 
 #include <linux/io.h>
 #include <mach/irqs.h>
+#include <linux/platform_device.h>
 
 #define OMAP1_MPUIO_BASE			0xfffb5000
 
@@ -71,6 +72,25 @@
 				 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
+
+struct omap_gpio_dev_attr {
+	int bank_width;		/* GPIO bank width */
+	bool dbck_flag;		/* dbck validity - True only for OMAP3&4 */
+	bool off_mode_support;	/* True for OMAP3&4 non-wakeup domain GPIOs */
+};
+
+struct omap_gpio_platform_data {
+	u16 virtual_irq_start;
+	int bank_type;
+	struct omap_gpio_dev_attr *gpio_attr;
+};
+
 extern int omap_gpio_init(void);	/* Call from board init only */
 extern void omap2_gpio_prepare_for_idle(int power_state);
 extern void omap2_gpio_resume_after_idle(void);
-- 
1.6.3.3


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

* [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx chip GPIO init
  2010-08-06 12:34   ` [PATCH 02/13 v5] OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init Charulatha V
@ 2010-08-06 12:34     ` Charulatha V
  2010-08-06 12:34       ` [PATCH 04/13 v5] OMAP: GPIO: Introduce support for OMAP7xx " Charulatha V
  2010-08-09  3:51       ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " DebBarma, Tarun Kanti
  0 siblings, 2 replies; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch adds support for handling OMAP16xx specific gpio_init
by providing platform device data and doing device registration.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap1/gpio16xx.c |  208 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap1/gpio16xx.c

diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
new file mode 100644
index 0000000..727c52b
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -0,0 +1,208 @@
+/*
+ * OMAP16XX-specific gpio code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ *	Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1610_GPIO1_BASE		0xfffbe400
+#define OMAP1610_GPIO2_BASE		0xfffbec00
+#define OMAP1610_GPIO3_BASE		0xfffbb400
+#define OMAP1610_GPIO4_BASE		0xfffbbc00
+#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
+
+static struct omap_gpio_dev_attr omap16xx_gpio_attr = {
+	.bank_width = 16,
+};
+
+/*
+ * OMAP16XX MPU GPIO interface data
+ */
+static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
+	{
+		.start	= OMAP1_MPUIO_VBASE,
+		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_MPUIO,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
+	.virtual_irq_start	= IH_MPUIO_BASE,
+	.bank_type		= METHOD_MPUIO,
+	.gpio_attr		= &omap16xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap16xx_mpu_gpio = {
+	.name           = "omap-gpio",
+	.id             = 0,
+	.dev            = {
+		.platform_data = &omap16xx_mpu_gpio_config,
+	},
+	.num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
+	.resource = omap16xx_mpu_gpio_resources,
+};
+
+/*
+ * OMAP16XX GPIO1 interface data
+ */
+static struct __initdata resource omap16xx_gpio1_resources[] = {
+	{
+		.start	= OMAP1610_GPIO1_BASE,
+		.end	= OMAP1610_GPIO1_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_GPIO_BANK1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
+	.virtual_irq_start	= IH_GPIO_BASE,
+	.bank_type		= METHOD_GPIO_1610,
+	.gpio_attr		= &omap16xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap16xx_gpio1 = {
+	.name           = "omap-gpio",
+	.id             = 1,
+	.dev            = {
+		.platform_data = &omap16xx_gpio1_config,
+	},
+	.num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
+	.resource = omap16xx_gpio1_resources,
+};
+
+/*
+ * OMAP16XX GPIO2 interface data
+ */
+static struct __initdata resource omap16xx_gpio2_resources[] = {
+	{
+		.start	= OMAP1610_GPIO2_BASE,
+		.end	= OMAP1610_GPIO2_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_1610_GPIO_BANK2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 16,
+	.bank_type		= METHOD_GPIO_1610,
+	.gpio_attr		= &omap16xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap16xx_gpio2 = {
+	.name           = "omap-gpio",
+	.id             = 2,
+	.dev            = {
+		.platform_data = &omap16xx_gpio2_config,
+	},
+	.num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
+	.resource = omap16xx_gpio2_resources,
+};
+
+/*
+ * OMAP16XX GPIO3 interface data
+ */
+static struct __initdata resource omap16xx_gpio3_resources[] = {
+	{
+		.start	= OMAP1610_GPIO3_BASE,
+		.end	= OMAP1610_GPIO3_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_1610_GPIO_BANK3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 32,
+	.bank_type		= METHOD_GPIO_1610,
+	.gpio_attr		= &omap16xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap16xx_gpio3 = {
+	.name           = "omap-gpio",
+	.id             = 3,
+	.dev            = {
+		.platform_data = &omap16xx_gpio3_config,
+	},
+	.num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
+	.resource = omap16xx_gpio3_resources,
+};
+
+/*
+ * OMAP16XX GPIO4 interface data
+  */
+static struct __initdata resource omap16xx_gpio4_resources[] = {
+	{
+		.start	= OMAP1610_GPIO4_BASE,
+		.end	= OMAP1610_GPIO4_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_1610_GPIO_BANK4,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 48,
+	.bank_type		= METHOD_GPIO_1610,
+	.gpio_attr		= &omap16xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap16xx_gpio4 = {
+	.name           = "omap-gpio",
+	.id             = 4,
+	.dev            = {
+		.platform_data = &omap16xx_gpio4_config,
+	},
+	.num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
+	.resource = omap16xx_gpio4_resources,
+};
+
+static struct __initdata platform_device * omap16xx_gpio_dev[] = {
+	&omap16xx_mpu_gpio,
+	&omap16xx_gpio1,
+	&omap16xx_gpio2,
+	&omap16xx_gpio3,
+	&omap16xx_gpio4,
+};
+
+/*
+ * omap16xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap16xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap16xx_gpio_init(void)
+{
+	int i;
+
+	if (!cpu_is_omap16xx())
+		return -EINVAL;
+
+	for (i = 0; i < sizeof(omap16xx_gpio_dev); i++)
+			platform_device_register(omap16xx_gpio_dev[i]);
+
+	gpio_bank_count = sizeof(omap16xx_gpio_dev);
+
+	return 0;
+}
+postcore_initcall(omap16xx_gpio_init);
-- 
1.6.3.3


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

* [PATCH 04/13 v5] OMAP: GPIO: Introduce support for OMAP7xx chip GPIO init
  2010-08-06 12:34     ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " Charulatha V
@ 2010-08-06 12:34       ` Charulatha V
  2010-08-06 12:34         ` [PATCH 05/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP3 Charulatha V
  2010-08-09  3:51       ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " DebBarma, Tarun Kanti
  1 sibling, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch adds support for handling OMAP7xx specific gpio_init
by providing platform device data and doing device registration.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap1/gpio7xx.c |  274 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 274 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap1/gpio7xx.c

diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
new file mode 100644
index 0000000..c8cebc4
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -0,0 +1,274 @@
+/*
+ * OMAP7XX-specific gpio code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ *	Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP7XX_GPIO1_BASE		0xfffbc000
+#define OMAP7XX_GPIO2_BASE		0xfffbc800
+#define OMAP7XX_GPIO3_BASE		0xfffbd000
+#define OMAP7XX_GPIO4_BASE		0xfffbd800
+#define OMAP7XX_GPIO5_BASE		0xfffbe000
+#define OMAP7XX_GPIO6_BASE		0xfffbe800
+#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
+
+static struct omap_gpio_dev_attr omap7xx_gpio_attr = {
+	.bank_width = 32,
+};
+
+/*
+ * OMAP7XX MPU GPIO interface data
+ */
+static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
+	{
+		.start	= OMAP1_MPUIO_VBASE,
+		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_MPUIO,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
+	.virtual_irq_start	= IH_MPUIO_BASE,
+	.bank_type		= METHOD_MPUIO,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_mpu_gpio = {
+	.name           = "omap-gpio",
+	.id             = 0,
+	.dev            = {
+		.platform_data = &omap7xx_mpu_gpio_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources),
+	.resource = omap7xx_mpu_gpio_resources,
+};
+
+/*
+ * OMAP7XX GPIO1 interface data
+ */
+static struct __initdata resource omap7xx_gpio1_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO1_BASE,
+		.end	= OMAP7XX_GPIO1_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
+	.virtual_irq_start	= IH_GPIO_BASE,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio1 = {
+	.name           = "omap-gpio",
+	.id             = 1,
+	.dev            = {
+		.platform_data = &omap7xx_gpio1_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio1_resources),
+	.resource = omap7xx_gpio1_resources,
+};
+
+/*
+ * OMAP7XX GPIO2 interface data
+ */
+static struct __initdata resource omap7xx_gpio2_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO2_BASE,
+		.end	= OMAP7XX_GPIO2_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 32,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio2 = {
+	.name           = "omap-gpio",
+	.id             = 2,
+	.dev            = {
+		.platform_data = &omap7xx_gpio2_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio2_resources),
+	.resource = omap7xx_gpio2_resources,
+};
+
+/*
+ * OMAP7XX GPIO3 interface data
+ */
+static struct __initdata resource omap7xx_gpio3_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO3_BASE,
+		.end	= OMAP7XX_GPIO3_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 64,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio3 = {
+	.name           = "omap-gpio",
+	.id             = 3,
+	.dev            = {
+		.platform_data = &omap7xx_gpio3_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio3_resources),
+	.resource = omap7xx_gpio3_resources,
+};
+
+/*
+ * OMAP7XX GPIO4 interface data
+ */
+static struct __initdata resource omap7xx_gpio4_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO4_BASE,
+		.end	= OMAP7XX_GPIO4_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK4,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 96,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio4 = {
+	.name           = "omap-gpio",
+	.id             = 4,
+	.dev            = {
+		.platform_data = &omap7xx_gpio4_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio4_resources),
+	.resource = omap7xx_gpio4_resources,
+};
+
+/*
+ * OMAP7XX GPIO5 interface data
+  */
+static struct __initdata resource omap7xx_gpio5_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO5_BASE,
+		.end	= OMAP7XX_GPIO5_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK5,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 128,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio5 = {
+	.name           = "omap-gpio",
+	.id             = 5,
+	.dev            = {
+		.platform_data = &omap7xx_gpio5_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio5_resources),
+	.resource = omap7xx_gpio5_resources,
+};
+
+/*
+ * OMAP7XX GPIO6 interface data
+  */
+static struct __initdata resource omap7xx_gpio6_resources[] = {
+	{
+		.start	= OMAP7XX_GPIO6_BASE,
+		.end	= OMAP7XX_GPIO6_BASE + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_7XX_GPIO_BANK6,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
+	.virtual_irq_start	= IH_GPIO_BASE + 160,
+	.bank_type		= METHOD_GPIO_7XX,
+	.gpio_attr		= &omap7xx_gpio_attr,
+};
+
+static struct __initdata platform_device omap7xx_gpio6 = {
+	.name           = "omap-gpio",
+	.id             = 6,
+	.dev            = {
+		.platform_data = &omap7xx_gpio6_config,
+	},
+	.num_resources = ARRAY_SIZE(omap7xx_gpio6_resources),
+	.resource = omap7xx_gpio6_resources,
+};
+
+static struct __initdata platform_device * omap7xx_gpio_dev[] = {
+	&omap7xx_mpu_gpio,
+	&omap7xx_gpio1,
+	&omap7xx_gpio2,
+	&omap7xx_gpio3,
+	&omap7xx_gpio4,
+	&omap7xx_gpio5,
+	&omap7xx_gpio6,
+};
+
+/*
+ * omap7xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap7xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap7xx_gpio_init(void)
+{
+	int i;
+
+	if (!cpu_is_omap7xx())
+		return -EINVAL;
+
+	for (i = 0; i < sizeof(omap7xx_gpio_dev); i++)
+		platform_device_register(omap7xx_gpio_dev[i]);
+
+	gpio_bank_count = sizeof(omap7xx_gpio_dev);
+
+	return 0;
+}
+postcore_initcall(omap7xx_gpio_init);
-- 
1.6.3.3


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

* [PATCH 05/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP3
  2010-08-06 12:34       ` [PATCH 04/13 v5] OMAP: GPIO: Introduce support for OMAP7xx " Charulatha V
@ 2010-08-06 12:34         ` Charulatha V
  2010-08-06 12:34           ` [PATCH 06/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP242X Charulatha V
  0 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

Add hwmod structures for GPIO module on OMAP3

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  382 ++++++++++++++++++++++++++++
 1 files changed, 382 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5d8eb58..90fb907 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -17,6 +17,7 @@
 #include <mach/irqs.h>
 #include <plat/cpu.h>
 #include <plat/dma.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -36,6 +37,12 @@ static struct omap_hwmod omap3xxx_iva_hwmod;
 static struct omap_hwmod omap3xxx_l3_main_hwmod;
 static struct omap_hwmod omap3xxx_l4_core_hwmod;
 static struct omap_hwmod omap3xxx_l4_per_hwmod;
+static struct omap_hwmod omap3xxx_gpio1_hwmod;
+static struct omap_hwmod omap3xxx_gpio2_hwmod;
+static struct omap_hwmod omap3xxx_gpio3_hwmod;
+static struct omap_hwmod omap3xxx_gpio4_hwmod;
+static struct omap_hwmod omap3xxx_gpio5_hwmod;
+static struct omap_hwmod omap3xxx_gpio6_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -197,6 +204,375 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
 };
 
+/* L4 WKUP -> GPIO1 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = {
+	{
+		.pa_start	= 0x48310000,
+		.pa_end		= 0x483101ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = {
+	.master		= &omap3xxx_l4_wkup_hwmod,
+	.slave		= &omap3xxx_gpio1_hwmod,
+	.clk		= "gpio1_ick",
+	.addr		= omap3xxx_gpio1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio1_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO2 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = {
+	{
+		.pa_start	= 0x49050000,
+		.pa_end		= 0x490501ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_gpio2_hwmod,
+	.clk		= "gpio2_ick",
+	.addr		= omap3xxx_gpio2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio2_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO3 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = {
+	{
+		.pa_start	= 0x49052000,
+		.pa_end		= 0x490521ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_gpio3_hwmod,
+	.clk		= "gpio3_ick",
+	.addr		= omap3xxx_gpio3_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio3_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO4 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
+	{
+		.pa_start	= 0x49054000,
+		.pa_end		= 0x490541ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_gpio4_hwmod,
+	.clk		= "gpio4_ick",
+	.addr		= omap3xxx_gpio4_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio4_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO5 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = {
+	{
+		.pa_start	= 0x49056000,
+		.pa_end		= 0x490561ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_gpio5_hwmod,
+	.clk		= "gpio5_ick",
+	.addr		= omap3xxx_gpio5_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio5_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO6 interface */
+
+static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = {
+	{
+		.pa_start	= 0x49058000,
+		.pa_end		= 0x490581ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_gpio6_hwmod,
+	.clk		= "gpio6_ick",
+	.addr		= omap3xxx_gpio6_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio6_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* GPIO common*/
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = {
+	.name = "gpio",
+	.sysc = &omap3xxx_gpio_sysc,
+	.rev = 1,
+};
+
+/* GPIO dev_attr common for gpio2-6*/
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = true,
+	.off_mode_support = true,
+};
+
+/* GPIO1 */
+
+static struct omap_gpio_dev_attr gpio1_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = true,
+	.off_mode_support = false,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_gpio1_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK1 },
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio1_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = {
+	&omap3xxx_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap3xxx_gpio1_hwmod = {
+	.name		= "gpio1",
+	.mpu_irqs	= omap3xxx_gpio1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio1_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio1_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO1_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO1_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio1_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio1_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info omap3xxx_gpio2_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK2 },
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio2_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = {
+	&omap3xxx_l4_per__gpio2,
+};
+
+static struct omap_hwmod omap3xxx_gpio2_hwmod = {
+	.name		= "gpio2",
+	.mpu_irqs	= omap3xxx_gpio2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio2_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio2_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO2_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO2_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio2_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info omap3xxx_gpio3_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK3 },
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio3_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = {
+	&omap3xxx_l4_per__gpio3,
+};
+
+static struct omap_hwmod omap3xxx_gpio3_hwmod = {
+	.name		= "gpio3",
+	.mpu_irqs	= omap3xxx_gpio3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio3_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio3_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO3_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO3_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio3_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info omap3xxx_gpio4_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK4 },
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio4_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = {
+	&omap3xxx_l4_per__gpio4,
+};
+
+static struct omap_hwmod omap3xxx_gpio4_hwmod = {
+	.name		= "gpio4",
+	.mpu_irqs	= omap3xxx_gpio4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio4_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio4_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO4_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO4_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio4_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+
+/* GPIO5 */
+
+static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK5 },
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio5_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = {
+	&omap3xxx_l4_per__gpio5,
+};
+
+static struct omap_hwmod omap3xxx_gpio5_hwmod = {
+	.name		= "gpio5",
+	.mpu_irqs	= omap3xxx_gpio5_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio5_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio5_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO5_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO5_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio5_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio5_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO6 */
+
+static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK6 },
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio6_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = {
+	&omap3xxx_l4_per__gpio6,
+};
+
+static struct omap_hwmod omap3xxx_gpio6_hwmod = {
+	.name		= "gpio6",
+	.mpu_irqs	= omap3xxx_gpio6_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio6_irqs),
+	.main_clk	= NULL,
+	.opt_clks	= gpio6_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks),
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_GPIO6_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_GPIO6_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_gpio6_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio6_slaves),
+	.class		= &omap3xxx_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_main_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -204,6 +580,12 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l4_wkup_hwmod,
 	&omap3xxx_mpu_hwmod,
 	&omap3xxx_iva_hwmod,
+	&omap3xxx_gpio1_hwmod,
+	&omap3xxx_gpio2_hwmod,
+	&omap3xxx_gpio3_hwmod,
+	&omap3xxx_gpio4_hwmod,
+	&omap3xxx_gpio5_hwmod,
+	&omap3xxx_gpio6_hwmod,
 	NULL,
 };
 
-- 
1.6.3.3


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

* [PATCH 06/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP242X
  2010-08-06 12:34         ` [PATCH 05/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP3 Charulatha V
@ 2010-08-06 12:34           ` Charulatha V
  2010-08-06 12:34             ` [PATCH 07/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP243X Charulatha V
  0 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

Add hwmod structures for GPIO module on OMAP242X

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  234 ++++++++++++++++++++++++++++
 1 files changed, 234 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 3cc768e..228ffe4 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -15,6 +15,7 @@
 #include <mach/irqs.h>
 #include <plat/cpu.h>
 #include <plat/dma.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -33,6 +34,10 @@ static struct omap_hwmod omap2420_mpu_hwmod;
 static struct omap_hwmod omap2420_iva_hwmod;
 static struct omap_hwmod omap2420_l3_main_hwmod;
 static struct omap_hwmod omap2420_l4_core_hwmod;
+static struct omap_hwmod omap2420_gpio1_hwmod;
+static struct omap_hwmod omap2420_gpio2_hwmod;
+static struct omap_hwmod omap2420_gpio3_hwmod;
+static struct omap_hwmod omap2420_gpio4_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -165,12 +170,241 @@ static struct omap_hwmod omap2420_iva_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
 };
 
+/* L4 WKUP -> GPIO1 interface */
+static struct omap_hwmod_addr_space omap2420_gpio1_addr_space[] = {
+	{
+		.pa_start	= 0x48018000,
+		.pa_end		= 0x480181ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = {
+	.master		= &omap2420_l4_wkup_hwmod,
+	.slave		= &omap2420_gpio1_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2420_gpio1_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2420_gpio1_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO2 interface */
+static struct omap_hwmod_addr_space omap2420_gpio2_addr_space[] = {
+	{
+		.pa_start	= 0x4801a000,
+		.pa_end		= 0x4801a1ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = {
+	.master		= &omap2420_l4_wkup_hwmod,
+	.slave		= &omap2420_gpio2_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2420_gpio2_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2420_gpio2_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO3 interface */
+static struct omap_hwmod_addr_space omap2420_gpio3_addr_space[] = {
+	{
+		.pa_start	= 0x4801c000,
+		.pa_end		= 0x4801c1ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = {
+	.master		= &omap2420_l4_wkup_hwmod,
+	.slave		= &omap2420_gpio3_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2420_gpio3_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2420_gpio3_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO4 interface */
+static struct omap_hwmod_addr_space omap2420_gpio4_addr_space[] = {
+	{
+		.pa_start	= 0x4801e000,
+		.pa_end		= 0x4801e1ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = {
+	.master		= &omap2420_l4_wkup_hwmod,
+	.slave		= &omap2420_gpio4_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2420_gpio4_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2420_gpio4_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* GPIO common */
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = false,
+	/*
+	 * off_mode is supported by GPIO, but it is not
+	 * supported by software due to leakage current problem.
+	 * Hence making off_mode_support flag as false
+	 */
+	.off_mode_support = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap242x_gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap242x_gpio_hwmod_class = {
+	.name = "gpio",
+	.sysc = &omap242x_gpio_sysc,
+	.rev = 0,
+};
+
+/* GPIO1 */
+
+static struct omap_hwmod_irq_info omap242x_gpio1_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK1 },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = {
+	&omap2420_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2420_gpio1_hwmod = {
+	.name		= "gpio1",
+	.mpu_irqs	= omap242x_gpio1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio1_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio1_slaves),
+	.class		= &omap242x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info omap242x_gpio2_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK2 },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = {
+	&omap2420_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2420_gpio2_hwmod = {
+	.name		= "gpio2",
+	.mpu_irqs	= omap242x_gpio2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio2_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio2_slaves),
+	.class		= &omap242x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info omap242x_gpio3_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK3 },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = {
+	&omap2420_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2420_gpio3_hwmod = {
+	.name		= "gpio3",
+	.mpu_irqs	= omap242x_gpio3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio3_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio3_slaves),
+	.class		= &omap242x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info omap242x_gpio4_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK4 },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = {
+	&omap2420_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2420_gpio4_hwmod = {
+	.name		= "gpio4",
+	.mpu_irqs	= omap242x_gpio4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio4_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio4_slaves),
+	.class		= &omap242x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
 static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_l3_main_hwmod,
 	&omap2420_l4_core_hwmod,
 	&omap2420_l4_wkup_hwmod,
 	&omap2420_mpu_hwmod,
 	&omap2420_iva_hwmod,
+	&omap2420_gpio1_hwmod,
+	&omap2420_gpio2_hwmod,
+	&omap2420_gpio3_hwmod,
+	&omap2420_gpio4_hwmod,
 	NULL,
 };
 
-- 
1.6.3.3


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

* [PATCH 07/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP243X
  2010-08-06 12:34           ` [PATCH 06/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP242X Charulatha V
@ 2010-08-06 12:34             ` Charulatha V
  2010-08-06 12:34               ` [PATCH 08/13 v5] OMAP: GPIO: Add gpio dev_attr and correct clks in OMAP4 hwmod struct Charulatha V
  0 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

Add hwmod structures for GPIO module on OMAP243X

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  290 ++++++++++++++++++++++++++++
 1 files changed, 290 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 4526628..d3582e1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -15,6 +15,7 @@
 #include <mach/irqs.h>
 #include <plat/cpu.h>
 #include <plat/dma.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -33,6 +34,11 @@ static struct omap_hwmod omap2430_mpu_hwmod;
 static struct omap_hwmod omap2430_iva_hwmod;
 static struct omap_hwmod omap2430_l3_main_hwmod;
 static struct omap_hwmod omap2430_l4_core_hwmod;
+static struct omap_hwmod omap2430_gpio1_hwmod;
+static struct omap_hwmod omap2430_gpio2_hwmod;
+static struct omap_hwmod omap2430_gpio3_hwmod;
+static struct omap_hwmod omap2430_gpio4_hwmod;
+static struct omap_hwmod omap2430_gpio5_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
@@ -165,12 +171,296 @@ static struct omap_hwmod omap2430_iva_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
 };
 
+/* L4 WKUP -> GPIO1 interface */
+
+static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = {
+	{
+		.pa_start	= 0x4900C000,
+		.pa_end		= 0x4900C1ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = {
+	.master		= &omap2430_l4_wkup_hwmod,
+	.slave		= &omap2430_gpio1_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2430_gpio1_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2430_gpio1_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO2 interface */
+
+static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = {
+	{
+		.pa_start	= 0x4900E000,
+		.pa_end		= 0x4900E1ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = {
+	.master		= &omap2430_l4_wkup_hwmod,
+	.slave		= &omap2430_gpio2_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2430_gpio2_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2430_gpio2_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO3 interface */
+
+static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = {
+	{
+		.pa_start	= 0x49010000,
+		.pa_end		= 0x490101ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = {
+	.master		= &omap2430_l4_wkup_hwmod,
+	.slave		= &omap2430_gpio3_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2430_gpio3_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2430_gpio3_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP -> GPIO4 interface */
+
+static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = {
+	{
+		.pa_start	= 0x49012000,
+		.pa_end		= 0x490121ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = {
+	.master		= &omap2430_l4_wkup_hwmod,
+	.slave		= &omap2430_gpio4_hwmod,
+	.clk		= "gpios_ick",
+	.addr		= omap2430_gpio4_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2430_gpio4_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> GPIO5 interface */
+
+static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = {
+	{
+		.pa_start	= 0x480B6000,
+		.pa_end		= 0x480B61ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = {
+	.master		= &omap2430_l4_core_hwmod,
+	.slave		= &omap2430_gpio5_hwmod,
+	.clk		= "gpio5_ick",
+	.addr		= omap2430_gpio5_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap2430_gpio5_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* GPIO common */
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = false,
+	/*
+	 * off_mode is supported by GPIO, but it is not
+	 * supported by software due to leakage current problem.
+	 * Hence making off_mode_support flag as false
+	 */
+	.off_mode_support = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap243x_gpio_hwmod_class = {
+	.name = "gpio",
+	.sysc = &omap243x_gpio_sysc,
+	.rev = 0,
+};
+
+/* GPIO1 */
+
+static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK1 },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = {
+	&omap2430_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2430_gpio1_hwmod = {
+	.name		= "gpio1",
+	.mpu_irqs	= omap243x_gpio1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio1_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio1_slaves),
+	.class		= &omap243x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK2 },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = {
+	&omap2430_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2430_gpio2_hwmod = {
+	.name		= "gpio2",
+	.mpu_irqs	= omap243x_gpio2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio2_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio2_slaves),
+	.class		= &omap243x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK3 },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = {
+	&omap2430_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2430_gpio3_hwmod = {
+	.name		= "gpio3",
+	.mpu_irqs	= omap243x_gpio3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio3_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio3_slaves),
+	.class		= &omap243x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK4 },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = {
+	&omap2430_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2430_gpio4_hwmod = {
+	.name		= "gpio4",
+	.mpu_irqs	= omap243x_gpio4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio4_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+			.module_offs = WKUP_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio4_slaves),
+	.class		= &omap243x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO5 */
+
+static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_24XX_GPIO_BANK5 },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = {
+	&omap2430_l4_core__gpio5,
+};
+
+static struct omap_hwmod omap2430_gpio5_hwmod = {
+	.name		= "gpio5",
+	.mpu_irqs	= omap243x_gpio5_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio5_irqs),
+	.main_clk	= "gpio5_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP2430_ST_GPIO5_SHIFT,
+			.module_offs = CORE_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio5_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio5_slaves),
+	.class		= &omap243x_gpio_hwmod_class,
+	.dev_attr	= &gpio_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
 static __initdata struct omap_hwmod *omap2430_hwmods[] = {
 	&omap2430_l3_main_hwmod,
 	&omap2430_l4_core_hwmod,
 	&omap2430_l4_wkup_hwmod,
 	&omap2430_mpu_hwmod,
 	&omap2430_iva_hwmod,
+	&omap2430_gpio1_hwmod,
+	&omap2430_gpio2_hwmod,
+	&omap2430_gpio3_hwmod,
+	&omap2430_gpio4_hwmod,
+	&omap2430_gpio5_hwmod,
 	NULL,
 };
 
-- 
1.6.3.3


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

* [PATCH 08/13 v5] OMAP: GPIO: Add gpio dev_attr and correct clks in OMAP4 hwmod struct
  2010-08-06 12:34             ` [PATCH 07/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP243X Charulatha V
@ 2010-08-06 12:34               ` Charulatha V
  2010-08-06 12:34                 ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Charulatha V
  0 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch adds gpio_dev_attr to OMAP4 gpio hwmod structure. This patch
also corrects the gpio .main_clk and .clk fields in gpio hwmod structures.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   40 +++++++++++++++++++--------
 1 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 20f5f8c..1b066df 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -22,6 +22,7 @@
 
 #include <plat/omap_hwmod.h>
 #include <plat/cpu.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -1272,6 +1273,20 @@ static struct omap_hwmod omap44xx_fdif_hwmod = {
  * general purpose io module
  */
 
+/* gpio_dev_attr common for gpio2-6*/
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = true,
+	.off_mode_support = true,
+};
+
+/* gpio_dev_attr for gpio1*/
+static struct omap_gpio_dev_attr gpio1_dev_attr = {
+	.bank_width = 32,
+	.dbck_flag = true,
+	.off_mode_support = false,
+};
+
 static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = {
 	.rev_offs	= 0x0000,
 	.sysc_offs	= 0x0010,
@@ -1285,6 +1300,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = {
 static struct omap_hwmod_class omap44xx_gpio_hwmod_class = {
 	.name = "gpio",
 	.sysc = &omap44xx_gpio_sysc,
+	.rev = 2,
 };
 
 /* gpio1 */
@@ -1305,7 +1321,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_gpio1_hwmod,
-	.clk		= "l4_wkup_clk_mux_ck",
+	.clk		= "gpio1_ick",
 	.addr		= omap44xx_gpio1_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio1_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1325,7 +1341,6 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio1_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio1_irqs),
-	.main_clk	= "gpio1_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
@@ -1333,6 +1348,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+	.dev_attr	= &gpio1_dev_attr,
 	.slaves		= omap44xx_gpio1_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio1_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -1356,7 +1372,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio2_hwmod,
-	.clk		= "l4_div_ck",
+	.clk		= "gpio2_ick",
 	.addr		= omap44xx_gpio2_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio2_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1376,7 +1392,6 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio2_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio2_irqs),
-	.main_clk	= "gpio2_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
@@ -1384,6 +1399,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
 	.slaves		= omap44xx_gpio2_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio2_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -1407,7 +1423,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio3_hwmod,
-	.clk		= "l4_div_ck",
+	.clk		= "gpio3_ick",
 	.addr		= omap44xx_gpio3_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio3_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1427,7 +1443,6 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio3_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio3_irqs),
-	.main_clk	= "gpio3_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
@@ -1435,6 +1450,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
 	},
 	.opt_clks	= gpio3_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
 	.slaves		= omap44xx_gpio3_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio3_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -1458,7 +1474,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio4_hwmod,
-	.clk		= "l4_div_ck",
+	.clk		= "gpio4_ick",
 	.addr		= omap44xx_gpio4_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio4_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1478,7 +1494,6 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio4_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio4_irqs),
-	.main_clk	= "gpio4_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
@@ -1486,6 +1501,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
 	},
 	.opt_clks	= gpio4_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
 	.slaves		= omap44xx_gpio4_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio4_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -1509,7 +1525,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio5_hwmod,
-	.clk		= "l4_div_ck",
+	.clk		= "gpio5_ick",
 	.addr		= omap44xx_gpio5_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio5_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1529,7 +1545,6 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio5_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio5_irqs),
-	.main_clk	= "gpio5_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
@@ -1537,6 +1552,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
 	},
 	.opt_clks	= gpio5_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
 	.slaves		= omap44xx_gpio5_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio5_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -1560,7 +1576,7 @@ static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = {
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio6_hwmod,
-	.clk		= "l4_div_ck",
+	.clk		= "gpio6_ick",
 	.addr		= omap44xx_gpio6_addrs,
 	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio6_addrs),
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
@@ -1580,7 +1596,6 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
 	.class		= &omap44xx_gpio_hwmod_class,
 	.mpu_irqs	= omap44xx_gpio6_irqs,
 	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio6_irqs),
-	.main_clk	= "gpio6_ick",
 	.prcm = {
 		.omap4 = {
 			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
@@ -1588,6 +1603,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
 	},
 	.opt_clks	= gpio6_opt_clks,
 	.opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
 	.slaves		= omap44xx_gpio6_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio6_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
-- 
1.6.3.3


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

* [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init
  2010-08-06 12:34               ` [PATCH 08/13 v5] OMAP: GPIO: Add gpio dev_attr and correct clks in OMAP4 hwmod struct Charulatha V
@ 2010-08-06 12:34                 ` Charulatha V
  2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
                                     ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch adds support for handling GPIO as a HWMOD FW adapted
platform device for OMAP2PLUS chips.

gpio_init needs to be done before machine_init functions access
gpio APIs.Hence gpio_init is made as a postcore_initcall.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/gpio.c |  120 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 120 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpio.c

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
new file mode 100644
index 0000000..30aeef9
--- /dev/null
+++ b/arch/arm/mach-omap2/gpio.c
@@ -0,0 +1,120 @@
+/*
+ * gpio.c - OMAP2PLUS-specific gpio code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ *	Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+/*
+ * For GPIO, it is a must to relinquish clocks in the Idle-path
+ * as it is possible to have a GPIO bank requested and still
+ * allow PER domain to go to OFF. In the idle path (interrupt
+ * disabled context), omap_device APIs cannot be used as they
+ * are not mutex-free functions. Hence the below wrappers are
+ * required to handle interrupts disabled context and interrupts
+ * enabled context.
+ */
+static int gpio_enable_hwmod(struct omap_device *od)
+{
+	struct omap_hwmod *oh = *od->hwmods;
+
+	if (irqs_disabled())
+		_omap_hwmod_enable(oh);
+	else
+		omap_device_enable_hwmods(od);
+	return 0;
+}
+
+static int gpio_idle_hwmod(struct omap_device *od)
+{
+	struct omap_hwmod *oh = *od->hwmods;
+
+	if (irqs_disabled())
+		_omap_hwmod_idle(oh);
+	else
+		omap_device_idle_hwmods(od);
+	return 0;
+}
+
+static struct omap_device_pm_latency omap_gpio_latency[] = {
+	[0] = {
+		.deactivate_func = gpio_idle_hwmod,
+		.activate_func   = gpio_enable_hwmod,
+		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	},
+};
+
+static int omap2_init_gpio(struct omap_hwmod *oh, void *user)
+{
+	struct omap_device *od;
+	struct omap_gpio_platform_data *pdata;
+	char *name = "omap-gpio";
+	static int id;
+	struct omap_gpio_dev_attr *gpio_dev_data;
+
+	if (!oh) {
+		pr_err("Could not look up omap gpio %d\n", id + 1);
+		return -EINVAL;
+	}
+
+	pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
+					GFP_KERNEL);
+	if (!pdata) {
+		pr_err("Memory allocation failed gpio%d\n", id + 1);
+		return -ENOMEM;
+	}
+
+	gpio_dev_data = (struct omap_gpio_dev_attr *)oh->dev_attr;
+
+	pdata->gpio_attr = gpio_dev_data;
+	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * id;
+	switch (oh->class->rev) {
+	case 0:
+	case 1:
+		pdata->bank_type = METHOD_GPIO_24XX;
+		break;
+	case 2:
+		pdata->bank_type = METHOD_GPIO_44XX;
+		break;
+	default:
+		WARN(1, "Invalid gpio bank_type\n");
+		break;
+	}
+	gpio_bank_count++;
+
+	od = omap_device_build(name, id, oh, pdata,
+				sizeof(*pdata),	omap_gpio_latency,
+				ARRAY_SIZE(omap_gpio_latency),
+				false);
+	WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
+				name, oh->name);
+
+	id++;
+	return 0;
+}
+
+/*
+ * gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence gpio_init is a postcore_initcall.
+ */
+static int __init omap2_gpio_init(void)
+{
+	return omap_hwmod_for_each_by_class("gpio", omap2_init_gpio,
+						NULL);
+}
+postcore_initcall(omap2_gpio_init);
-- 
1.6.3.3


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

* [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-06 12:34                 ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Charulatha V
@ 2010-08-06 12:34                   ` Charulatha V
  2010-08-06 12:34                     ` [PATCH 11/13 v5] OMAP: GPIO: Make gpio_context as part of gpio_bank structure Charulatha V
  2010-08-09 23:06                     ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Kevin Hilman
  2010-08-09 23:58                   ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Kevin Hilman
  2010-08-10  0:21                   ` Kevin Hilman
  2 siblings, 2 replies; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch implements GPIO as a platform device. Also it
implements OMAP2PLUS specific GPIO as HWMOD FW adapted device.
This patch makes GPIO to use runtime APIs.

GPIO APIs are used in machine_init functions. Hence it is
required to complete GPIO probe before machine_init. Therefore
GPIO device register and driver register are implemented as
postcore_initcalls.

Inorder to convert GPIO as platform device, modifications are
required in clockxxxx_data.c file for OMAP1 so that device names
can be used to obtain clock instead of getting clocks by
name/NULL ptr.

omap_gpio_init() does nothing now and this function would be
removed in the next patch as it's usage is spread across most of
the board files.

TODO:
1. Cleanup the GPIO driver. Use function pointers and register
offest pointers instead of using hardcoded values
2. Remove all cpu_is_ checks and OMAP specific macros
3. Remove usage of gpio_bank array so that only
instance specific information is used in driver code
4. Rename 'method'/ avoid it's usage

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap1/Makefile           |    6 +
 arch/arm/mach-omap1/clock_data.c       |    4 +-
 arch/arm/mach-omap2/Makefile           |    2 +-
 arch/arm/plat-omap/gpio.c              |  428 ++++++++------------------------
 arch/arm/plat-omap/include/plat/gpio.h |    3 +
 5 files changed, 121 insertions(+), 322 deletions(-)

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 9a304d8..b014bb1 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -49,6 +49,12 @@ ifeq ($(CONFIG_ARCH_OMAP15XX),y)
 obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= fpga.o
 endif
 
+# GPIO
+obj-$(CONFIG_ARCH_OMAP730)		+= gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP850)		+= gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP15XX)		+= gpio15xx.o
+obj-$(CONFIG_ARCH_OMAP16XX)		+= gpio16xx.o
+
 # LEDs support
 led-$(CONFIG_MACH_OMAP_H2)		+= leds-h2p2-debug.o
 led-$(CONFIG_MACH_OMAP_H3)		+= leds-h2p2-debug.o
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
index af54114..cbdcf9c 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -143,7 +143,7 @@ static struct arm_idlect1_clk armper_ck = {
  * activation.  [ GPIO code for 1510 ]
  */
 static struct clk arm_gpio_ck = {
-	.name		= "arm_gpio_ck",
+	.name		= "ick",
 	.ops		= &clkops_generic,
 	.parent		= &ck_dpll1,
 	.flags		= ENABLE_ON_INIT,
@@ -684,7 +684,7 @@ static struct omap_clk omap_clks[] = {
 	CLK(NULL,	"ck_sossi",	&sossi_ck,	CK_16XX),
 	CLK(NULL,	"arm_ck",	&arm_ck,	CK_16XX | CK_1510 | CK_310),
 	CLK(NULL,	"armper_ck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"arm_gpio_ck",	&arm_gpio_ck,	CK_1510 | CK_310),
+	CLK("omap-gpio.0", "ick", &arm_gpio_ck,	CK_1510 | CK_310),
 	CLK(NULL,	"armxor_ck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
 	CLK(NULL,	"armtim_ck",	&armtim_ck.clk,	CK_16XX | CK_1510 | CK_310),
 	CLK("omap_wdt",	"fck",		&armwdt_ck.clk,	CK_16XX | CK_1510 | CK_310),
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 800b430..9dcc4b5 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o gpio.o
 
 omap-2-3-common				= irq.o sdrc.o
 hwmod-common				= omap_hwmod.o \
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index dfe4b9e..a377d40 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -21,7 +21,10 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
+#include <plat/omap_device.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <mach/irqs.h>
@@ -32,7 +35,6 @@
 /*
  * OMAP1510 GPIO registers
  */
-#define OMAP1510_GPIO_BASE		0xfffce000
 #define OMAP1510_GPIO_DATA_INPUT	0x00
 #define OMAP1510_GPIO_DATA_OUTPUT	0x04
 #define OMAP1510_GPIO_DIR_CONTROL	0x08
@@ -46,10 +48,6 @@
 /*
  * OMAP1610 specific GPIO registers
  */
-#define OMAP1610_GPIO1_BASE		0xfffbe400
-#define OMAP1610_GPIO2_BASE		0xfffbec00
-#define OMAP1610_GPIO3_BASE		0xfffbb400
-#define OMAP1610_GPIO4_BASE		0xfffbbc00
 #define OMAP1610_GPIO_REVISION		0x0000
 #define OMAP1610_GPIO_SYSCONFIG		0x0010
 #define OMAP1610_GPIO_SYSSTATUS		0x0014
@@ -71,12 +69,6 @@
 /*
  * OMAP7XX specific GPIO registers
  */
-#define OMAP7XX_GPIO1_BASE		0xfffbc000
-#define OMAP7XX_GPIO2_BASE		0xfffbc800
-#define OMAP7XX_GPIO3_BASE		0xfffbd000
-#define OMAP7XX_GPIO4_BASE		0xfffbd800
-#define OMAP7XX_GPIO5_BASE		0xfffbe000
-#define OMAP7XX_GPIO6_BASE		0xfffbe800
 #define OMAP7XX_GPIO_DATA_INPUT		0x00
 #define OMAP7XX_GPIO_DATA_OUTPUT	0x04
 #define OMAP7XX_GPIO_DIR_CONTROL	0x08
@@ -84,25 +76,7 @@
 #define OMAP7XX_GPIO_INT_MASK		0x10
 #define OMAP7XX_GPIO_INT_STATUS		0x14
 
-#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
-
-/*
- * omap24xx specific GPIO registers
- */
-#define OMAP242X_GPIO1_BASE		0x48018000
-#define OMAP242X_GPIO2_BASE		0x4801a000
-#define OMAP242X_GPIO3_BASE		0x4801c000
-#define OMAP242X_GPIO4_BASE		0x4801e000
-
-#define OMAP243X_GPIO1_BASE		0x4900C000
-#define OMAP243X_GPIO2_BASE		0x4900E000
-#define OMAP243X_GPIO3_BASE		0x49010000
-#define OMAP243X_GPIO4_BASE		0x49012000
-#define OMAP243X_GPIO5_BASE		0x480B6000
-
 #define OMAP24XX_GPIO_REVISION		0x0000
-#define OMAP24XX_GPIO_SYSCONFIG		0x0010
-#define OMAP24XX_GPIO_SYSSTATUS		0x0014
 #define OMAP24XX_GPIO_IRQSTATUS1	0x0018
 #define OMAP24XX_GPIO_IRQSTATUS2	0x0028
 #define OMAP24XX_GPIO_IRQENABLE2	0x002c
@@ -126,7 +100,6 @@
 #define OMAP24XX_GPIO_SETDATAOUT	0x0094
 
 #define OMAP4_GPIO_REVISION		0x0000
-#define OMAP4_GPIO_SYSCONFIG		0x0010
 #define OMAP4_GPIO_EOI			0x0020
 #define OMAP4_GPIO_IRQSTATUSRAW0	0x0024
 #define OMAP4_GPIO_IRQSTATUSRAW1	0x0028
@@ -138,7 +111,6 @@
 #define OMAP4_GPIO_IRQSTATUSCLR1	0x0040
 #define OMAP4_GPIO_IRQWAKEN0		0x0044
 #define OMAP4_GPIO_IRQWAKEN1		0x0048
-#define OMAP4_GPIO_SYSSTATUS		0x0114
 #define OMAP4_GPIO_IRQENABLE1		0x011c
 #define OMAP4_GPIO_WAKE_EN		0x0120
 #define OMAP4_GPIO_IRQSTATUS2		0x0128
@@ -159,26 +131,6 @@
 #define OMAP4_GPIO_SETWKUENA		0x0184
 #define OMAP4_GPIO_CLEARDATAOUT		0x0190
 #define OMAP4_GPIO_SETDATAOUT		0x0194
-/*
- * omap34xx specific GPIO registers
- */
-
-#define OMAP34XX_GPIO1_BASE		0x48310000
-#define OMAP34XX_GPIO2_BASE		0x49050000
-#define OMAP34XX_GPIO3_BASE		0x49052000
-#define OMAP34XX_GPIO4_BASE		0x49054000
-#define OMAP34XX_GPIO5_BASE		0x49056000
-#define OMAP34XX_GPIO6_BASE		0x49058000
-
-/*
- * OMAP44XX  specific GPIO registers
- */
-#define OMAP44XX_GPIO1_BASE             0x4a310000
-#define OMAP44XX_GPIO2_BASE             0x48055000
-#define OMAP44XX_GPIO3_BASE             0x48057000
-#define OMAP44XX_GPIO4_BASE             0x48059000
-#define OMAP44XX_GPIO5_BASE             0x4805B000
-#define OMAP44XX_GPIO6_BASE             0x4805D000
 
 struct gpio_bank {
 	unsigned long pbase;
@@ -203,97 +155,13 @@ struct gpio_bank {
 	struct clk *dbck;
 	u32 mod_usage;
 	u32 dbck_enable_mask;
+	struct device *dev;
+	bool dbck_flag;
+	bool off_mode_support;
 };
 
-#ifdef CONFIG_ARCH_OMAP16XX
-static struct gpio_bank gpio_bank_1610[5] = {
-	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
-		METHOD_MPUIO },
-	{ OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16,
-		METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32,
-		METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48,
-		METHOD_GPIO_1610 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP15XX
-static struct gpio_bank gpio_bank_1510[2] = {
-	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
-		METHOD_MPUIO },
-	{ OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_1510 }
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-static struct gpio_bank gpio_bank_7xx[7] = {
-	{ OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE,
-		METHOD_MPUIO },
-	{ OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_7XX },
-	{ OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_7XX },
-	{ OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_7XX },
-	{ OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4,  IH_GPIO_BASE + 96,
-		METHOD_GPIO_7XX },
-	{ OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5,  IH_GPIO_BASE + 128,
-		METHOD_GPIO_7XX },
-	{ OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6,  IH_GPIO_BASE + 160,
-		METHOD_GPIO_7XX },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
-
-static struct gpio_bank gpio_bank_242x[4] = {
-	{ OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
-		METHOD_GPIO_24XX },
-};
-
-static struct gpio_bank gpio_bank_243x[5] = {
-	{ OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
-		METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128,
-		METHOD_GPIO_24XX },
-};
-
-#endif
-
 #ifdef CONFIG_ARCH_OMAP3
-static struct gpio_bank gpio_bank_34xx[6] = {
-	{ OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO2_BASE, NULL, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO3_BASE, NULL, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO4_BASE, NULL, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96,
-		METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO5_BASE, NULL, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128,
-		METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO6_BASE, NULL, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160,
-		METHOD_GPIO_24XX },
-};
-
 struct omap3_gpio_regs {
-	u32 sysconfig;
 	u32 irqenable1;
 	u32 irqenable2;
 	u32 wake_en;
@@ -309,26 +177,16 @@ struct omap3_gpio_regs {
 static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
 #endif
 
-#ifdef CONFIG_ARCH_OMAP4
-static struct gpio_bank gpio_bank_44xx[6] = {
-	{ OMAP44XX_GPIO1_BASE, NULL, OMAP44XX_IRQ_GPIO1, IH_GPIO_BASE,
-		METHOD_GPIO_44XX },
-	{ OMAP44XX_GPIO2_BASE, NULL, OMAP44XX_IRQ_GPIO2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_44XX },
-	{ OMAP44XX_GPIO3_BASE, NULL, OMAP44XX_IRQ_GPIO3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_44XX },
-	{ OMAP44XX_GPIO4_BASE, NULL, OMAP44XX_IRQ_GPIO4, IH_GPIO_BASE + 96,
-		METHOD_GPIO_44XX },
-	{ OMAP44XX_GPIO5_BASE, NULL, OMAP44XX_IRQ_GPIO5, IH_GPIO_BASE + 128,
-		METHOD_GPIO_44XX },
-	{ OMAP44XX_GPIO6_BASE, NULL, OMAP44XX_IRQ_GPIO6, IH_GPIO_BASE + 160,
-		METHOD_GPIO_44XX },
-};
+/*
+ * TODO: Cleanup gpio_bank usage as it is having information
+ * related to all instances of the device
+ */
+static struct gpio_bank *gpio_bank;
 
-#endif
+static int bank_width;
 
-static struct gpio_bank *gpio_bank;
-static int gpio_bank_count;
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+int gpio_bank_count;
 
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 {
@@ -633,6 +491,9 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	u32			val;
 	u32			l;
 
+	if (!bank->dbck_flag)
+		return;
+
 	if (debounce < 32)
 		debounce = 0x01;
 	else if (debounce > 7936)
@@ -642,7 +503,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 
 	l = 1 << get_gpio_index(gpio);
 
-	if (cpu_is_omap44xx())
+	if (bank->method == METHOD_GPIO_44XX)
 		reg += OMAP4_GPIO_DEBOUNCINGTIME;
 	else
 		reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
@@ -650,21 +511,28 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	__raw_writel(debounce, reg);
 
 	reg = bank->base;
-	if (cpu_is_omap44xx())
+	if (bank->method == METHOD_GPIO_44XX)
 		reg += OMAP4_GPIO_DEBOUNCENABLE;
 	else
 		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
 
 	val = __raw_readl(reg);
 
+	if (!bank->dbck) {
+		struct platform_device *pdev = to_platform_device(bank->dev);
+		struct omap_device *odev = to_omap_device(pdev);
+		if (odev->hwmods[0]->opt_clks->_clk)
+			bank->dbck = odev->hwmods[0]->opt_clks->_clk;
+		if (IS_ERR(bank->dbck))
+			dev_err(bank->dev, "Could not get gpio dbck\n");
+	}
+
 	if (debounce) {
 		val |= l;
-		if (cpu_is_omap34xx() || cpu_is_omap44xx())
-			clk_enable(bank->dbck);
+		clk_enable(bank->dbck);
 	} else {
 		val &= ~l;
-		if (cpu_is_omap34xx() || cpu_is_omap44xx())
-			clk_disable(bank->dbck);
+		clk_disable(bank->dbck);
 	}
 	bank->dbck_enable_mask = val;
 
@@ -1531,7 +1399,8 @@ static struct platform_device omap_mpuio_device = {
 
 static inline void mpuio_init(void)
 {
-	platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]);
+	struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+	platform_set_drvdata(&omap_mpuio_device, bank);
 
 	if (platform_driver_register(&omap_mpuio_driver) == 0)
 		(void) platform_device_register(&omap_mpuio_device);
@@ -1664,24 +1533,6 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
 
 /*---------------------------------------------------------------------*/
 
-static int initialized;
-#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_ick;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2430)
-static struct clk * gpio5_ick;
-static struct clk * gpio5_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
-#endif
-
 static void __init omap_gpio_show_rev(void)
 {
 	u32 rev;
@@ -1704,6 +1555,18 @@ static void __init omap_gpio_show_rev(void)
  */
 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;
+}
+
 static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
 {
 	if (cpu_class_is_omap2()) {
@@ -1770,16 +1633,9 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
 
 static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 {
-	int j, bank_width = 16;
+	int j;
 	static int gpio;
 
-	if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
-		bank_width = 32; /* 7xx has 32-bit GPIOs */
-
-	if ((bank->method == METHOD_GPIO_24XX) ||
-			(bank->method == METHOD_GPIO_44XX))
-		bank_width = 32;
-
 	bank->mod_usage = 0;
 	/* REVISIT eventually switch from OMAP-specific gpio structs
 	 * over to the generic ones
@@ -1822,140 +1678,69 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 	set_irq_data(bank->irq, bank);
 }
 
-static int __init _omap_gpio_init(void)
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
-	int i;
-	int gpio = 0;
+	static int gpio_init_done;
+	struct omap_gpio_platform_data *pdata;
+	int id;
 	struct gpio_bank *bank;
-	int bank_size = SZ_8K;	/* Module 4KB + L4 4KB except on omap1 */
-	char clk_name[11];
+	struct resource *res;
 
-	initialized = 1;
+	if (!pdev || !pdev->dev.platform_data)
+		return -EINVAL;
 
-#if defined(CONFIG_ARCH_OMAP1)
-	if (cpu_is_omap15xx()) {
-		gpio_ick = clk_get(NULL, "arm_gpio_ck");
-		if (IS_ERR(gpio_ick))
-			printk("Could not get arm_gpio_ck\n");
-		else
-			clk_enable(gpio_ick);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP2)
-	if (cpu_class_is_omap2()) {
-		gpio_ick = clk_get(NULL, "gpios_ick");
-		if (IS_ERR(gpio_ick))
-			printk("Could not get gpios_ick\n");
-		else
-			clk_enable(gpio_ick);
-		gpio_fck = clk_get(NULL, "gpios_fck");
-		if (IS_ERR(gpio_fck))
-			printk("Could not get gpios_fck\n");
-		else
-			clk_enable(gpio_fck);
+	pdata = pdev->dev.platform_data;
 
-		/*
-		 * On 2430 & 3430 GPIO 5 uses CORE L4 ICLK
-		 */
-#if defined(CONFIG_ARCH_OMAP2430)
-		if (cpu_is_omap2430()) {
-			gpio5_ick = clk_get(NULL, "gpio5_ick");
-			if (IS_ERR(gpio5_ick))
-				printk("Could not get gpio5_ick\n");
-			else
-				clk_enable(gpio5_ick);
-			gpio5_fck = clk_get(NULL, "gpio5_fck");
-			if (IS_ERR(gpio5_fck))
-				printk("Could not get gpio5_fck\n");
-			else
-				clk_enable(gpio5_fck);
-		}
-#endif
-	}
-#endif
+	if (!gpio_init_done) {
+		int ret;
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		for (i = 0; i < OMAP34XX_NR_GPIOS; i++) {
-			sprintf(clk_name, "gpio%d_ick", i + 1);
-			gpio_iclks[i] = clk_get(NULL, clk_name);
-			if (IS_ERR(gpio_iclks[i]))
-				printk(KERN_ERR "Could not get %s\n", clk_name);
-			else
-				clk_enable(gpio_iclks[i]);
-		}
+		ret = init_gpio_info(pdev);
+		if (ret)
+			return ret;
 	}
-#endif
 
+	id = pdev->id;
+	bank = &gpio_bank[id];
 
-#ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap15xx()) {
-		gpio_bank_count = 2;
-		gpio_bank = gpio_bank_1510;
-		bank_size = SZ_2K;
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap16xx()) {
-		gpio_bank_count = 5;
-		gpio_bank = gpio_bank_1610;
-		bank_size = SZ_2K;
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	if (cpu_is_omap7xx()) {
-		gpio_bank_count = 7;
-		gpio_bank = gpio_bank_7xx;
-		bank_size = SZ_2K;
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP2
-	if (cpu_is_omap242x()) {
-		gpio_bank_count = 4;
-		gpio_bank = gpio_bank_242x;
-	}
-	if (cpu_is_omap243x()) {
-		gpio_bank_count = 5;
-		gpio_bank = gpio_bank_243x;
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP3
-	if (cpu_is_omap34xx()) {
-		gpio_bank_count = OMAP34XX_NR_GPIOS;
-		gpio_bank = gpio_bank_34xx;
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (unlikely(!res)) {
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
+		return -ENODEV;
 	}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	if (cpu_is_omap44xx()) {
-		gpio_bank_count = OMAP34XX_NR_GPIOS;
-		gpio_bank = gpio_bank_44xx;
+	bank->irq = res->start;
+	bank->virtual_irq_start = pdata->virtual_irq_start;
+	bank->method = pdata->bank_type;
+	bank->dev = &pdev->dev;
+	bank->dbck_flag = pdata->gpio_attr->dbck_flag;
+	bank->off_mode_support = pdata->gpio_attr->off_mode_support;
+	bank_width = pdata->gpio_attr->bank_width;
+
+	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);
+		return -ENODEV;
 	}
-#endif
-	for (i = 0; i < gpio_bank_count; i++) {
 
-		bank = &gpio_bank[i];
-		spin_lock_init(&bank->lock);
+	bank->base = ioremap(res->start, resource_size(res));
+	if (!bank->base) {
+		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
+		return -ENOMEM;
+	}
 
-		/* Static mapping, never released */
-		bank->base = ioremap(bank->pbase, bank_size);
-		if (!bank->base) {
-			printk(KERN_ERR "Could not ioremap gpio bank%i\n", i);
-			continue;
-		}
+	pm_runtime_enable(bank->dev);
+	pm_runtime_get_sync(bank->dev);
 
-		omap_gpio_mod_init(bank, i);
-		omap_gpio_chip_init(bank);
+	omap_gpio_mod_init(bank, id);
+	omap_gpio_chip_init(bank);
 
-		if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-			sprintf(clk_name, "gpio%d_dbck", i + 1);
-			bank->dbck = clk_get(NULL, clk_name);
-			if (IS_ERR(bank->dbck))
-				printk(KERN_ERR "Could not get %s\n", clk_name);
-		}
+	if (!gpio_init_done) {
+		omap_gpio_show_rev();
+		gpio_init_done = 1;
 	}
 
-	omap_gpio_show_rev();
-
 	return 0;
 }
 
@@ -2247,8 +2032,6 @@ void omap_gpio_save_context(void)
 	/* 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];
-		gpio_context[i].sysconfig =
-			__raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);
 		gpio_context[i].irqenable1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		gpio_context[i].irqenable2 =
@@ -2279,8 +2062,6 @@ void omap_gpio_restore_context(void)
 
 	for (i = 1; i < gpio_bank_count; i++) {
 		struct gpio_bank *bank = &gpio_bank[i];
-		__raw_writel(gpio_context[i].sysconfig,
-				bank->base + OMAP24XX_GPIO_SYSCONFIG);
 		__raw_writel(gpio_context[i].irqenable1,
 				bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		__raw_writel(gpio_context[i].irqenable2,
@@ -2305,25 +2086,34 @@ void omap_gpio_restore_context(void)
 }
 #endif
 
+static struct platform_driver omap_gpio_driver = {
+	.probe		= omap_gpio_probe,
+	.driver		= {
+		.name	= "omap-gpio",
+	},
+};
+
 /*
- * This may get called early from board specific init
- * for boards that have interrupts routed via FPGA.
+ * gpio driver register needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap_gpio_drv_reg() is a postcore_initcall.
  */
+static int __init omap_gpio_drv_reg(void)
+{
+	return platform_driver_register(&omap_gpio_driver);
+}
+postcore_initcall(omap_gpio_drv_reg);
+
+/* TODO: Remove omap_gpio_init() and its usage from board files */
 int __init omap_gpio_init(void)
 {
-	if (!initialized)
-		return _omap_gpio_init();
-	else
-		return 0;
+	return 0;
 }
 
 static int __init omap_gpio_sysinit(void)
 {
 	int ret = 0;
 
-	if (!initialized)
-		ret = _omap_gpio_init();
-
 	mpuio_init();
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 67d0086..6d95eb2 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -91,6 +91,9 @@ struct omap_gpio_platform_data {
 	struct omap_gpio_dev_attr *gpio_attr;
 };
 
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+extern int gpio_bank_count;
+
 extern int omap_gpio_init(void);	/* Call from board init only */
 extern void omap2_gpio_prepare_for_idle(int power_state);
 extern void omap2_gpio_resume_after_idle(void);
-- 
1.6.3.3


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

* [PATCH 11/13 v5] OMAP: GPIO: Make gpio_context as part of gpio_bank structure
  2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
@ 2010-08-06 12:34                     ` Charulatha V
  2010-08-06 12:34                       ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Charulatha V
  2010-08-09 23:06                     ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Kevin Hilman
  1 sibling, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

gpio_context array, which is used to save gpio bank's context,
is used only for OMAP3 architecture.

This patch moves gpio_context as part of gpio_bank structure
so that it can be specific to each gpio bank and can be
used for any OMAP architecture

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

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index a377d40..6a5cf43 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -132,6 +132,19 @@
 #define OMAP4_GPIO_CLEARDATAOUT		0x0190
 #define OMAP4_GPIO_SETDATAOUT		0x0194
 
+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_bank {
 	unsigned long pbase;
 	void __iomem *base;
@@ -156,27 +169,11 @@ struct gpio_bank {
 	u32 mod_usage;
 	u32 dbck_enable_mask;
 	struct device *dev;
+	struct omap_gpio_regs gpio_context;
 	bool dbck_flag;
 	bool off_mode_support;
 };
 
-#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
-
 /*
  * TODO: Cleanup gpio_bank usage as it is having information
  * related to all instances of the device
@@ -2032,25 +2029,25 @@ void omap_gpio_save_context(void)
 	/* 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];
-		gpio_context[i].irqenable1 =
+		bank->gpio_context.irqenable1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		gpio_context[i].irqenable2 =
+		bank->gpio_context.irqenable2 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		gpio_context[i].wake_en =
+		bank->gpio_context.wake_en =
 			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-		gpio_context[i].ctrl =
+		bank->gpio_context.ctrl =
 			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-		gpio_context[i].oe =
+		bank->gpio_context.oe =
 			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
-		gpio_context[i].leveldetect0 =
+		bank->gpio_context.leveldetect0 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		gpio_context[i].leveldetect1 =
+		bank->gpio_context.leveldetect1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		gpio_context[i].risingdetect =
+		bank->gpio_context.risingdetect =
 			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		gpio_context[i].fallingdetect =
+		bank->gpio_context.fallingdetect =
 			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		gpio_context[i].dataout =
+		bank->gpio_context.dataout =
 			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
 	}
 }
@@ -2063,24 +2060,25 @@ void omap_gpio_restore_context(void)
 	for (i = 1; i < gpio_bank_count; i++) {
 		struct gpio_bank *bank = &gpio_bank[i];
 		__raw_writel(gpio_context[i].irqenable1,
+		__raw_writel(bank->gpio_context.irqenable1,
 				bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		__raw_writel(gpio_context[i].irqenable2,
+		__raw_writel(bank->gpio_context.irqenable2,
 				bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		__raw_writel(gpio_context[i].wake_en,
+		__raw_writel(bank->gpio_context.wake_en,
 				bank->base + OMAP24XX_GPIO_WAKE_EN);
-		__raw_writel(gpio_context[i].ctrl,
+		__raw_writel(bank->gpio_context.ctrl,
 				bank->base + OMAP24XX_GPIO_CTRL);
-		__raw_writel(gpio_context[i].oe,
+		__raw_writel(bank->gpio_context.oe,
 				bank->base + OMAP24XX_GPIO_OE);
-		__raw_writel(gpio_context[i].leveldetect0,
+		__raw_writel(bank->gpio_context.leveldetect0,
 				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		__raw_writel(gpio_context[i].leveldetect1,
+		__raw_writel(bank->gpio_context.leveldetect1,
 				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		__raw_writel(gpio_context[i].risingdetect,
+		__raw_writel(bank->gpio_context.risingdetect,
 				bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		__raw_writel(gpio_context[i].fallingdetect,
+		__raw_writel(bank->gpio_context.fallingdetect,
 				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(gpio_context[i].dataout,
+		__raw_writel(bank->gpio_context.dataout,
 				bank->base + OMAP24XX_GPIO_DATAOUT);
 	}
 }
-- 
1.6.3.3


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

* [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-06 12:34                     ` [PATCH 11/13 v5] OMAP: GPIO: Make gpio_context as part of gpio_bank structure Charulatha V
@ 2010-08-06 12:34                       ` Charulatha V
  2010-08-06 12:34                         ` [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init() Charulatha V
                                           ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch makes GPIO driver to use dev_pm_ops instead of
sysdev_class. With this approach, gpio_bank_suspend & gpio_bank_resume
are not part of sys_dev_class.

According to this patch, a GPIO bank relinquishes the clock using
PM runtime APIs when all the gpios in that bank are freed. It also
relinquishes the clocks in the idle-path too, as it is possible to
have a GPIO bank requested and still allow PER domain to go to OFF state.

In the idle path (interrupt disabled context), PM runtime APIs cannot
be used as they are not mutex-free functions. Hence omap_device APIs
are used in the idle and resume after idle path.

To summarize,
1. pm_runtime_get_sync() for any gpio bank is called when one of the gpios
   is requested on the bank, in which, no other gpio is being used (when
   mod_usage becomes non-zero)
2. omap_device_enable() is called during gpio resume after idle, only
   if the particular bank is being used (if mod_usage is non-zero)
3. pm_runtime_put_sync() is called when the last used gpio in that
   gpio bank is freed (when mod_usage becomes zero)
4. omap_device_idle() is called during idle, if the particular bank
   is being used (if mod_usage is non-zero)

With this patch, GPIO's prepare_for_idle and resume_after_idle APIs
makes use of the parameter save_context and restore_context respectively
inorder to identify if save context/restore context needs to be done.

Links to related discussion:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32833.html

For suspend/resume path to work, this patch has dependency of
1. reverting the following patch:
OMAP: bus-level PM: enable use of runtime PM API for suspend/resume
http://dev.omapzoom.org/?p=swarch/linux-omap-adv.git;a=commitdiff;
h=8041359e18e49bf8a3d41f15894db9e476f3a8fc
(or)
2. Remove the locking in the omap_hwmod_for_each* function

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap2/pm24xx.c           |    4 +-
 arch/arm/mach-omap2/pm34xx.c           |   23 +-
 arch/arm/plat-omap/gpio.c              |  561 ++++++++++++++++----------------
 arch/arm/plat-omap/include/plat/gpio.h |    6 +-
 4 files changed, 297 insertions(+), 297 deletions(-)

diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 6aeedea..c01e156 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -106,7 +106,7 @@ static void omap2_enter_full_retention(void)
 	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
 	omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
 
-	omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);
+	omap2_gpio_prepare_for_idle(false);
 
 	if (omap2_pm_debug) {
 		omap2_pm_dump(0, 0, 0);
@@ -140,7 +140,7 @@ no_sleep:
 		tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
 		omap2_pm_dump(0, 1, tmp);
 	}
-	omap2_gpio_resume_after_idle();
+	omap2_gpio_resume_after_idle(false);
 
 	clk_enable(osc_ck);
 
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fb4994a..66c7e11 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -79,16 +79,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
 static struct powerdomain *cam_pwrdm;
 
-static inline void omap3_per_save_context(void)
-{
-	omap_gpio_save_context();
-}
-
-static inline void omap3_per_restore_context(void)
-{
-	omap_gpio_restore_context();
-}
-
 static void omap3_enable_io_chain(void)
 {
 	int timeout = 0;
@@ -395,15 +385,17 @@ void omap_sram_idle(void)
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		omap_uart_prepare_idle(2);
-		omap2_gpio_prepare_for_idle(per_next_state);
 		if (per_next_state == PWRDM_POWER_OFF) {
 			if (core_next_state == PWRDM_POWER_ON) {
 				per_next_state = PWRDM_POWER_RET;
 				pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
 				per_state_modified = 1;
-			} else
-				omap3_per_save_context();
+			}
 		}
+		if (per_next_state == PWRDM_POWER_OFF)
+			omap2_gpio_prepare_for_idle(true);
+		else
+			omap2_gpio_prepare_for_idle(false);
 	}
 
 	if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
@@ -471,9 +463,10 @@ void omap_sram_idle(void)
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
-		omap2_gpio_resume_after_idle();
 		if (per_prev_state == PWRDM_POWER_OFF)
-			omap3_per_restore_context();
+			omap2_gpio_resume_after_idle(true);
+		else
+			omap2_gpio_resume_after_idle(false);
 		omap_uart_resume_idle(2);
 		if (per_state_modified)
 			pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 6a5cf43..6686f9f 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -25,12 +25,12 @@
 #include <linux/pm_runtime.h>
 
 #include <plat/omap_device.h>
+#include <plat/powerdomain.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <mach/irqs.h>
 #include <mach/gpio.h>
 #include <asm/mach/irq.h>
-#include <plat/powerdomain.h>
 
 /*
  * OMAP1510 GPIO registers
@@ -179,7 +179,6 @@ struct gpio_bank {
  * related to all instances of the device
  */
 static struct gpio_bank *gpio_bank;
-
 static int bank_width;
 
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
@@ -1045,6 +1044,9 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
 	unsigned long flags;
 
+	if (!bank->mod_usage)
+		pm_runtime_get_sync(bank->dev);
+
 	spin_lock_irqsave(&bank->lock, flags);
 
 	/* Set trigger to none. You need to enable the desired trigger with
@@ -1061,22 +1063,19 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
 	}
 #endif
-	if (!cpu_class_is_omap1()) {
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is enabled, clocks are not gated */
-			ctrl &= 0xFFFFFFFE;
-			__raw_writel(ctrl, reg);
-		}
-		bank->mod_usage |= 1 << offset;
+	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
+		void __iomem *reg = bank->base;
+		u32 ctrl;
+		if (bank->method == METHOD_GPIO_24XX)
+			reg += OMAP24XX_GPIO_CTRL;
+		else if (bank->method == METHOD_GPIO_44XX)
+			reg += OMAP4_GPIO_CTRL;
+		ctrl = __raw_readl(reg);
+		/* Module is enabled, clocks are not gated */
+		ctrl &= 0xFFFFFFFE;
+		__raw_writel(ctrl, reg);
 	}
+	bank->mod_usage |= 1 << offset;
 	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
@@ -1109,24 +1108,26 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 		__raw_writel(1 << offset, reg);
 	}
 #endif
-	if (!cpu_class_is_omap1()) {
-		bank->mod_usage &= ~(1 << offset);
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is disabled, clocks are gated */
-			ctrl |= 1;
-			__raw_writel(ctrl, reg);
-		}
+	bank->mod_usage &= ~(1 << offset);
+	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
+		void __iomem *reg = bank->base;
+		u32 ctrl;
+
+		if (bank->method == METHOD_GPIO_24XX)
+			reg += OMAP24XX_GPIO_CTRL;
+		else if (bank->method == METHOD_GPIO_44XX)
+			reg += OMAP4_GPIO_CTRL;
+		ctrl = __raw_readl(reg);
+		/* Module is disabled, clocks are gated */
+		ctrl |= 1;
+		__raw_writel(ctrl, reg);
 	}
+
 	_reset_gpio(bank, bank->chip.base + offset);
 	spin_unlock_irqrestore(&bank->lock, flags);
+
+	if (!bank->mod_usage)
+		pm_runtime_put_sync(bank->dev);
 }
 
 /*
@@ -1728,7 +1729,6 @@ 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, id);
 	omap_gpio_chip_init(bank);
@@ -1741,294 +1741,222 @@ 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;
+static void omap_gpio_save_context(struct device *dev);
+static void omap_gpio_restore_context(struct device *dev);
 
-	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;
-		unsigned long flags;
+static int omap_gpio_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	void __iomem *wake_status;
+	void __iomem *wake_clear;
+	void __iomem *wake_set;
+	unsigned long flags;
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
 
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-		case METHOD_GPIO_24XX:
-			wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
-			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-			break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_44XX:
-			wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			break;
-#endif
-		default:
-			continue;
-		}
+	omap_gpio_save_context(dev);
 
-		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);
-		spin_unlock_irqrestore(&bank->lock, flags);
+	switch (bank->method) {
+	case METHOD_GPIO_1610:
+		wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
+		wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+		wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+		break;
+	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;
+	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;
+	default:
+		return 0;
 	}
 
+	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);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
 	return 0;
 }
 
-static int omap_gpio_resume(struct sys_device *dev)
+static int omap_gpio_resume(struct device *dev)
 {
-	int i;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
+	void __iomem *wake_clear;
+	void __iomem *wake_set;
+	unsigned long flags;
 
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
+	switch (bank->method) {
+	case METHOD_GPIO_1610:
+		wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+		wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+		break;
+	case METHOD_GPIO_24XX:
+		wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
+		wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
+		break;
+	case METHOD_GPIO_44XX:
+		wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
+		wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
+		break;
+	default:
 		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;
-		unsigned long flags;
-
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-		case METHOD_GPIO_24XX:
-			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-			break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_44XX:
-			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			break;
-#endif
-		default:
-			continue;
-		}
+	spin_lock_irqsave(&bank->lock, flags);
+	__raw_writel(0xffffffff, wake_clear);
+	__raw_writel(bank->saved_wakeup, wake_set);
+	spin_unlock_irqrestore(&bank->lock, flags);
 
-		spin_lock_irqsave(&bank->lock, flags);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->saved_wakeup, wake_set);
-		spin_unlock_irqrestore(&bank->lock, flags);
-	}
+	omap_gpio_restore_context(dev);
 
 	return 0;
 }
 
-static struct sysdev_class omap_gpio_sysclass = {
-	.name		= "gpio",
-	.suspend	= omap_gpio_suspend,
-	.resume		= omap_gpio_resume,
-};
-
-static struct sys_device omap_gpio_device = {
-	.id		= 0,
-	.cls		= &omap_gpio_sysclass,
-};
-
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
 static int workaround_enabled;
 
-void omap2_gpio_prepare_for_idle(int power_state)
+static int gpio_bank_runtime_suspend(struct device *dev)
 {
-	int i, c = 0;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
-
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		u32 l1, l2;
-
-		if (bank->dbck_enable_mask)
-			clk_disable(bank->dbck);
+	u32 l1, l2;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
 
-		if (power_state > PWRDM_POWER_OFF)
-			continue;
+	if (bank->dbck_enable_mask)
+		clk_disable(bank->dbck);
 
-		/* 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 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))
+		return 0;
 
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			bank->saved_datain = __raw_readl(bank->base +
+	if (bank->method == METHOD_GPIO_24XX) {
+		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 +
+		l1 = __raw_readl(bank->base +
 					OMAP24XX_GPIO_FALLINGDETECT);
-			__raw_writel(l2, bank->base +
-					OMAP24XX_GPIO_RISINGDETECT);
-		}
+		l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+	} else if (bank->method == METHOD_GPIO_44XX) {
+		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);
+	}
 
-		if (cpu_is_omap44xx()) {
-			__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
-			__raw_writel(l2, 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;
 
-		c++;
-	}
-	if (!c) {
-		workaround_enabled = 0;
-		return;
+	if (bank->method == METHOD_GPIO_24XX) {
+		__raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		__raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
+	} else if (bank->method == METHOD_GPIO_44XX) {
+		__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
+		__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
 	}
+
 	workaround_enabled = 1;
+
+	return 0;
 }
 
-void omap2_gpio_resume_after_idle(void)
+static int gpio_bank_runtime_resume(struct device *dev)
 {
-	int i;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		u32 l, gen, gen0, gen1;
-
-		if (bank->dbck_enable_mask)
-			clk_enable(bank->dbck);
+	u32 l, gen, gen0, gen1;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
 
-		if (!workaround_enabled)
-			continue;
+	if (bank->dbck_enable_mask)
+		clk_enable(bank->dbck);
 
-		if (!(bank->enabled_non_wakeup_gpios))
-			continue;
+	if ((!workaround_enabled) || (!(bank->enabled_non_wakeup_gpios)))
+		return 0;
 
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			__raw_writel(bank->saved_fallingdetect,
+	if (bank->method == METHOD_GPIO_24XX) {
+		__raw_writel(bank->saved_fallingdetect,
 				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-			__raw_writel(bank->saved_risingdetect,
+		__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,
+		l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+	} else if (bank->method == METHOD_GPIO_44XX) {
+		__raw_writel(bank->saved_fallingdetect,
 				 bank->base + OMAP4_GPIO_FALLINGDETECT);
-			__raw_writel(bank->saved_risingdetect,
+		__raw_writel(bank->saved_risingdetect,
 				 bank->base + OMAP4_GPIO_RISINGDETECT);
-			l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
-		}
+		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;
+	/* 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;
+	/*
+	 * 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);
+	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;
+	/* 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 (gen) {
+		u32 old0, old1;
 
-			if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-				old0 = __raw_readl(bank->base +
+		if (bank->method == METHOD_GPIO_24XX) {
+			old0 = __raw_readl(bank->base +
 					OMAP24XX_GPIO_LEVELDETECT0);
-				old1 = __raw_readl(bank->base +
+			old1 = __raw_readl(bank->base +
 					OMAP24XX_GPIO_LEVELDETECT1);
-				__raw_writel(old0 | gen, bank->base +
+			__raw_writel(old0 | gen, bank->base +
 					OMAP24XX_GPIO_LEVELDETECT0);
-				__raw_writel(old1 | gen, bank->base +
+			__raw_writel(old1 | gen, bank->base +
 					OMAP24XX_GPIO_LEVELDETECT1);
-				__raw_writel(old0, bank->base +
+			__raw_writel(old0, bank->base +
 					OMAP24XX_GPIO_LEVELDETECT0);
-				__raw_writel(old1, bank->base +
+			__raw_writel(old1, bank->base +
 					OMAP24XX_GPIO_LEVELDETECT1);
-			}
-
-			if (cpu_is_omap44xx()) {
-				old0 = __raw_readl(bank->base +
+		} else if (bank->method == METHOD_GPIO_44XX) {
+			old0 = __raw_readl(bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-				old1 = __raw_readl(bank->base +
+			old1 = __raw_readl(bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0 | l, bank->base +
+			__raw_writel(old0 | l, bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1 | l, bank->base +
+			__raw_writel(old1 | l, bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0, bank->base +
+			__raw_writel(old0, bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1, bank->base +
+			__raw_writel(old1, bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-			}
 		}
 	}
 
+	return 0;
 }
 
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-/* save the registers of bank 2-6 */
-void omap_gpio_save_context(void)
+/* save the registers of bank */
+static void omap_gpio_save_context(struct device *dev)
 {
-	int i;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
 
-	/* 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];
+	if (bank->method == METHOD_GPIO_24XX) {
 		bank->gpio_context.irqenable1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		bank->gpio_context.irqenable2 =
@@ -2049,17 +1977,37 @@ void omap_gpio_save_context(void)
 			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
 		bank->gpio_context.dataout =
 			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
+	} else if (bank->method == METHOD_GPIO_44XX) {
+		bank->gpio_context.irqenable1 =
+			__raw_readl(bank->base + OMAP4_GPIO_IRQENABLE1);
+		bank->gpio_context.irqenable2 =
+			__raw_readl(bank->base + OMAP4_GPIO_IRQENABLE2);
+		bank->gpio_context.wake_en =
+			__raw_readl(bank->base + OMAP4_GPIO_WAKE_EN);
+		bank->gpio_context.ctrl =
+			__raw_readl(bank->base + OMAP4_GPIO_CTRL);
+		bank->gpio_context.oe =
+			__raw_readl(bank->base + OMAP4_GPIO_OE);
+		bank->gpio_context.leveldetect0 =
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0);
+		bank->gpio_context.leveldetect1 =
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
+		bank->gpio_context.risingdetect =
+			__raw_readl(bank->base + OMAP4_GPIO_RISINGDETECT);
+		bank->gpio_context.fallingdetect =
+			__raw_readl(bank->base + OMAP4_GPIO_FALLINGDETECT);
+		bank->gpio_context.dataout =
+			__raw_readl(bank->base + OMAP4_GPIO_DATAOUT);
 	}
 }
 
 /* restore the required registers of bank 2-6 */
-void omap_gpio_restore_context(void)
+static void omap_gpio_restore_context(struct device *dev)
 {
-	int i;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = &gpio_bank[pdev->id];
 
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		__raw_writel(gpio_context[i].irqenable1,
+	if (bank->method == METHOD_GPIO_24XX) {
 		__raw_writel(bank->gpio_context.irqenable1,
 				bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		__raw_writel(bank->gpio_context.irqenable2,
@@ -2080,14 +2028,88 @@ void omap_gpio_restore_context(void)
 				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
 		__raw_writel(bank->gpio_context.dataout,
 				bank->base + OMAP24XX_GPIO_DATAOUT);
+	} else if (bank->method == METHOD_GPIO_44XX) {
+		__raw_writel(bank->gpio_context.irqenable1,
+				bank->base + OMAP4_GPIO_IRQENABLE1);
+		__raw_writel(bank->gpio_context.irqenable2,
+				bank->base + OMAP4_GPIO_IRQENABLE2);
+		__raw_writel(bank->gpio_context.wake_en,
+				bank->base + OMAP4_GPIO_WAKE_EN);
+		__raw_writel(bank->gpio_context.ctrl,
+				bank->base + OMAP4_GPIO_CTRL);
+		__raw_writel(bank->gpio_context.oe,
+				bank->base + OMAP4_GPIO_OE);
+		__raw_writel(bank->gpio_context.leveldetect0,
+				bank->base + OMAP4_GPIO_LEVELDETECT0);
+		__raw_writel(bank->gpio_context.leveldetect1,
+				bank->base + OMAP4_GPIO_LEVELDETECT1);
+		__raw_writel(bank->gpio_context.risingdetect,
+				bank->base + OMAP4_GPIO_RISINGDETECT);
+		__raw_writel(bank->gpio_context.fallingdetect,
+				bank->base + OMAP4_GPIO_FALLINGDETECT);
+		__raw_writel(bank->gpio_context.dataout,
+				bank->base + OMAP4_GPIO_DATAOUT);
 	}
 }
+
+void omap2_gpio_prepare_for_idle(bool save_context)
+{
+#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ARCH_OMAP2PLUS)
+	int i;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		struct platform_device *pdev = to_platform_device(bank->dev);
+
+		/*
+		 * Only if the device is used & if it supports off-mode,
+		 * prepare for idle.
+		 */
+		if ((!bank->off_mode_support) || (!bank->mod_usage))
+			continue;
+
+		gpio_bank_runtime_suspend(bank->dev);
+		if (save_context)
+			omap_gpio_save_context(bank->dev);
+		omap_device_idle(pdev);
+	}
+#endif
+}
+
+void omap2_gpio_resume_after_idle(bool restore_context)
+{
+#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ARCH_OMAP2PLUS)
+	int i;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		if ((bank->off_mode_support) && (bank->mod_usage)) {
+			struct platform_device *pdev =
+						to_platform_device(bank->dev);
+
+			omap_device_enable(pdev);
+			if (restore_context)
+				omap_gpio_restore_context(bank->dev);
+			gpio_bank_runtime_resume(bank->dev);
+		}
+	}
+
+	workaround_enabled = 0;
 #endif
+}
+
+static const struct dev_pm_ops gpio_pm_ops = {
+	.suspend	 = omap_gpio_suspend,
+	.resume		 = omap_gpio_resume,
+	.runtime_suspend = gpio_bank_runtime_suspend,
+	.runtime_resume	 = gpio_bank_runtime_resume,
+};
 
 static struct platform_driver omap_gpio_driver = {
 	.probe		= omap_gpio_probe,
 	.driver		= {
 		.name	= "omap-gpio",
+		.pm	= &gpio_pm_ops,
 	},
 };
 
@@ -2110,21 +2132,8 @@ int __init omap_gpio_init(void)
 
 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) {
-			ret = sysdev_class_register(&omap_gpio_sysclass);
-			if (ret == 0)
-				ret = sysdev_register(&omap_gpio_device);
-		}
-	}
-#endif
-
-	return ret;
+	return 0;
 }
 
 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 6d95eb2..b84b179 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -95,12 +95,10 @@ struct omap_gpio_platform_data {
 extern int gpio_bank_count;
 
 extern int omap_gpio_init(void);	/* Call from board init only */
-extern void omap2_gpio_prepare_for_idle(int power_state);
-extern void omap2_gpio_resume_after_idle(void);
+extern void omap2_gpio_prepare_for_idle(bool save_context);
+extern void omap2_gpio_resume_after_idle(bool restore_context);
 extern void omap_set_gpio_debounce(int gpio, int enable);
 extern void omap_set_gpio_debounce_time(int gpio, int enable);
-extern void omap_gpio_save_context(void);
-extern void omap_gpio_restore_context(void);
 /*-------------------------------------------------------------------------*/
 
 /* Wrappers for "new style" GPIO calls, using the new infrastructure
-- 
1.6.3.3


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

* [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init()
  2010-08-06 12:34                       ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Charulatha V
@ 2010-08-06 12:34                         ` Charulatha V
  2010-08-09 23:00                           ` Kevin Hilman
  2010-08-09 21:45                         ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Kevin Hilman
  2010-08-10  0:21                         ` Kevin Hilman
  2 siblings, 1 reply; 38+ messages in thread
From: Charulatha V @ 2010-08-06 12:34 UTC (permalink / raw)
  To: linux-omap; +Cc: paul, khilman, b-cousson, rnayak, Charulatha V, Basak, Partha

This patch removes the usage of omap_gpio_init() from all
omap board files since omap_gpio_init() does nothing, after gpio
is implemented as a platform device.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Basak, Partha <p-basak2@ti.com>
---
 arch/arm/mach-omap1/board-ams-delta.c      |    1 -
 arch/arm/mach-omap1/board-fsample.c        |    1 -
 arch/arm/mach-omap1/board-h2.c             |    1 -
 arch/arm/mach-omap1/board-h3.c             |    1 -
 arch/arm/mach-omap1/board-htcherald.c      |    1 -
 arch/arm/mach-omap1/board-innovator.c      |    1 -
 arch/arm/mach-omap1/board-nokia770.c       |    1 -
 arch/arm/mach-omap1/board-osk.c            |    1 -
 arch/arm/mach-omap1/board-palmte.c         |    1 -
 arch/arm/mach-omap1/board-palmz71.c        |    1 -
 arch/arm/mach-omap1/board-perseus2.c       |    1 -
 arch/arm/mach-omap1/board-sx1.c            |    1 -
 arch/arm/mach-omap1/board-voiceblue.c      |    1 -
 arch/arm/mach-omap2/board-2430sdp.c        |    1 -
 arch/arm/mach-omap2/board-3430sdp.c        |    1 -
 arch/arm/mach-omap2/board-3630sdp.c        |    1 -
 arch/arm/mach-omap2/board-4430sdp.c        |    1 -
 arch/arm/mach-omap2/board-am3517evm.c      |    1 -
 arch/arm/mach-omap2/board-apollon.c        |    1 -
 arch/arm/mach-omap2/board-cm-t35.c         |    1 -
 arch/arm/mach-omap2/board-devkit8000.c     |    1 -
 arch/arm/mach-omap2/board-h4.c             |    1 -
 arch/arm/mach-omap2/board-igep0020.c       |    1 -
 arch/arm/mach-omap2/board-ldp.c            |    1 -
 arch/arm/mach-omap2/board-n8x0.c           |    1 -
 arch/arm/mach-omap2/board-omap3beagle.c    |    1 -
 arch/arm/mach-omap2/board-omap3evm.c       |    1 -
 arch/arm/mach-omap2/board-omap3pandora.c   |    1 -
 arch/arm/mach-omap2/board-omap3stalker.c   |    1 -
 arch/arm/mach-omap2/board-omap3touchbook.c |    1 -
 arch/arm/mach-omap2/board-omap4panda.c     |    1 -
 arch/arm/mach-omap2/board-overo.c          |    1 -
 arch/arm/mach-omap2/board-rx51.c           |    1 -
 arch/arm/mach-omap2/board-zoom2.c          |    1 -
 arch/arm/mach-omap2/board-zoom3.c          |    1 -
 35 files changed, 0 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 41992ab..774867f 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -136,7 +136,6 @@ static void __init ams_delta_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct map_desc ams_delta_io_desc[] __initdata = {
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 180ce79..09b6165 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -325,7 +325,6 @@ static void __init omap_fsample_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 	fsample_init_smc91x();
 }
 
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d2cda58..cf9aaff 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -374,7 +374,6 @@ static void __init h2_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 	h2_init_smc91x();
 }
 
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index c2ef4ff..423b45e 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -435,7 +435,6 @@ static void __init h3_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 	h3_init_smc91x();
 }
 
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 311899f..bc8f56f 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -278,7 +278,6 @@ static void __init htcherald_init(void)
 {
 	printk(KERN_INFO "HTC Herald init.\n");
 
-	omap_gpio_init();
 
 	omap_board_config = htcherald_config;
 	omap_board_config_size = ARRAY_SIZE(htcherald_config);
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 3daf87a..27c283d 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -290,7 +290,6 @@ static void __init innovator_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 		omap1510_fpga_init_irq();
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 51a4539..397febe 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -246,7 +246,6 @@ static void __init omap_nokia770_init(void)
 	platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
 	spi_register_board_info(nokia770_spi_board_info,
 				ARRAY_SIZE(nokia770_spi_board_info));
-	omap_gpio_init();
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, NULL, 0);
 	hwa742_dev_init();
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 679740c..fcd67d0 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -283,7 +283,6 @@ static void __init osk_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 	osk_init_smc91x();
 	osk_init_cf();
 }
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 782bb25..69708ac 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -63,7 +63,6 @@ static void __init omap_palmte_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static const int palmte_keymap[] = {
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 6636290..644d217 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -62,7 +62,6 @@ omap_palmz71_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static int palmz71_keymap[] = {
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 34ab354..d8dbb4a 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -293,7 +293,6 @@ static void __init omap_perseus2_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 	perseus2_init_smc91x();
 }
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2eb148b..18093a5 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -409,7 +409,6 @@ static void __init omap_sx1_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 }
 /*----------------------------------------*/
 
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 6b3cf14..794c497 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -158,7 +158,6 @@ static void __init voiceblue_init_irq(void)
 {
 	omap1_init_common_hw();
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static void __init voiceblue_init(void)
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 8538e41..b86824e 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -144,7 +144,6 @@ static void __init omap_2430sdp_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 67b95b5..9f38f5f 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -328,7 +328,6 @@ static void __init omap_3430sdp_init_irq(void)
 	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
 	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static int sdp3430_batt_table[] = {
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index b359c3f..78973f5 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -76,7 +76,6 @@ static void __init omap_sdp_init_irq(void)
 	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
 			h8mbx00u0mer0em_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 #ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..b7f6369 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -181,7 +181,6 @@ static void __init omap_4430sdp_init_irq(void)
 	omap2_gp_clockevent_set_gptimer(1);
 #endif
 	gic_init_irq();
-	omap_gpio_init();
 }
 
 static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 4d0f585..dd7aa66 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -372,7 +372,6 @@ static void __init am3517_evm_init_irq(void)
 
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index c6421a7..cd70971 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -280,7 +280,6 @@ static void __init omap_apollon_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(apollon_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 	apollon_init_smc91x();
 }
 
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index e10bc10..000c7d4 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -687,7 +687,6 @@ static void __init cm_t35_init_irq(void)
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct omap_board_mux board_mux[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index a07086d..82b73e5 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -452,7 +452,6 @@ static void __init devkit8000_init_irq(void)
 #ifdef CONFIG_OMAP_32K_TIMER
 	omap2_gp_clockevent_set_gptimer(12);
 #endif
-	omap_gpio_init();
 }
 
 static void __init devkit8000_ads7846_init(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index e09bd68..4eb7c24 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -293,7 +293,6 @@ static void __init omap_h4_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(h4_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 	h4_init_flash();
 }
 
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 175f043..63a68ef 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -406,7 +406,6 @@ static void __init igep2_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(igep2_config);
 	omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct twl4030_codec_audio_data igep2_audio_data = {
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 00d9b13..097c8b9 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -292,7 +292,6 @@ static void __init omap_ldp_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 	ldp_init_smsc911x();
 }
 
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index a3e2b49..afa0ce5 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -648,7 +648,6 @@ static void __init n8x0_init_irq(void)
 {
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 #ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 87969c7..fda730b 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -393,7 +393,6 @@ static void __init omap3_beagle_init_irq(void)
 #ifdef CONFIG_OMAP_32K_TIMER
 	omap2_gp_clockevent_set_gptimer(12);
 #endif
-	omap_gpio_init();
 }
 
 static struct platform_device *omap3_beagle_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 6494dbd..cbb7614 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -627,7 +627,6 @@ static void __init omap3_evm_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct platform_device *omap3_evm_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 55836fa..ad9cd5f 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -588,7 +588,6 @@ static void __init omap3pandora_init_irq(void)
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static void pandora_wl1251_set_power(bool enable)
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index bcd01d2..1fbce09 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -588,7 +588,6 @@ static void __init omap3_stalker_init_irq(void)
 #ifdef CONFIG_OMAP_32K_TIMER
 	omap2_gp_clockevent_set_gptimer(12);
 #endif
-	omap_gpio_init();
 }
 
 static struct platform_device *omap3_stalker_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 663c62d..6118042 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -427,7 +427,6 @@ static void __init omap3_touchbook_init_irq(void)
 #ifdef CONFIG_OMAP_32K_TIMER
 	omap2_gp_clockevent_set_gptimer(12);
 #endif
-	omap_gpio_init();
 }
 
 static struct platform_device *omap3_touchbook_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index c03d1d5..09b0da1 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -44,7 +44,6 @@ static void __init omap4_panda_init_irq(void)
 {
 	omap2_init_common_hw(NULL, NULL);
 	gic_init_irq();
-	omap_gpio_init();
 }
 
 static struct omap_musb_board_data musb_board_data = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 4c48436..099f4f7 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -415,7 +415,6 @@ static void __init overo_init_irq(void)
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 static struct platform_device *overo_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index a58e8cb..04b0259 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -108,7 +108,6 @@ static void __init rx51_init_irq(void)
 	sdrc_params = rx51_get_sdram_timings();
 	omap2_init_common_hw(sdrc_params, sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 extern void __init rx51_peripherals_init(void);
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 3ad9ecf..634b05b 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -31,7 +31,6 @@ static void __init omap_zoom2_init_irq(void)
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 				 mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 /* REVISIT: These audio entries can be removed once MFD code is merged */
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 6ca0b83..a048981 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -76,7 +76,6 @@ static void __init omap_zoom_init_irq(void)
 	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
 			h8mbx00u0mer0em_sdrc_params);
 	omap_init_irq();
-	omap_gpio_init();
 }
 
 #ifdef CONFIG_OMAP_MUX
-- 
1.6.3.3


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

* RE: [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx chip GPIO init
  2010-08-06 12:34     ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " Charulatha V
  2010-08-06 12:34       ` [PATCH 04/13 v5] OMAP: GPIO: Introduce support for OMAP7xx " Charulatha V
@ 2010-08-09  3:51       ` DebBarma, Tarun Kanti
  1 sibling, 0 replies; 38+ messages in thread
From: DebBarma, Tarun Kanti @ 2010-08-09  3:51 UTC (permalink / raw)
  To: Varadarajan, Charulatha, linux-omap
  Cc: paul, khilman, Cousson, Benoit, Nayak, Rajendra, Basak, Partha

Charu,

> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Varadarajan, Charulatha
> Sent: Friday, August 06, 2010 6:04 PM
> To: linux-omap@vger.kernel.org
> Cc: paul@pwsan.com; khilman@deeprootsystems.com; Cousson, Benoit; Nayak,
> Rajendra; Varadarajan, Charulatha; Basak, Partha
> Subject: [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx chip
> GPIO init
> 
> This patch adds support for handling OMAP16xx specific gpio_init
> by providing platform device data and doing device registration.
> 
> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>
> ---
>  arch/arm/mach-omap1/gpio16xx.c |  208
> ++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 208 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap1/gpio16xx.c
> 
> diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-
> omap1/gpio16xx.c
> new file mode 100644
> index 0000000..727c52b
> --- /dev/null
> +++ b/arch/arm/mach-omap1/gpio16xx.c
> @@ -0,0 +1,208 @@
> +/*
> + * OMAP16XX-specific gpio code
> + *
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + *
> + * Author:
> + *	Charulatha V <charu@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/gpio.h>
> +
> +#define OMAP1610_GPIO1_BASE		0xfffbe400
> +#define OMAP1610_GPIO2_BASE		0xfffbec00
> +#define OMAP1610_GPIO3_BASE		0xfffbb400
> +#define OMAP1610_GPIO4_BASE		0xfffbbc00
> +#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
> +
> +static struct omap_gpio_dev_attr omap16xx_gpio_attr = {
> +	.bank_width = 16,
> +};
> +
> +/*
> + * OMAP16XX MPU GPIO interface data
> + */
> +static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
> +	{
> +		.start	= OMAP1_MPUIO_VBASE,
> +		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +	{
> +		.start	= INT_MPUIO,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config
> = {
> +	.virtual_irq_start	= IH_MPUIO_BASE,
> +	.bank_type		= METHOD_MPUIO,
> +	.gpio_attr		= &omap16xx_gpio_attr,
> +};
> +
> +static struct __initdata platform_device omap16xx_mpu_gpio = {
> +	.name           = "omap-gpio",
> +	.id             = 0,
> +	.dev            = {
> +		.platform_data = &omap16xx_mpu_gpio_config,
> +	},
> +	.num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
> +	.resource = omap16xx_mpu_gpio_resources,
> +};
> +
> +/*
> + * OMAP16XX GPIO1 interface data
> + */
> +static struct __initdata resource omap16xx_gpio1_resources[] = {
> +	{
> +		.start	= OMAP1610_GPIO1_BASE,
> +		.end	= OMAP1610_GPIO1_BASE + SZ_2K - 1,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +	{
> +		.start	= INT_GPIO_BANK1,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config =
> {
> +	.virtual_irq_start	= IH_GPIO_BASE,
> +	.bank_type		= METHOD_GPIO_1610,
> +	.gpio_attr		= &omap16xx_gpio_attr,
> +};
> +
> +static struct __initdata platform_device omap16xx_gpio1 = {
> +	.name           = "omap-gpio",
> +	.id             = 1,
> +	.dev            = {
> +		.platform_data = &omap16xx_gpio1_config,
> +	},
> +	.num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
> +	.resource = omap16xx_gpio1_resources,
> +};
> +
> +/*
> + * OMAP16XX GPIO2 interface data
> + */
> +static struct __initdata resource omap16xx_gpio2_resources[] = {
> +	{
> +		.start	= OMAP1610_GPIO2_BASE,
> +		.end	= OMAP1610_GPIO2_BASE + SZ_2K - 1,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +	{
> +		.start	= INT_1610_GPIO_BANK2,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config =
> {
> +	.virtual_irq_start	= IH_GPIO_BASE + 16,
> +	.bank_type		= METHOD_GPIO_1610,
> +	.gpio_attr		= &omap16xx_gpio_attr,
> +};
> +
> +static struct __initdata platform_device omap16xx_gpio2 = {
> +	.name           = "omap-gpio",
> +	.id             = 2,
> +	.dev            = {
> +		.platform_data = &omap16xx_gpio2_config,
> +	},
> +	.num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
> +	.resource = omap16xx_gpio2_resources,
> +};
> +
> +/*
> + * OMAP16XX GPIO3 interface data
> + */
> +static struct __initdata resource omap16xx_gpio3_resources[] = {
> +	{
> +		.start	= OMAP1610_GPIO3_BASE,
> +		.end	= OMAP1610_GPIO3_BASE + SZ_2K - 1,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +	{
> +		.start	= INT_1610_GPIO_BANK3,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config =
> {
> +	.virtual_irq_start	= IH_GPIO_BASE + 32,
> +	.bank_type		= METHOD_GPIO_1610,
> +	.gpio_attr		= &omap16xx_gpio_attr,
> +};
> +
> +static struct __initdata platform_device omap16xx_gpio3 = {
> +	.name           = "omap-gpio",
> +	.id             = 3,
> +	.dev            = {
> +		.platform_data = &omap16xx_gpio3_config,
> +	},
> +	.num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
> +	.resource = omap16xx_gpio3_resources,
> +};
> +
> +/*
> + * OMAP16XX GPIO4 interface data
> +  */
> +static struct __initdata resource omap16xx_gpio4_resources[] = {
> +	{
> +		.start	= OMAP1610_GPIO4_BASE,
> +		.end	= OMAP1610_GPIO4_BASE + SZ_2K - 1,
> +		.flags	= IORESOURCE_MEM,
> +	},
> +	{
> +		.start	= INT_1610_GPIO_BANK4,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config =
> {
> +	.virtual_irq_start	= IH_GPIO_BASE + 48,
> +	.bank_type		= METHOD_GPIO_1610,
> +	.gpio_attr		= &omap16xx_gpio_attr,
> +};
> +
> +static struct __initdata platform_device omap16xx_gpio4 = {
> +	.name           = "omap-gpio",
> +	.id             = 4,
> +	.dev            = {
> +		.platform_data = &omap16xx_gpio4_config,
> +	},
> +	.num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
> +	.resource = omap16xx_gpio4_resources,
> +};
> +
> +static struct __initdata platform_device * omap16xx_gpio_dev[] = {
> +	&omap16xx_mpu_gpio,
> +	&omap16xx_gpio1,
> +	&omap16xx_gpio2,
> +	&omap16xx_gpio3,
> +	&omap16xx_gpio4,
> +};
> +
> +/*
> + * omap16xx_gpio_init needs to be done before
> + * machine_init functions access gpio APIs.
> + * Hence omap16xx_gpio_init is a postcore_initcall.
> + */
> +static int __init omap16xx_gpio_init(void)
> +{
> +	int i;
> +
> +	if (!cpu_is_omap16xx())
> +		return -EINVAL;
> +
> +	for (i = 0; i < sizeof(omap16xx_gpio_dev); i++)
> +			platform_device_register(omap16xx_gpio_dev[i]);
> +
> +	gpio_bank_count = sizeof(omap16xx_gpio_dev);
> +
I believe, you meant ARRAY_SIZE(omap16xx_gpio_dev) ?

> +	return 0;
> +}
> +postcore_initcall(omap16xx_gpio_init);
> --
> 1.6.3.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-06 12:34                       ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Charulatha V
  2010-08-06 12:34                         ` [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init() Charulatha V
@ 2010-08-09 21:45                         ` Kevin Hilman
  2010-08-10  0:21                         ` Kevin Hilman
  2 siblings, 0 replies; 38+ messages in thread
From: Kevin Hilman @ 2010-08-09 21:45 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> @@ -1728,7 +1729,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
>  	}
>  
>  	pm_runtime_enable(bank->dev);
> -	pm_runtime_get_sync(bank->dev);

Why do you remove this?

>  	omap_gpio_mod_init(bank, id);

This next call accesses GPIO registers and will fault if the GPIO module
is reset.

You get lucky currently as the GPIO hwmods are not reset on init due to
a problem under investigation.  (see this patch in Benoit's series)
[PATCH v3 6/7] OMAP: hwmod: Temporary prevent reset during _setup for GPIOs

Kevin

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

* Re: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-06 12:34 ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Charulatha V
  2010-08-06 12:34   ` [PATCH 02/13 v5] OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init Charulatha V
@ 2010-08-09 22:20   ` Kevin Hilman
  2010-08-10  5:18     ` Varadarajan, Charulatha
  1 sibling, 1 reply; 38+ messages in thread
From: Kevin Hilman @ 2010-08-09 22:20 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> This is in prepartion for implementing GPIO as a platform device.
> gpio bank's base addresses are moved from gpio.c to plat/gpio.h.
>
> This patch also modifies omap_gpio_init() to make use of
> omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init() does
> the module init by clearing the status register and initializing the
> GPIO control register. omap_gpio_chip_init() initializes the chip request,
> free, get, set and other function pointers and sets the gpio irq handler.
>
> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>

[...]

> +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);
> +			/* Enable autoidle for the OCP interface */
> +			omap_writel(1 << 0, 0x48306814);

This autoidle stuff should be removed in this series as setting this is
handled by the hwmod layer.

> +		} 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];
> +
> +			/* Enable autoidle for the OCP interface */
> +			omap_writel(1 << 0, 0x48019010);

ditto

> +		}

Kevin

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

* Re: [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init()
  2010-08-06 12:34                         ` [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init() Charulatha V
@ 2010-08-09 23:00                           ` Kevin Hilman
  2010-08-10  5:22                             ` Varadarajan, Charulatha
  0 siblings, 1 reply; 38+ messages in thread
From: Kevin Hilman @ 2010-08-09 23:00 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> This patch removes the usage of omap_gpio_init() from all
> omap board files since omap_gpio_init() does nothing, after gpio
> is implemented as a platform device.

This patch should also remove the function from plat/gpio.c

Kevin

> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>
> ---
>  arch/arm/mach-omap1/board-ams-delta.c      |    1 -
>  arch/arm/mach-omap1/board-fsample.c        |    1 -
>  arch/arm/mach-omap1/board-h2.c             |    1 -
>  arch/arm/mach-omap1/board-h3.c             |    1 -
>  arch/arm/mach-omap1/board-htcherald.c      |    1 -
>  arch/arm/mach-omap1/board-innovator.c      |    1 -
>  arch/arm/mach-omap1/board-nokia770.c       |    1 -
>  arch/arm/mach-omap1/board-osk.c            |    1 -
>  arch/arm/mach-omap1/board-palmte.c         |    1 -
>  arch/arm/mach-omap1/board-palmz71.c        |    1 -
>  arch/arm/mach-omap1/board-perseus2.c       |    1 -
>  arch/arm/mach-omap1/board-sx1.c            |    1 -
>  arch/arm/mach-omap1/board-voiceblue.c      |    1 -
>  arch/arm/mach-omap2/board-2430sdp.c        |    1 -
>  arch/arm/mach-omap2/board-3430sdp.c        |    1 -
>  arch/arm/mach-omap2/board-3630sdp.c        |    1 -
>  arch/arm/mach-omap2/board-4430sdp.c        |    1 -
>  arch/arm/mach-omap2/board-am3517evm.c      |    1 -
>  arch/arm/mach-omap2/board-apollon.c        |    1 -
>  arch/arm/mach-omap2/board-cm-t35.c         |    1 -
>  arch/arm/mach-omap2/board-devkit8000.c     |    1 -
>  arch/arm/mach-omap2/board-h4.c             |    1 -
>  arch/arm/mach-omap2/board-igep0020.c       |    1 -
>  arch/arm/mach-omap2/board-ldp.c            |    1 -
>  arch/arm/mach-omap2/board-n8x0.c           |    1 -
>  arch/arm/mach-omap2/board-omap3beagle.c    |    1 -
>  arch/arm/mach-omap2/board-omap3evm.c       |    1 -
>  arch/arm/mach-omap2/board-omap3pandora.c   |    1 -
>  arch/arm/mach-omap2/board-omap3stalker.c   |    1 -
>  arch/arm/mach-omap2/board-omap3touchbook.c |    1 -
>  arch/arm/mach-omap2/board-omap4panda.c     |    1 -
>  arch/arm/mach-omap2/board-overo.c          |    1 -
>  arch/arm/mach-omap2/board-rx51.c           |    1 -
>  arch/arm/mach-omap2/board-zoom2.c          |    1 -
>  arch/arm/mach-omap2/board-zoom3.c          |    1 -
>  35 files changed, 0 insertions(+), 35 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
> index 41992ab..774867f 100644
> --- a/arch/arm/mach-omap1/board-ams-delta.c
> +++ b/arch/arm/mach-omap1/board-ams-delta.c
> @@ -136,7 +136,6 @@ static void __init ams_delta_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct map_desc ams_delta_io_desc[] __initdata = {
> diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
> index 180ce79..09b6165 100644
> --- a/arch/arm/mach-omap1/board-fsample.c
> +++ b/arch/arm/mach-omap1/board-fsample.c
> @@ -325,7 +325,6 @@ static void __init omap_fsample_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  	fsample_init_smc91x();
>  }
>  
> diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
> index d2cda58..cf9aaff 100644
> --- a/arch/arm/mach-omap1/board-h2.c
> +++ b/arch/arm/mach-omap1/board-h2.c
> @@ -374,7 +374,6 @@ static void __init h2_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  	h2_init_smc91x();
>  }
>  
> diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
> index c2ef4ff..423b45e 100644
> --- a/arch/arm/mach-omap1/board-h3.c
> +++ b/arch/arm/mach-omap1/board-h3.c
> @@ -435,7 +435,6 @@ static void __init h3_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  	h3_init_smc91x();
>  }
>  
> diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
> index 311899f..bc8f56f 100644
> --- a/arch/arm/mach-omap1/board-htcherald.c
> +++ b/arch/arm/mach-omap1/board-htcherald.c
> @@ -278,7 +278,6 @@ static void __init htcherald_init(void)
>  {
>  	printk(KERN_INFO "HTC Herald init.\n");
>  
> -	omap_gpio_init();
>  
>  	omap_board_config = htcherald_config;
>  	omap_board_config_size = ARRAY_SIZE(htcherald_config);
> diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
> index 3daf87a..27c283d 100644
> --- a/arch/arm/mach-omap1/board-innovator.c
> +++ b/arch/arm/mach-omap1/board-innovator.c
> @@ -290,7 +290,6 @@ static void __init innovator_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  #ifdef CONFIG_ARCH_OMAP15XX
>  	if (cpu_is_omap1510()) {
>  		omap1510_fpga_init_irq();
> diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
> index 51a4539..397febe 100644
> --- a/arch/arm/mach-omap1/board-nokia770.c
> +++ b/arch/arm/mach-omap1/board-nokia770.c
> @@ -246,7 +246,6 @@ static void __init omap_nokia770_init(void)
>  	platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
>  	spi_register_board_info(nokia770_spi_board_info,
>  				ARRAY_SIZE(nokia770_spi_board_info));
> -	omap_gpio_init();
>  	omap_serial_init();
>  	omap_register_i2c_bus(1, 100, NULL, 0);
>  	hwa742_dev_init();
> diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
> index 679740c..fcd67d0 100644
> --- a/arch/arm/mach-omap1/board-osk.c
> +++ b/arch/arm/mach-omap1/board-osk.c
> @@ -283,7 +283,6 @@ static void __init osk_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  	osk_init_smc91x();
>  	osk_init_cf();
>  }
> diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
> index 782bb25..69708ac 100644
> --- a/arch/arm/mach-omap1/board-palmte.c
> +++ b/arch/arm/mach-omap1/board-palmte.c
> @@ -63,7 +63,6 @@ static void __init omap_palmte_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static const int palmte_keymap[] = {
> diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
> index 6636290..644d217 100644
> --- a/arch/arm/mach-omap1/board-palmz71.c
> +++ b/arch/arm/mach-omap1/board-palmz71.c
> @@ -62,7 +62,6 @@ omap_palmz71_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static int palmz71_keymap[] = {
> diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
> index 34ab354..d8dbb4a 100644
> --- a/arch/arm/mach-omap1/board-perseus2.c
> +++ b/arch/arm/mach-omap1/board-perseus2.c
> @@ -293,7 +293,6 @@ static void __init omap_perseus2_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  	perseus2_init_smc91x();
>  }
>  /* Only FPGA needs to be mapped here. All others are done with ioremap */
> diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
> index 2eb148b..18093a5 100644
> --- a/arch/arm/mach-omap1/board-sx1.c
> +++ b/arch/arm/mach-omap1/board-sx1.c
> @@ -409,7 +409,6 @@ static void __init omap_sx1_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  /*----------------------------------------*/
>  
> diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
> index 6b3cf14..794c497 100644
> --- a/arch/arm/mach-omap1/board-voiceblue.c
> +++ b/arch/arm/mach-omap1/board-voiceblue.c
> @@ -158,7 +158,6 @@ static void __init voiceblue_init_irq(void)
>  {
>  	omap1_init_common_hw();
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static void __init voiceblue_init(void)
> diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
> index 8538e41..b86824e 100644
> --- a/arch/arm/mach-omap2/board-2430sdp.c
> +++ b/arch/arm/mach-omap2/board-2430sdp.c
> @@ -144,7 +144,6 @@ static void __init omap_2430sdp_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
> diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
> index 67b95b5..9f38f5f 100644
> --- a/arch/arm/mach-omap2/board-3430sdp.c
> +++ b/arch/arm/mach-omap2/board-3430sdp.c
> @@ -328,7 +328,6 @@ static void __init omap_3430sdp_init_irq(void)
>  	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
>  	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static int sdp3430_batt_table[] = {
> diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
> index b359c3f..78973f5 100644
> --- a/arch/arm/mach-omap2/board-3630sdp.c
> +++ b/arch/arm/mach-omap2/board-3630sdp.c
> @@ -76,7 +76,6 @@ static void __init omap_sdp_init_irq(void)
>  	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
>  			h8mbx00u0mer0em_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  #ifdef CONFIG_OMAP_MUX
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> index 9447644..b7f6369 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -181,7 +181,6 @@ static void __init omap_4430sdp_init_irq(void)
>  	omap2_gp_clockevent_set_gptimer(1);
>  #endif
>  	gic_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct omap_musb_board_data musb_board_data = {
> diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
> index 4d0f585..dd7aa66 100644
> --- a/arch/arm/mach-omap2/board-am3517evm.c
> +++ b/arch/arm/mach-omap2/board-am3517evm.c
> @@ -372,7 +372,6 @@ static void __init am3517_evm_init_irq(void)
>  
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
> diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
> index c6421a7..cd70971 100644
> --- a/arch/arm/mach-omap2/board-apollon.c
> +++ b/arch/arm/mach-omap2/board-apollon.c
> @@ -280,7 +280,6 @@ static void __init omap_apollon_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(apollon_config);
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  	apollon_init_smc91x();
>  }
>  
> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index e10bc10..000c7d4 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -687,7 +687,6 @@ static void __init cm_t35_init_irq(void)
>  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
>  			     mt46h32m32lf6_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct omap_board_mux board_mux[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
> index a07086d..82b73e5 100644
> --- a/arch/arm/mach-omap2/board-devkit8000.c
> +++ b/arch/arm/mach-omap2/board-devkit8000.c
> @@ -452,7 +452,6 @@ static void __init devkit8000_init_irq(void)
>  #ifdef CONFIG_OMAP_32K_TIMER
>  	omap2_gp_clockevent_set_gptimer(12);
>  #endif
> -	omap_gpio_init();
>  }
>  
>  static void __init devkit8000_ads7846_init(void)
> diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
> index e09bd68..4eb7c24 100644
> --- a/arch/arm/mach-omap2/board-h4.c
> +++ b/arch/arm/mach-omap2/board-h4.c
> @@ -293,7 +293,6 @@ static void __init omap_h4_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(h4_config);
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  	h4_init_flash();
>  }
>  
> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index 175f043..63a68ef 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -406,7 +406,6 @@ static void __init igep2_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(igep2_config);
>  	omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct twl4030_codec_audio_data igep2_audio_data = {
> diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
> index 00d9b13..097c8b9 100644
> --- a/arch/arm/mach-omap2/board-ldp.c
> +++ b/arch/arm/mach-omap2/board-ldp.c
> @@ -292,7 +292,6 @@ static void __init omap_ldp_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(ldp_config);
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  	ldp_init_smsc911x();
>  }
>  
> diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
> index a3e2b49..afa0ce5 100644
> --- a/arch/arm/mach-omap2/board-n8x0.c
> +++ b/arch/arm/mach-omap2/board-n8x0.c
> @@ -648,7 +648,6 @@ static void __init n8x0_init_irq(void)
>  {
>  	omap2_init_common_hw(NULL, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  #ifdef CONFIG_OMAP_MUX
> diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
> index 87969c7..fda730b 100644
> --- a/arch/arm/mach-omap2/board-omap3beagle.c
> +++ b/arch/arm/mach-omap2/board-omap3beagle.c
> @@ -393,7 +393,6 @@ static void __init omap3_beagle_init_irq(void)
>  #ifdef CONFIG_OMAP_32K_TIMER
>  	omap2_gp_clockevent_set_gptimer(12);
>  #endif
> -	omap_gpio_init();
>  }
>  
>  static struct platform_device *omap3_beagle_devices[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index 6494dbd..cbb7614 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -627,7 +627,6 @@ static void __init omap3_evm_init_irq(void)
>  	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
>  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct platform_device *omap3_evm_devices[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
> index 55836fa..ad9cd5f 100644
> --- a/arch/arm/mach-omap2/board-omap3pandora.c
> +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> @@ -588,7 +588,6 @@ static void __init omap3pandora_init_irq(void)
>  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
>  			     mt46h32m32lf6_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static void pandora_wl1251_set_power(bool enable)
> diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
> index bcd01d2..1fbce09 100644
> --- a/arch/arm/mach-omap2/board-omap3stalker.c
> +++ b/arch/arm/mach-omap2/board-omap3stalker.c
> @@ -588,7 +588,6 @@ static void __init omap3_stalker_init_irq(void)
>  #ifdef CONFIG_OMAP_32K_TIMER
>  	omap2_gp_clockevent_set_gptimer(12);
>  #endif
> -	omap_gpio_init();
>  }
>  
>  static struct platform_device *omap3_stalker_devices[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
> index 663c62d..6118042 100644
> --- a/arch/arm/mach-omap2/board-omap3touchbook.c
> +++ b/arch/arm/mach-omap2/board-omap3touchbook.c
> @@ -427,7 +427,6 @@ static void __init omap3_touchbook_init_irq(void)
>  #ifdef CONFIG_OMAP_32K_TIMER
>  	omap2_gp_clockevent_set_gptimer(12);
>  #endif
> -	omap_gpio_init();
>  }
>  
>  static struct platform_device *omap3_touchbook_devices[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
> index c03d1d5..09b0da1 100644
> --- a/arch/arm/mach-omap2/board-omap4panda.c
> +++ b/arch/arm/mach-omap2/board-omap4panda.c
> @@ -44,7 +44,6 @@ static void __init omap4_panda_init_irq(void)
>  {
>  	omap2_init_common_hw(NULL, NULL);
>  	gic_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct omap_musb_board_data musb_board_data = {
> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 4c48436..099f4f7 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -415,7 +415,6 @@ static void __init overo_init_irq(void)
>  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
>  			     mt46h32m32lf6_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  static struct platform_device *overo_devices[] __initdata = {
> diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
> index a58e8cb..04b0259 100644
> --- a/arch/arm/mach-omap2/board-rx51.c
> +++ b/arch/arm/mach-omap2/board-rx51.c
> @@ -108,7 +108,6 @@ static void __init rx51_init_irq(void)
>  	sdrc_params = rx51_get_sdram_timings();
>  	omap2_init_common_hw(sdrc_params, sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  extern void __init rx51_peripherals_init(void);
> diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
> index 3ad9ecf..634b05b 100644
> --- a/arch/arm/mach-omap2/board-zoom2.c
> +++ b/arch/arm/mach-omap2/board-zoom2.c
> @@ -31,7 +31,6 @@ static void __init omap_zoom2_init_irq(void)
>  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
>  				 mt46h32m32lf6_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  /* REVISIT: These audio entries can be removed once MFD code is merged */
> diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
> index 6ca0b83..a048981 100644
> --- a/arch/arm/mach-omap2/board-zoom3.c
> +++ b/arch/arm/mach-omap2/board-zoom3.c
> @@ -76,7 +76,6 @@ static void __init omap_zoom_init_irq(void)
>  	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
>  			h8mbx00u0mer0em_sdrc_params);
>  	omap_init_irq();
> -	omap_gpio_init();
>  }
>  
>  #ifdef CONFIG_OMAP_MUX

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

* Re: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
  2010-08-06 12:34                     ` [PATCH 11/13 v5] OMAP: GPIO: Make gpio_context as part of gpio_bank structure Charulatha V
@ 2010-08-09 23:06                     ` Kevin Hilman
  2010-08-10 11:53                       ` Basak, Partha
  1 sibling, 1 reply; 38+ messages in thread
From: Kevin Hilman @ 2010-08-09 23:06 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> @@ -650,21 +511,28 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
>  	__raw_writel(debounce, reg);
>  
>  	reg = bank->base;
> -	if (cpu_is_omap44xx())
> +	if (bank->method == METHOD_GPIO_44XX)
>  		reg += OMAP4_GPIO_DEBOUNCENABLE;
>  	else
>  		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
>  
>  	val = __raw_readl(reg);
>  
> +	if (!bank->dbck) {
> +		struct platform_device *pdev = to_platform_device(bank->dev);
> +		struct omap_device *odev = to_omap_device(pdev);

insert empty line

> +		if (odev->hwmods[0]->opt_clks->_clk)
> +			bank->dbck = odev->hwmods[0]->opt_clks->_clk;

As was discussed in Bangalore, drivers should have no knowledge of hwmod
internals.

Instead, please propose an API to hwmod for getting the optional
clock(s), or possibly cleaner, an API to directly enable/disable
optional clocks for an omap_device.

Kevin

> +		if (IS_ERR(bank->dbck))
> +			dev_err(bank->dev, "Could not get gpio dbck\n");
> +	}
> +

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

* Re: [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init
  2010-08-06 12:34                 ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Charulatha V
  2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
@ 2010-08-09 23:58                   ` Kevin Hilman
  2010-08-10  5:56                     ` Varadarajan, Charulatha
  2010-08-10  0:21                   ` Kevin Hilman
  2 siblings, 1 reply; 38+ messages in thread
From: Kevin Hilman @ 2010-08-09 23:58 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> This patch adds support for handling GPIO as a HWMOD FW adapted
> platform device for OMAP2PLUS chips.
>
> gpio_init needs to be done before machine_init functions access
> gpio APIs.Hence gpio_init is made as a postcore_initcall.
>
> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>
> ---

[...]

> +static int omap2_init_gpio(struct omap_hwmod *oh, void *user)
> +{
> +	struct omap_device *od;
> +	struct omap_gpio_platform_data *pdata;
> +	char *name = "omap-gpio";
> +	static int id;
> +	struct omap_gpio_dev_attr *gpio_dev_data;
> +
> +	if (!oh) {
> +		pr_err("Could not look up omap gpio %d\n", id + 1);
> +		return -EINVAL;
> +	}
> +
> +	pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> +					GFP_KERNEL);
> +	if (!pdata) {
> +		pr_err("Memory allocation failed gpio%d\n", id + 1);
> +		return -ENOMEM;
> +	}
> +
> +	gpio_dev_data = (struct omap_gpio_dev_attr *)oh->dev_attr;
> +
> +	pdata->gpio_attr = gpio_dev_data;
> +	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * id;
> +	switch (oh->class->rev) {
> +	case 0:
> +	case 1:
> +		pdata->bank_type = METHOD_GPIO_24XX;
> +		break;
> +	case 2:
> +		pdata->bank_type = METHOD_GPIO_44XX;
> +		break;
> +	default:
> +		WARN(1, "Invalid gpio bank_type\n");
> +		break;
> +	}
> +	gpio_bank_count++;
> +
> +	od = omap_device_build(name, id, oh, pdata,
> +				sizeof(*pdata),	omap_gpio_latency,
> +				ARRAY_SIZE(omap_gpio_latency),
> +				false);
> +	WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> +				name, oh->name);
> +

pdata should be free'd here as omap_device_build makes a copy for
itself.

Kevin

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

* Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-06 12:34                       ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Charulatha V
  2010-08-06 12:34                         ` [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init() Charulatha V
  2010-08-09 21:45                         ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Kevin Hilman
@ 2010-08-10  0:21                         ` Kevin Hilman
  2010-08-10 12:37                           ` Basak, Partha
  2010-08-12 12:43                           ` Basak, Partha
  2 siblings, 2 replies; 38+ messages in thread
From: Kevin Hilman @ 2010-08-10  0:21 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> This patch makes GPIO driver to use dev_pm_ops instead of
> sysdev_class. With this approach, gpio_bank_suspend & gpio_bank_resume
> are not part of sys_dev_class.
>
> According to this patch, a GPIO bank relinquishes the clock using
> PM runtime APIs when all the gpios in that bank are freed. 

This does not match the code.

The only clock associated with a GPIO hwmod is the optional clock for
the debounce clock.  This clock is managed by the driver itself, not
by using the PM runtime API.

> It also
> relinquishes the clocks in the idle-path too, as it is possible to
> have a GPIO bank requested and still allow PER domain to go to OFF state.

This doesn't make sense to me.  What clocks are you referring to?

> In the idle path (interrupt disabled context), PM runtime APIs cannot
> be used as they are not mutex-free functions. Hence omap_device APIs
> are used in the idle and resume after idle path.

This needs much more fleshing out. 

Exactly what mutexes are causing the problems here.  As pointed out in
previous discussions, the ones in the PM runtime core should not be a
problem in this path.  Therefore, I'll assume the problems are coming
from the mutexes when the device code (mach-omap2/gpio.c) calls into the
hwmod layer.  More on this in comments on the next patch.

> To summarize,
> 1. pm_runtime_get_sync() for any gpio bank is called when one of the gpios
>    is requested on the bank, in which, no other gpio is being used (when
>    mod_usage becomes non-zero)
> 2. omap_device_enable() is called during gpio resume after idle, only
>    if the particular bank is being used (if mod_usage is non-zero)

context is saved/restored in the idle path, but...

> 3. pm_runtime_put_sync() is called when the last used gpio in that
>    gpio bank is freed (when mod_usage becomes zero)

in this path, the bank is now runtime suspended, but context has not
been saved for it.  That should be fine, since this bank is no longer
used, but now let's assume there was an off-mode transition and context
is lost.  Then, gpio_request() is called which will trigger
a pm_runtime_get_sync() and gpio_bank_runtime_resume() will be called.

In this case, it's not terribly clear that runtime_resume is doing sane
things if context has just been lost.  Seems like runtime_resume should
be a nop in this case since any re-init will be be done in gpio_request().

> 4. omap_device_idle() is called during idle, if the particular bank
>    is being used (if mod_usage is non-zero)

This mixture of pm_runtime_* and omap_device_* APIs is confusing at
best.

There should be a single path into the drivers runtime_suspend hooks.
Namely, when pm_runtime_put_* is called and the usecount goes to zero.
If you can't use the runtime PM APIs, then we need to understand
*exactly* why and work on a solution for that particular problem.

On my omap34xx/omap3evm, I had to disable the omap_device_* calls in the
idle path since as they were causing strange crashes, and as stated
above, I'm not sure what the purpose is.

> With this patch, GPIO's prepare_for_idle and resume_after_idle APIs
> makes use of the parameter save_context and restore_context respectively
> inorder to identify if save context/restore context needs to be done.

Why?

> Links to related discussion:
> http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32833.html
>
> For suspend/resume path to work, this patch has dependency of
> 1. reverting the following patch:
> OMAP: bus-level PM: enable use of runtime PM API for suspend/resume
> http://dev.omapzoom.org/?p=swarch/linux-omap-adv.git;a=commitdiff;
> h=8041359e18e49bf8a3d41f15894db9e476f3a8fc
> (or)
> 2. Remove the locking in the omap_hwmod_for_each* function

Did you mean 'and' instead of 'or'?  If you meant 'or', then clearly
(20 is preferred over (1), and I have a patch to fix that in the current
pm-wip/runtime branch.

If you meant 'and', then you need to describe the root cause for (1).

> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>
> ---
>  arch/arm/mach-omap2/pm24xx.c           |    4 +-
>  arch/arm/mach-omap2/pm34xx.c           |   23 +-
>  arch/arm/plat-omap/gpio.c              |  561 ++++++++++++++++----------------
>  arch/arm/plat-omap/include/plat/gpio.h |    6 +-
>  4 files changed, 297 insertions(+), 297 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
> index 6aeedea..c01e156 100644
> --- a/arch/arm/mach-omap2/pm24xx.c
> +++ b/arch/arm/mach-omap2/pm24xx.c
> @@ -106,7 +106,7 @@ static void omap2_enter_full_retention(void)
>  	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
>  	omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
>  
> -	omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);
> +	omap2_gpio_prepare_for_idle(false);
>  
>  	if (omap2_pm_debug) {
>  		omap2_pm_dump(0, 0, 0);
> @@ -140,7 +140,7 @@ no_sleep:
>  		tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
>  		omap2_pm_dump(0, 1, tmp);
>  	}
> -	omap2_gpio_resume_after_idle();
> +	omap2_gpio_resume_after_idle(false);
>  
>  	clk_enable(osc_ck);
>  
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index fb4994a..66c7e11 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -79,16 +79,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
>  static struct powerdomain *core_pwrdm, *per_pwrdm;
>  static struct powerdomain *cam_pwrdm;
>  
> -static inline void omap3_per_save_context(void)
> -{
> -	omap_gpio_save_context();
> -}
> -
> -static inline void omap3_per_restore_context(void)
> -{
> -	omap_gpio_restore_context();
> -}
> -
>  static void omap3_enable_io_chain(void)
>  {
>  	int timeout = 0;
> @@ -395,15 +385,17 @@ void omap_sram_idle(void)
>  	/* PER */
>  	if (per_next_state < PWRDM_POWER_ON) {
>  		omap_uart_prepare_idle(2);
> -		omap2_gpio_prepare_for_idle(per_next_state);
>  		if (per_next_state == PWRDM_POWER_OFF) {
>  			if (core_next_state == PWRDM_POWER_ON) {
>  				per_next_state = PWRDM_POWER_RET;
>  				pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
>  				per_state_modified = 1;
> -			} else
> -				omap3_per_save_context();
> +			}
>  		}
> +		if (per_next_state == PWRDM_POWER_OFF)
> +			omap2_gpio_prepare_for_idle(true);
> +		else
> +			omap2_gpio_prepare_for_idle(false);

Why is this better than passing the next power state?

>  	}
>  
>  	if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
> @@ -471,9 +463,10 @@ void omap_sram_idle(void)
>  	/* PER */
>  	if (per_next_state < PWRDM_POWER_ON) {
>  		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
> -		omap2_gpio_resume_after_idle();
>  		if (per_prev_state == PWRDM_POWER_OFF)
> -			omap3_per_restore_context();
> +			omap2_gpio_resume_after_idle(true);
> +		else
> +			omap2_gpio_resume_after_idle(false);
>  		omap_uart_resume_idle(2);
>  		if (per_state_modified)
>  			pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
> diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
> index 6a5cf43..6686f9f 100644
> --- a/arch/arm/plat-omap/gpio.c
> +++ b/arch/arm/plat-omap/gpio.c
> @@ -25,12 +25,12 @@
>  #include <linux/pm_runtime.h>
>  
>  #include <plat/omap_device.h>
> +#include <plat/powerdomain.h>
>  #include <mach/hardware.h>
>  #include <asm/irq.h>
>  #include <mach/irqs.h>
>  #include <mach/gpio.h>
>  #include <asm/mach/irq.h>
> -#include <plat/powerdomain.h>
>  
>  /*
>   * OMAP1510 GPIO registers
> @@ -179,7 +179,6 @@ struct gpio_bank {
>   * related to all instances of the device
>   */
>  static struct gpio_bank *gpio_bank;
> -
>  static int bank_width;
>  
>  /* TODO: Analyze removing gpio_bank_count usage from driver code */
> @@ -1045,6 +1044,9 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
>  	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
>  	unsigned long flags;
>  
> +	if (!bank->mod_usage)
> +		pm_runtime_get_sync(bank->dev);
> +

Would be fine to skip the 'if' here and let runtime PM continue the
usecounting.  Since we'll have trace tools that instrument runtime PM,
it will be nice to be able to trace all the users instead of just the
first one to request a GPIO in a given bank.

>  	spin_lock_irqsave(&bank->lock, flags);
>  
>  	/* Set trigger to none. You need to enable the desired trigger with
> @@ -1061,22 +1063,19 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
>  		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
>  	}
>  #endif
> -	if (!cpu_class_is_omap1()) {
> -		if (!bank->mod_usage) {
> -			void __iomem *reg = bank->base;
> -			u32 ctrl;
> -
> -			if (cpu_is_omap24xx() || cpu_is_omap34xx())
> -				reg += OMAP24XX_GPIO_CTRL;
> -			else if (cpu_is_omap44xx())
> -				reg += OMAP4_GPIO_CTRL;
> -			ctrl = __raw_readl(reg);
> -			/* Module is enabled, clocks are not gated */
> -			ctrl &= 0xFFFFFFFE;
> -			__raw_writel(ctrl, reg);
> -		}
> -		bank->mod_usage |= 1 << offset;
> +	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
> +		void __iomem *reg = bank->base;
> +		u32 ctrl;
> +		if (bank->method == METHOD_GPIO_24XX)
> +			reg += OMAP24XX_GPIO_CTRL;
> +		else if (bank->method == METHOD_GPIO_44XX)
> +			reg += OMAP4_GPIO_CTRL;
> +		ctrl = __raw_readl(reg);
> +		/* Module is enabled, clocks are not gated */
> +		ctrl &= 0xFFFFFFFE;
> +		__raw_writel(ctrl, reg);

If you get rid of the 'if (!mod_usage)' check above for the
pm_runtime_get, you could just get rid of the mod_usage flag all
together and do this section in the runtime_resume hook.

>  	}
> +	bank->mod_usage |= 1 << offset;
>  	spin_unlock_irqrestore(&bank->lock, flags);
>  
>  	return 0;
> @@ -1109,24 +1108,26 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
>  		__raw_writel(1 << offset, reg);
>  	}
>  #endif
> -	if (!cpu_class_is_omap1()) {
> -		bank->mod_usage &= ~(1 << offset);
> -		if (!bank->mod_usage) {
> -			void __iomem *reg = bank->base;
> -			u32 ctrl;
> -
> -			if (cpu_is_omap24xx() || cpu_is_omap34xx())
> -				reg += OMAP24XX_GPIO_CTRL;
> -			else if (cpu_is_omap44xx())
> -				reg += OMAP4_GPIO_CTRL;
> -			ctrl = __raw_readl(reg);
> -			/* Module is disabled, clocks are gated */
> -			ctrl |= 1;
> -			__raw_writel(ctrl, reg);
> -		}
> +	bank->mod_usage &= ~(1 << offset);
> +	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
> +		void __iomem *reg = bank->base;
> +		u32 ctrl;
> +
> +		if (bank->method == METHOD_GPIO_24XX)
> +			reg += OMAP24XX_GPIO_CTRL;
> +		else if (bank->method == METHOD_GPIO_44XX)
> +			reg += OMAP4_GPIO_CTRL;
> +		ctrl = __raw_readl(reg);
> +		/* Module is disabled, clocks are gated */
> +		ctrl |= 1;
> +		__raw_writel(ctrl, reg);

ditto, but in the runtime_suspend hook

>  	}
> +
>  	_reset_gpio(bank, bank->chip.base + offset);
>  	spin_unlock_irqrestore(&bank->lock, flags);
> +
> +	if (!bank->mod_usage)
> +		pm_runtime_put_sync(bank->dev);

see above

>  }
>  
>  /*
> @@ -1728,7 +1729,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
>  	}
>  
>  	pm_runtime_enable(bank->dev);
> -	pm_runtime_get_sync(bank->dev);

as mentioned before, this should stay, otherwise mod_init will fault if
GPIO hwmod is disabled.

>  	omap_gpio_mod_init(bank, id);
>  	omap_gpio_chip_init(bank);
> @@ -1741,294 +1741,222 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)

and you'd need a matching 'put' here.

[...]

Kevin

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

* Re: [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init
  2010-08-06 12:34                 ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Charulatha V
  2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
  2010-08-09 23:58                   ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Kevin Hilman
@ 2010-08-10  0:21                   ` Kevin Hilman
  2 siblings, 0 replies; 38+ messages in thread
From: Kevin Hilman @ 2010-08-10  0:21 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, paul, b-cousson, rnayak, Basak, Partha

Charulatha V <charu@ti.com> writes:

> This patch adds support for handling GPIO as a HWMOD FW adapted
> platform device for OMAP2PLUS chips.
>
> gpio_init needs to be done before machine_init functions access
> gpio APIs.Hence gpio_init is made as a postcore_initcall.
>
> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Basak, Partha <p-basak2@ti.com>
> ---
>  arch/arm/mach-omap2/gpio.c |  120 ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 120 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/gpio.c
>
> diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
> new file mode 100644
> index 0000000..30aeef9
> --- /dev/null
> +++ b/arch/arm/mach-omap2/gpio.c
> @@ -0,0 +1,120 @@
> +/*
> + * gpio.c - OMAP2PLUS-specific gpio code
> + *
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + *
> + * Author:
> + *	Charulatha V <charu@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/gpio.h>
> +#include <linux/err.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +
> +#include <plat/omap_hwmod.h>
> +#include <plat/omap_device.h>
> +
> +/*
> + * For GPIO, it is a must to relinquish clocks in the Idle-path
> + * as it is possible to have a GPIO bank requested and still
> + * allow PER domain to go to OFF. 

What clocks are you referring to?   

There is no main_clk associated with this hwmod, so hwmod is not
managing any clocks for you and the driver is handling the debounce
clock (opt_clk.)

> In the idle path (interrupt
> + * disabled context), omap_device APIs cannot be used as they
> + * are not mutex-free functions. Hence the below wrappers are
> + * required to handle interrupts disabled context and interrupts
> + * enabled context.
> + */
> +static int gpio_enable_hwmod(struct omap_device *od)
> +{
> +	struct omap_hwmod *oh = *od->hwmods;
> +
> +	if (irqs_disabled())
> +		_omap_hwmod_enable(oh);
> +	else
> +		omap_device_enable_hwmods(od);
> +	return 0;
> +}
> +
> +static int gpio_idle_hwmod(struct omap_device *od)
> +{
> +	struct omap_hwmod *oh = *od->hwmods;
> +
> +	if (irqs_disabled())
> +		_omap_hwmod_idle(oh);
> +	else
> +		omap_device_idle_hwmods(od);
> +	return 0;
> +}

The use of hwmod to disable GPIO hwmods in the idle path needs some more
explanation since it differs from what is done in the current GPIO code.

As mentioned above, the (optional) clocks are being managed by the
driver already, so what exactly are you wanting hwmod to do for you?
The only thing that will happen is the toggling of no-idle/smart-idle,
and it's not clear to me that is what you want.

Whatever the new behavior you're trying to get, it should be described
well in the changelog since it's different from current behavior of the
GPIO code.  In fact, a change like this which is signifcantly different
from current behavior should be done in a separate patch.

> +
> +static struct omap_device_pm_latency omap_gpio_latency[] = {
> +	[0] = {
> +		.deactivate_func = gpio_idle_hwmod,
> +		.activate_func   = gpio_enable_hwmod,
> +		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
> +	},
> +};

So, to keep the same behavior as the current code, you could just drop
the omap_gpio_latency part here, and you don't have to worry about
calling into omap_hwmod_* with interrupts disabled.

Kevin


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

* RE: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-09 22:20   ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Kevin Hilman
@ 2010-08-10  5:18     ` Varadarajan, Charulatha
  2010-08-10  7:20       ` Basak, Partha
  0 siblings, 1 reply; 38+ messages in thread
From: Varadarajan, Charulatha @ 2010-08-10  5:18 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra, Basak, Partha



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 3:51 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: Re: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for
> platform device implementation
> 
> Charulatha V <charu@ti.com> writes:
> 
> > This is in prepartion for implementing GPIO as a platform device.
> > gpio bank's base addresses are moved from gpio.c to plat/gpio.h.
> >
> > This patch also modifies omap_gpio_init() to make use of
> > omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init()
> does
> > the module init by clearing the status register and initializing the
> > GPIO control register. omap_gpio_chip_init() initializes the chip
> request,
> > free, get, set and other function pointers and sets the gpio irq handler.
> >
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Basak, Partha <p-basak2@ti.com>
> 
> [...]
> 
> > +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);
> > +			/* Enable autoidle for the OCP interface */
> > +			omap_writel(1 << 0, 0x48306814);
> 
> This autoidle stuff should be removed in this series as setting this is
> handled by the hwmod layer.

Okay. 

> 
> > +		} 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];
> > +
> > +			/* Enable autoidle for the OCP interface */
> > +			omap_writel(1 << 0, 0x48019010);
> 
> ditto

Okay.

> 
> > +		}
> 
> Kevin

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

* RE: [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init()
  2010-08-09 23:00                           ` Kevin Hilman
@ 2010-08-10  5:22                             ` Varadarajan, Charulatha
  0 siblings, 0 replies; 38+ messages in thread
From: Varadarajan, Charulatha @ 2010-08-10  5:22 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra, Basak, Partha



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 4:30 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: Re: [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init()
>
> Charulatha V <charu@ti.com> writes:
>
> > This patch removes the usage of omap_gpio_init() from all
> > omap board files since omap_gpio_init() does nothing, after gpio
> > is implemented as a platform device.
>
> This patch should also remove the function from plat/gpio.c

Yes. My mistake, I missed it in this patch series.

>
> Kevin
>
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Basak, Partha <p-basak2@ti.com>
> > ---
> >  arch/arm/mach-omap1/board-ams-delta.c      |    1 -
> >  arch/arm/mach-omap1/board-fsample.c        |    1 -
> >  arch/arm/mach-omap1/board-h2.c             |    1 -
> >  arch/arm/mach-omap1/board-h3.c             |    1 -
> >  arch/arm/mach-omap1/board-htcherald.c      |    1 -
> >  arch/arm/mach-omap1/board-innovator.c      |    1 -
> >  arch/arm/mach-omap1/board-nokia770.c       |    1 -
> >  arch/arm/mach-omap1/board-osk.c            |    1 -
> >  arch/arm/mach-omap1/board-palmte.c         |    1 -
> >  arch/arm/mach-omap1/board-palmz71.c        |    1 -
> >  arch/arm/mach-omap1/board-perseus2.c       |    1 -
> >  arch/arm/mach-omap1/board-sx1.c            |    1 -
> >  arch/arm/mach-omap1/board-voiceblue.c      |    1 -
> >  arch/arm/mach-omap2/board-2430sdp.c        |    1 -
> >  arch/arm/mach-omap2/board-3430sdp.c        |    1 -
> >  arch/arm/mach-omap2/board-3630sdp.c        |    1 -
> >  arch/arm/mach-omap2/board-4430sdp.c        |    1 -
> >  arch/arm/mach-omap2/board-am3517evm.c      |    1 -
> >  arch/arm/mach-omap2/board-apollon.c        |    1 -
> >  arch/arm/mach-omap2/board-cm-t35.c         |    1 -
> >  arch/arm/mach-omap2/board-devkit8000.c     |    1 -
> >  arch/arm/mach-omap2/board-h4.c             |    1 -
> >  arch/arm/mach-omap2/board-igep0020.c       |    1 -
> >  arch/arm/mach-omap2/board-ldp.c            |    1 -
> >  arch/arm/mach-omap2/board-n8x0.c           |    1 -
> >  arch/arm/mach-omap2/board-omap3beagle.c    |    1 -
> >  arch/arm/mach-omap2/board-omap3evm.c       |    1 -
> >  arch/arm/mach-omap2/board-omap3pandora.c   |    1 -
> >  arch/arm/mach-omap2/board-omap3stalker.c   |    1 -
> >  arch/arm/mach-omap2/board-omap3touchbook.c |    1 -
> >  arch/arm/mach-omap2/board-omap4panda.c     |    1 -
> >  arch/arm/mach-omap2/board-overo.c          |    1 -
> >  arch/arm/mach-omap2/board-rx51.c           |    1 -
> >  arch/arm/mach-omap2/board-zoom2.c          |    1 -
> >  arch/arm/mach-omap2/board-zoom3.c          |    1 -
> >  35 files changed, 0 insertions(+), 35 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-
> omap1/board-ams-delta.c
> > index 41992ab..774867f 100644
> > --- a/arch/arm/mach-omap1/board-ams-delta.c
> > +++ b/arch/arm/mach-omap1/board-ams-delta.c
> > @@ -136,7 +136,6 @@ static void __init ams_delta_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct map_desc ams_delta_io_desc[] __initdata = {
> > diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-
> omap1/board-fsample.c
> > index 180ce79..09b6165 100644
> > --- a/arch/arm/mach-omap1/board-fsample.c
> > +++ b/arch/arm/mach-omap1/board-fsample.c
> > @@ -325,7 +325,6 @@ static void __init omap_fsample_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     fsample_init_smc91x();
> >  }
> >
> > diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-
> h2.c
> > index d2cda58..cf9aaff 100644
> > --- a/arch/arm/mach-omap1/board-h2.c
> > +++ b/arch/arm/mach-omap1/board-h2.c
> > @@ -374,7 +374,6 @@ static void __init h2_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     h2_init_smc91x();
> >  }
> >
> > diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-
> h3.c
> > index c2ef4ff..423b45e 100644
> > --- a/arch/arm/mach-omap1/board-h3.c
> > +++ b/arch/arm/mach-omap1/board-h3.c
> > @@ -435,7 +435,6 @@ static void __init h3_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     h3_init_smc91x();
> >  }
> >
> > diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-
> omap1/board-htcherald.c
> > index 311899f..bc8f56f 100644
> > --- a/arch/arm/mach-omap1/board-htcherald.c
> > +++ b/arch/arm/mach-omap1/board-htcherald.c
> > @@ -278,7 +278,6 @@ static void __init htcherald_init(void)
> >  {
> >     printk(KERN_INFO "HTC Herald init.\n");
> >
> > -   omap_gpio_init();
> >
> >     omap_board_config = htcherald_config;
> >     omap_board_config_size = ARRAY_SIZE(htcherald_config);
> > diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-
> omap1/board-innovator.c
> > index 3daf87a..27c283d 100644
> > --- a/arch/arm/mach-omap1/board-innovator.c
> > +++ b/arch/arm/mach-omap1/board-innovator.c
> > @@ -290,7 +290,6 @@ static void __init innovator_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  #ifdef CONFIG_ARCH_OMAP15XX
> >     if (cpu_is_omap1510()) {
> >             omap1510_fpga_init_irq();
> > diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-
> omap1/board-nokia770.c
> > index 51a4539..397febe 100644
> > --- a/arch/arm/mach-omap1/board-nokia770.c
> > +++ b/arch/arm/mach-omap1/board-nokia770.c
> > @@ -246,7 +246,6 @@ static void __init omap_nokia770_init(void)
> >     platform_add_devices(nokia770_devices,
> ARRAY_SIZE(nokia770_devices));
> >     spi_register_board_info(nokia770_spi_board_info,
> >                             ARRAY_SIZE(nokia770_spi_board_info));
> > -   omap_gpio_init();
> >     omap_serial_init();
> >     omap_register_i2c_bus(1, 100, NULL, 0);
> >     hwa742_dev_init();
> > diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-
> omap1/board-osk.c
> > index 679740c..fcd67d0 100644
> > --- a/arch/arm/mach-omap1/board-osk.c
> > +++ b/arch/arm/mach-omap1/board-osk.c
> > @@ -283,7 +283,6 @@ static void __init osk_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     osk_init_smc91x();
> >     osk_init_cf();
> >  }
> > diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-
> omap1/board-palmte.c
> > index 782bb25..69708ac 100644
> > --- a/arch/arm/mach-omap1/board-palmte.c
> > +++ b/arch/arm/mach-omap1/board-palmte.c
> > @@ -63,7 +63,6 @@ static void __init omap_palmte_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static const int palmte_keymap[] = {
> > diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-
> omap1/board-palmz71.c
> > index 6636290..644d217 100644
> > --- a/arch/arm/mach-omap1/board-palmz71.c
> > +++ b/arch/arm/mach-omap1/board-palmz71.c
> > @@ -62,7 +62,6 @@ omap_palmz71_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static int palmz71_keymap[] = {
> > diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-
> omap1/board-perseus2.c
> > index 34ab354..d8dbb4a 100644
> > --- a/arch/arm/mach-omap1/board-perseus2.c
> > +++ b/arch/arm/mach-omap1/board-perseus2.c
> > @@ -293,7 +293,6 @@ static void __init omap_perseus2_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     perseus2_init_smc91x();
> >  }
> >  /* Only FPGA needs to be mapped here. All others are done with ioremap
> */
> > diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-
> omap1/board-sx1.c
> > index 2eb148b..18093a5 100644
> > --- a/arch/arm/mach-omap1/board-sx1.c
> > +++ b/arch/arm/mach-omap1/board-sx1.c
> > @@ -409,7 +409,6 @@ static void __init omap_sx1_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >  /*----------------------------------------*/
> >
> > diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-
> omap1/board-voiceblue.c
> > index 6b3cf14..794c497 100644
> > --- a/arch/arm/mach-omap1/board-voiceblue.c
> > +++ b/arch/arm/mach-omap1/board-voiceblue.c
> > @@ -158,7 +158,6 @@ static void __init voiceblue_init_irq(void)
> >  {
> >     omap1_init_common_hw();
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static void __init voiceblue_init(void)
> > diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-
> omap2/board-2430sdp.c
> > index 8538e41..b86824e 100644
> > --- a/arch/arm/mach-omap2/board-2430sdp.c
> > +++ b/arch/arm/mach-omap2/board-2430sdp.c
> > @@ -144,7 +144,6 @@ static void __init omap_2430sdp_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(sdp2430_config);
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
> > diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-
> omap2/board-3430sdp.c
> > index 67b95b5..9f38f5f 100644
> > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > @@ -328,7 +328,6 @@ static void __init omap_3430sdp_init_irq(void)
> >     omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
> >     omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static int sdp3430_batt_table[] = {
> > diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-
> omap2/board-3630sdp.c
> > index b359c3f..78973f5 100644
> > --- a/arch/arm/mach-omap2/board-3630sdp.c
> > +++ b/arch/arm/mach-omap2/board-3630sdp.c
> > @@ -76,7 +76,6 @@ static void __init omap_sdp_init_irq(void)
> >     omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
> >                     h8mbx00u0mer0em_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  #ifdef CONFIG_OMAP_MUX
> > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-
> omap2/board-4430sdp.c
> > index 9447644..b7f6369 100644
> > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > @@ -181,7 +181,6 @@ static void __init omap_4430sdp_init_irq(void)
> >     omap2_gp_clockevent_set_gptimer(1);
> >  #endif
> >     gic_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct omap_musb_board_data musb_board_data = {
> > diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-
> omap2/board-am3517evm.c
> > index 4d0f585..dd7aa66 100644
> > --- a/arch/arm/mach-omap2/board-am3517evm.c
> > +++ b/arch/arm/mach-omap2/board-am3517evm.c
> > @@ -372,7 +372,6 @@ static void __init am3517_evm_init_irq(void)
> >
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst
> = {
> > diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-
> omap2/board-apollon.c
> > index c6421a7..cd70971 100644
> > --- a/arch/arm/mach-omap2/board-apollon.c
> > +++ b/arch/arm/mach-omap2/board-apollon.c
> > @@ -280,7 +280,6 @@ static void __init omap_apollon_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(apollon_config);
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     apollon_init_smc91x();
> >  }
> >
> > diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-
> omap2/board-cm-t35.c
> > index e10bc10..000c7d4 100644
> > --- a/arch/arm/mach-omap2/board-cm-t35.c
> > +++ b/arch/arm/mach-omap2/board-cm-t35.c
> > @@ -687,7 +687,6 @@ static void __init cm_t35_init_irq(void)
> >     omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
> >                          mt46h32m32lf6_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct omap_board_mux board_mux[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-
> omap2/board-devkit8000.c
> > index a07086d..82b73e5 100644
> > --- a/arch/arm/mach-omap2/board-devkit8000.c
> > +++ b/arch/arm/mach-omap2/board-devkit8000.c
> > @@ -452,7 +452,6 @@ static void __init devkit8000_init_irq(void)
> >  #ifdef CONFIG_OMAP_32K_TIMER
> >     omap2_gp_clockevent_set_gptimer(12);
> >  #endif
> > -   omap_gpio_init();
> >  }
> >
> >  static void __init devkit8000_ads7846_init(void)
> > diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-
> h4.c
> > index e09bd68..4eb7c24 100644
> > --- a/arch/arm/mach-omap2/board-h4.c
> > +++ b/arch/arm/mach-omap2/board-h4.c
> > @@ -293,7 +293,6 @@ static void __init omap_h4_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(h4_config);
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     h4_init_flash();
> >  }
> >
> > diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-
> omap2/board-igep0020.c
> > index 175f043..63a68ef 100644
> > --- a/arch/arm/mach-omap2/board-igep0020.c
> > +++ b/arch/arm/mach-omap2/board-igep0020.c
> > @@ -406,7 +406,6 @@ static void __init igep2_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(igep2_config);
> >     omap2_init_common_hw(m65kxxxxam_sdrc_params,
> m65kxxxxam_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct twl4030_codec_audio_data igep2_audio_data = {
> > diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-
> omap2/board-ldp.c
> > index 00d9b13..097c8b9 100644
> > --- a/arch/arm/mach-omap2/board-ldp.c
> > +++ b/arch/arm/mach-omap2/board-ldp.c
> > @@ -292,7 +292,6 @@ static void __init omap_ldp_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(ldp_config);
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >     ldp_init_smsc911x();
> >  }
> >
> > diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-
> omap2/board-n8x0.c
> > index a3e2b49..afa0ce5 100644
> > --- a/arch/arm/mach-omap2/board-n8x0.c
> > +++ b/arch/arm/mach-omap2/board-n8x0.c
> > @@ -648,7 +648,6 @@ static void __init n8x0_init_irq(void)
> >  {
> >     omap2_init_common_hw(NULL, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  #ifdef CONFIG_OMAP_MUX
> > diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-
> omap2/board-omap3beagle.c
> > index 87969c7..fda730b 100644
> > --- a/arch/arm/mach-omap2/board-omap3beagle.c
> > +++ b/arch/arm/mach-omap2/board-omap3beagle.c
> > @@ -393,7 +393,6 @@ static void __init omap3_beagle_init_irq(void)
> >  #ifdef CONFIG_OMAP_32K_TIMER
> >     omap2_gp_clockevent_set_gptimer(12);
> >  #endif
> > -   omap_gpio_init();
> >  }
> >
> >  static struct platform_device *omap3_beagle_devices[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-
> omap2/board-omap3evm.c
> > index 6494dbd..cbb7614 100644
> > --- a/arch/arm/mach-omap2/board-omap3evm.c
> > +++ b/arch/arm/mach-omap2/board-omap3evm.c
> > @@ -627,7 +627,6 @@ static void __init omap3_evm_init_irq(void)
> >     omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
> >     omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct platform_device *omap3_evm_devices[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-
> omap2/board-omap3pandora.c
> > index 55836fa..ad9cd5f 100644
> > --- a/arch/arm/mach-omap2/board-omap3pandora.c
> > +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> > @@ -588,7 +588,6 @@ static void __init omap3pandora_init_irq(void)
> >     omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
> >                          mt46h32m32lf6_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static void pandora_wl1251_set_power(bool enable)
> > diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-
> omap2/board-omap3stalker.c
> > index bcd01d2..1fbce09 100644
> > --- a/arch/arm/mach-omap2/board-omap3stalker.c
> > +++ b/arch/arm/mach-omap2/board-omap3stalker.c
> > @@ -588,7 +588,6 @@ static void __init omap3_stalker_init_irq(void)
> >  #ifdef CONFIG_OMAP_32K_TIMER
> >     omap2_gp_clockevent_set_gptimer(12);
> >  #endif
> > -   omap_gpio_init();
> >  }
> >
> >  static struct platform_device *omap3_stalker_devices[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-
> omap2/board-omap3touchbook.c
> > index 663c62d..6118042 100644
> > --- a/arch/arm/mach-omap2/board-omap3touchbook.c
> > +++ b/arch/arm/mach-omap2/board-omap3touchbook.c
> > @@ -427,7 +427,6 @@ static void __init omap3_touchbook_init_irq(void)
> >  #ifdef CONFIG_OMAP_32K_TIMER
> >     omap2_gp_clockevent_set_gptimer(12);
> >  #endif
> > -   omap_gpio_init();
> >  }
> >
> >  static struct platform_device *omap3_touchbook_devices[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-
> omap2/board-omap4panda.c
> > index c03d1d5..09b0da1 100644
> > --- a/arch/arm/mach-omap2/board-omap4panda.c
> > +++ b/arch/arm/mach-omap2/board-omap4panda.c
> > @@ -44,7 +44,6 @@ static void __init omap4_panda_init_irq(void)
> >  {
> >     omap2_init_common_hw(NULL, NULL);
> >     gic_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct omap_musb_board_data musb_board_data = {
> > diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-
> omap2/board-overo.c
> > index 4c48436..099f4f7 100644
> > --- a/arch/arm/mach-omap2/board-overo.c
> > +++ b/arch/arm/mach-omap2/board-overo.c
> > @@ -415,7 +415,6 @@ static void __init overo_init_irq(void)
> >     omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
> >                          mt46h32m32lf6_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  static struct platform_device *overo_devices[] __initdata = {
> > diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-
> omap2/board-rx51.c
> > index a58e8cb..04b0259 100644
> > --- a/arch/arm/mach-omap2/board-rx51.c
> > +++ b/arch/arm/mach-omap2/board-rx51.c
> > @@ -108,7 +108,6 @@ static void __init rx51_init_irq(void)
> >     sdrc_params = rx51_get_sdram_timings();
> >     omap2_init_common_hw(sdrc_params, sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  extern void __init rx51_peripherals_init(void);
> > diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-
> omap2/board-zoom2.c
> > index 3ad9ecf..634b05b 100644
> > --- a/arch/arm/mach-omap2/board-zoom2.c
> > +++ b/arch/arm/mach-omap2/board-zoom2.c
> > @@ -31,7 +31,6 @@ static void __init omap_zoom2_init_irq(void)
> >     omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
> >                              mt46h32m32lf6_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  /* REVISIT: These audio entries can be removed once MFD code is merged
> */
> > diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-
> omap2/board-zoom3.c
> > index 6ca0b83..a048981 100644
> > --- a/arch/arm/mach-omap2/board-zoom3.c
> > +++ b/arch/arm/mach-omap2/board-zoom3.c
> > @@ -76,7 +76,6 @@ static void __init omap_zoom_init_irq(void)
> >     omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
> >                     h8mbx00u0mer0em_sdrc_params);
> >     omap_init_irq();
> > -   omap_gpio_init();
> >  }
> >
> >  #ifdef CONFIG_OMAP_MUX

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

* RE: [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init
  2010-08-09 23:58                   ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Kevin Hilman
@ 2010-08-10  5:56                     ` Varadarajan, Charulatha
  0 siblings, 0 replies; 38+ messages in thread
From: Varadarajan, Charulatha @ 2010-08-10  5:56 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra, Basak, Partha



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 5:29 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: Re: [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS
> chip GPIO init
> 
> Charulatha V <charu@ti.com> writes:
> 
> > This patch adds support for handling GPIO as a HWMOD FW adapted
> > platform device for OMAP2PLUS chips.
> >
> > gpio_init needs to be done before machine_init functions access
> > gpio APIs.Hence gpio_init is made as a postcore_initcall.
> >
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Basak, Partha <p-basak2@ti.com>
> > ---
> 
> [...]
> 
> > +static int omap2_init_gpio(struct omap_hwmod *oh, void *user)
> > +{
> > +	struct omap_device *od;
> > +	struct omap_gpio_platform_data *pdata;
> > +	char *name = "omap-gpio";
> > +	static int id;
> > +	struct omap_gpio_dev_attr *gpio_dev_data;
> > +
> > +	if (!oh) {
> > +		pr_err("Could not look up omap gpio %d\n", id + 1);
> > +		return -EINVAL;
> > +	}
> > +
> > +	pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> > +					GFP_KERNEL);
> > +	if (!pdata) {
> > +		pr_err("Memory allocation failed gpio%d\n", id + 1);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	gpio_dev_data = (struct omap_gpio_dev_attr *)oh->dev_attr;
> > +
> > +	pdata->gpio_attr = gpio_dev_data;
> > +	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * id;
> > +	switch (oh->class->rev) {
> > +	case 0:
> > +	case 1:
> > +		pdata->bank_type = METHOD_GPIO_24XX;
> > +		break;
> > +	case 2:
> > +		pdata->bank_type = METHOD_GPIO_44XX;
> > +		break;
> > +	default:
> > +		WARN(1, "Invalid gpio bank_type\n");
> > +		break;
> > +	}
> > +	gpio_bank_count++;
> > +
> > +	od = omap_device_build(name, id, oh, pdata,
> > +				sizeof(*pdata),	omap_gpio_latency,
> > +				ARRAY_SIZE(omap_gpio_latency),
> > +				false);
> > +	WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> > +				name, oh->name);
> > +
> 
> pdata should be free'd here as omap_device_build makes a copy for
> itself.
> 

Okay.

> Kevin

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

* RE: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-10  5:18     ` Varadarajan, Charulatha
@ 2010-08-10  7:20       ` Basak, Partha
  2010-08-10 10:44         ` Cousson, Benoit
  0 siblings, 1 reply; 38+ messages in thread
From: Basak, Partha @ 2010-08-10  7:20 UTC (permalink / raw)
  To: Varadarajan, Charulatha, Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra



> -----Original Message-----
> From: Varadarajan, Charulatha
> Sent: Tuesday, August 10, 2010 10:49 AM
> To: Kevin Hilman
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: RE: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for
> platform device implementation
> 
> 
> 
> > -----Original Message-----
> > From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> > Sent: Tuesday, August 10, 2010 3:51 AM
> > To: Varadarajan, Charulatha
> > Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> > Rajendra; Basak, Partha
> > Subject: Re: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation
> for
> > platform device implementation
> >
> > Charulatha V <charu@ti.com> writes:
> >
> > > This is in prepartion for implementing GPIO as a platform device.
> > > gpio bank's base addresses are moved from gpio.c to plat/gpio.h.
> > >
> > > This patch also modifies omap_gpio_init() to make use of
> > > omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init()
> > does
> > > the module init by clearing the status register and initializing the
> > > GPIO control register. omap_gpio_chip_init() initializes the chip
> > request,
> > > free, get, set and other function pointers and sets the gpio irq
> handler.
> > >
> > > Signed-off-by: Charulatha V <charu@ti.com>
> > > Signed-off-by: Basak, Partha <p-basak2@ti.com>
> >
> > [...]
> >
> > > +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);
> > > +			/* Enable autoidle for the OCP interface */
> > > +			omap_writel(1 << 0, 0x48306814);
> >
> > This autoidle stuff should be removed in this series as setting this is
> > handled by the hwmod layer.
> 
> Okay.

This code is incorrectly setting the PRCM_SYSCONFIG(0x48306814) register inside GPIO module which is incorrect. Ideally it should be moved to generic code like prcm_setup_regs() inside PM44xx.c/PM34xx.c. Having said that, the reset value of PRCM_SYSCONFIG is 0x01, so it would be safe just to remove this.

Now, coming to setting of AutoIdle (in CM_AUTOIDLE_XXX registers), even though prcm_reg_ids are being populated, hwmod framework is not setting these anywhere, all CM_AutoIdle settings are being done one-time in side prcm_setup_regs().

Kevin, as you pointed out this needs to be done in the framework. Can we do it as part of enabling the slave clocks? How does the following look?

static int _enable_clocks(struct omap_hwmod *oh)
{
	int i;

	pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);

	if (oh->_clk)
		clk_enable(oh->_clk);

	if (oh->slaves_cnt > 0) {
		for (i = 0; i < oh->slaves_cnt; i++) {
			struct omap_hwmod_ocp_if *os = oh->slaves[i];
			struct clk *c = os->_clk;

			if (c && (os->flags & OCPIF_SWSUP_IDLE))
				clk_enable(c);
			else
				/*TODO: Set CM_AutoIdle here*/
		}
	}

	/* The opt clocks are controlled by the device driver. */

	return 0;
}

> 
> >
> > > +		} 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];
> > > +
> > > +			/* Enable autoidle for the OCP interface */
> > > +			omap_writel(1 << 0, 0x48019010);
> >
> > ditto
> 
> Okay.
> 
> >
> > > +		}
> >
> > Kevin

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

* Re: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-10  7:20       ` Basak, Partha
@ 2010-08-10 10:44         ` Cousson, Benoit
  2010-08-10 11:31           ` Basak, Partha
  0 siblings, 1 reply; 38+ messages in thread
From: Cousson, Benoit @ 2010-08-10 10:44 UTC (permalink / raw)
  To: Basak, Partha
  Cc: Varadarajan, Charulatha, Kevin Hilman, linux-omap, paul, Nayak,
	Rajendra, khasim

On 8/10/2010 9:20 AM, Basak, Partha wrote:
>
>> From: Varadarajan, Charulatha
>> Sent: Tuesday, August 10, 2010 10:49 AM
>>
>>> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>> Sent: Tuesday, August 10, 2010 3:51 AM
>>>
>>> Charulatha V<charu@ti.com>  writes:
>>>
>>>> This is in prepartion for implementing GPIO as a platform device.
>>>> gpio bank's base addresses are moved from gpio.c to plat/gpio.h.
>>>>
>>>> This patch also modifies omap_gpio_init() to make use of
>>>> omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init()
>>> does
>>>> the module init by clearing the status register and initializing the
>>>> GPIO control register. omap_gpio_chip_init() initializes the chip
>>> request,
>>>> free, get, set and other function pointers and sets the gpio irq
>> handler.
>>>>
>>>> Signed-off-by: Charulatha V<charu@ti.com>
>>>> Signed-off-by: Basak, Partha<p-basak2@ti.com>
>>>
>>> [...]
>>>
>>>> +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);
>>>> +			/* Enable autoidle for the OCP interface */
>>>> +			omap_writel(1<<  0, 0x48306814);
>>>
>>> This autoidle stuff should be removed in this series as setting this is
>>> handled by the hwmod layer.
>>
>> Okay.
>
> This code is incorrectly setting the PRCM_SYSCONFIG(0x48306814) register inside GPIO module which is incorrect. Ideally it should be moved to generic code like prcm_setup_regs() inside PM44xx.c/PM34xx.c. Having said that, the reset value of PRCM_SYSCONFIG is 0x01, so it would be safe just to remove this.

That's weird, do you know where it come from? Maybe it is re-enable 
because someone disable it at some point?
It is indeed a dirty hack, but it will be good to understand the 
rational, if any?

The code is from that commit: 5492fb1a ARM: OMAP: Add 3430 gpio support 
from Khasim Syed Mohammed (Added in Cc).

It seems to be a bad copy paste of the 2420 code (omap_writel(1<<  0, 
0x48019010)). That one is indeed changing the GPIO SYSCONFIG.


> Now, coming to setting of AutoIdle (in CM_AUTOIDLE_XXX registers), even though prcm_reg_ids are being populated, hwmod framework is not setting these anywhere, all CM_AutoIdle settings are being done one-time in side prcm_setup_regs().

In this case, Kevin was referring to the SYSCONFIG autoidle setting not 
the PRCM one. But the following point is still valid.

> Kevin, as you pointed out this needs to be done in the framework.

Yep, good point, it was indeed already suggested by the comment:

	/*
	 * Enable interface clock autoidle for all modules.
	 * Note that in the long run this should be done by clockfw
	 */

Except that doing that in hwmod make more sense now. hwmod probably 
didn't exist at that time.

Everything is in place in the hwmod prcm struct to set this setting from 
the hwmod core code.

> Can we do it as part of enabling the slave clocks? How does the following look?
>
> static int _enable_clocks(struct omap_hwmod *oh)
> {
> 	int i;
>
> 	pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
>
> 	if (oh->_clk)
> 		clk_enable(oh->_clk);
>
> 	if (oh->slaves_cnt>  0) {
> 		for (i = 0; i<  oh->slaves_cnt; i++) {
> 			struct omap_hwmod_ocp_if *os = oh->slaves[i];
> 			struct clk *c = os->_clk;
>
> 			if (c&&  (os->flags&  OCPIF_SWSUP_IDLE))
> 				clk_enable(c);
> 			else
> 				/*TODO: Set CM_AutoIdle here*/
> 		}
> 	}
>
> 	/* The opt clocks are controlled by the device driver. */
>
> 	return 0;
> }

It should be done only once, so it is better to do that at _setup time 
instead.
Please note that this is an OMAP2&3 setting only. That bit does not 
exist anymore in OMAP4.

Regards,
Benoit

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

* RE: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation
  2010-08-10 10:44         ` Cousson, Benoit
@ 2010-08-10 11:31           ` Basak, Partha
  0 siblings, 0 replies; 38+ messages in thread
From: Basak, Partha @ 2010-08-10 11:31 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: Varadarajan, Charulatha, Kevin Hilman, linux-omap, paul, Nayak,
	Rajendra, Syed Mohammed, Khasim



> -----Original Message-----
> From: Cousson, Benoit
> Sent: Tuesday, August 10, 2010 4:15 PM
> To: Basak, Partha
> Cc: Varadarajan, Charulatha; Kevin Hilman; linux-omap@vger.kernel.org;
> paul@pwsan.com; Nayak, Rajendra; Syed Mohammed, Khasim
> Subject: Re: [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for
> platform device implementation
> 
> On 8/10/2010 9:20 AM, Basak, Partha wrote:
> >
> >> From: Varadarajan, Charulatha
> >> Sent: Tuesday, August 10, 2010 10:49 AM
> >>
> >>> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> >>> Sent: Tuesday, August 10, 2010 3:51 AM
> >>>
> >>> Charulatha V<charu@ti.com>  writes:
> >>>
> >>>> This is in prepartion for implementing GPIO as a platform device.
> >>>> gpio bank's base addresses are moved from gpio.c to plat/gpio.h.
> >>>>
> >>>> This patch also modifies omap_gpio_init() to make use of
> >>>> omap_gpio_chip_init() and omap_gpio_mod_init(). omap_gpio_mod_init()
> >>> does
> >>>> the module init by clearing the status register and initializing the
> >>>> GPIO control register. omap_gpio_chip_init() initializes the chip
> >>> request,
> >>>> free, get, set and other function pointers and sets the gpio irq
> >> handler.
> >>>>
> >>>> Signed-off-by: Charulatha V<charu@ti.com>
> >>>> Signed-off-by: Basak, Partha<p-basak2@ti.com>
> >>>
> >>> [...]
> >>>
> >>>> +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);
> >>>> +			/* Enable autoidle for the OCP interface */
> >>>> +			omap_writel(1<<  0, 0x48306814);
> >>>
> >>> This autoidle stuff should be removed in this series as setting this
> is
> >>> handled by the hwmod layer.
> >>
> >> Okay.
> >
> > This code is incorrectly setting the PRCM_SYSCONFIG(0x48306814) register
> inside GPIO module which is incorrect. Ideally it should be moved to
> generic code like prcm_setup_regs() inside PM44xx.c/PM34xx.c. Having said
> that, the reset value of PRCM_SYSCONFIG is 0x01, so it would be safe just
> to remove this.
> 
> That's weird, do you know where it come from? Maybe it is re-enable
> because someone disable it at some point?
> It is indeed a dirty hack, but it will be good to understand the
> rational, if any?
> 
> The code is from that commit: 5492fb1a ARM: OMAP: Add 3430 gpio support
> from Khasim Syed Mohammed (Added in Cc).
> 
> It seems to be a bad copy paste of the 2420 code (omap_writel(1<<  0,
> 0x48019010)). That one is indeed changing the GPIO SYSCONFIG.
> 
> 
> > Now, coming to setting of AutoIdle (in CM_AUTOIDLE_XXX registers), even
> though prcm_reg_ids are being populated, hwmod framework is not setting
> these anywhere, all CM_AutoIdle settings are being done one-time in side
> prcm_setup_regs().
> 
> In this case, Kevin was referring to the SYSCONFIG autoidle setting not
> the PRCM one. But the following point is still valid.
> 
> > Kevin, as you pointed out this needs to be done in the framework.
> 
> Yep, good point, it was indeed already suggested by the comment:
> 
> 	/*
> 	 * Enable interface clock autoidle for all modules.
> 	 * Note that in the long run this should be done by clockfw
> 	 */
> 
> Except that doing that in hwmod make more sense now. hwmod probably
> didn't exist at that time.
> 
> Everything is in place in the hwmod prcm struct to set this setting from
> the hwmod core code.
> 
> > Can we do it as part of enabling the slave clocks? How does the
> following look?
> >
> > static int _enable_clocks(struct omap_hwmod *oh)
> > {
> > 	int i;
> >
> > 	pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
> >
> > 	if (oh->_clk)
> > 		clk_enable(oh->_clk);
> >
> > 	if (oh->slaves_cnt>  0) {
> > 		for (i = 0; i<  oh->slaves_cnt; i++) {
> > 			struct omap_hwmod_ocp_if *os = oh->slaves[i];
> > 			struct clk *c = os->_clk;
> >
> > 			if (c&&  (os->flags&  OCPIF_SWSUP_IDLE))
> > 				clk_enable(c);
> > 			else
> > 				/*TODO: Set CM_AutoIdle here*/
> > 		}
> > 	}
> >
> > 	/* The opt clocks are controlled by the device driver. */
> >
> > 	return 0;
> > }
> 
> It should be done only once, so it is better to do that at _setup time
> instead.
> Please note that this is an OMAP2&3 setting only. That bit does not
> exist anymore in OMAP4.
> 

We will put this as part of _setup. Also, we will remove this hard-coded setting from GPIO code. Aligned.

> Regards,
> Benoit

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

* RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-09 23:06                     ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Kevin Hilman
@ 2010-08-10 11:53                       ` Basak, Partha
  2010-08-10 17:59                         ` Kevin Hilman
  2010-08-11  5:47                         ` Paul Walmsley
  0 siblings, 2 replies; 38+ messages in thread
From: Basak, Partha @ 2010-08-10 11:53 UTC (permalink / raw)
  To: Kevin Hilman, Varadarajan, Charulatha
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 4:36 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: Re: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform
> device
> 
> Charulatha V <charu@ti.com> writes:
> 
> > @@ -650,21 +511,28 @@ static void _set_gpio_debounce(struct gpio_bank
> *bank, unsigned gpio,
> >  	__raw_writel(debounce, reg);
> >
> >  	reg = bank->base;
> > -	if (cpu_is_omap44xx())
> > +	if (bank->method == METHOD_GPIO_44XX)
> >  		reg += OMAP4_GPIO_DEBOUNCENABLE;
> >  	else
> >  		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
> >
> >  	val = __raw_readl(reg);
> >
> > +	if (!bank->dbck) {
> > +		struct platform_device *pdev = to_platform_device(bank->dev);
> > +		struct omap_device *odev = to_omap_device(pdev);
> 
> insert empty line
> 
> > +		if (odev->hwmods[0]->opt_clks->_clk)
> > +			bank->dbck = odev->hwmods[0]->opt_clks->_clk;


This is not correct always as opt_clks points to an array of optional clocks 
which can have more than one element.
The correct approach would be to scan through the list of optional clocks and pick up the one with role === "dbclk".
> 
> As was discussed in Bangalore, drivers should have no knowledge of hwmod
> internals.
> 
> Instead, please propose an API to hwmod for getting the optional
> clock(s), or possibly cleaner, an API to directly enable/disable
> optional clocks for an omap_device.

As per our discussion with Paul & you during workshop, I believe, optional clock control should be done using clock APIs. So, I would go by your suggestion 1 of exposing an API to expose the optional clocks in the hwmod, something like:
struct omap_hwmod_opt_clk	* omap_hwmod_get_opt_clks(struct omap_hwmod *oh);
If agreed, Charu will send updated patch.

> 
> Kevin
> 
> > +		if (IS_ERR(bank->dbck))
> > +			dev_err(bank->dev, "Could not get gpio dbck\n");
> > +	}
> > +

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

* RE: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-10  0:21                         ` Kevin Hilman
@ 2010-08-10 12:37                           ` Basak, Partha
  2010-08-10 18:10                             ` Kevin Hilman
  2010-08-12 12:43                           ` Basak, Partha
  1 sibling, 1 reply; 38+ messages in thread
From: Basak, Partha @ 2010-08-10 12:37 UTC (permalink / raw)
  To: Kevin Hilman, Varadarajan, Charulatha
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 5:51 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> Rajendra; Basak, Partha
> Subject: Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of
> sys_dev_class
> 
> Charulatha V <charu@ti.com> writes:
> 
> > This patch makes GPIO driver to use dev_pm_ops instead of
> > sysdev_class. With this approach, gpio_bank_suspend & gpio_bank_resume
> > are not part of sys_dev_class.
> >
> > According to this patch, a GPIO bank relinquishes the clock using
> > PM runtime APIs when all the gpios in that bank are freed.
> 
> This does not match the code.
> 
> The only clock associated with a GPIO hwmod is the optional clock for
> the debounce clock.  This clock is managed by the driver itself, not
> by using the PM runtime API.
> 
> > It also
> > relinquishes the clocks in the idle-path too, as it is possible to
> > have a GPIO bank requested and still allow PER domain to go to OFF
> state.
> 
> This doesn't make sense to me.  What clocks are you referring to?
> 

The main clock is there for OMAP24xx, but not relevant for OMAP3 & 4.

> > In the idle path (interrupt disabled context), PM runtime APIs cannot
> > be used as they are not mutex-free functions. Hence omap_device APIs
> > are used in the idle and resume after idle path.
> 
> This needs much more fleshing out.
> 
> Exactly what mutexes are causing the problems here.  As pointed out in
> previous discussions, the ones in the PM runtime core should not be a
> problem in this path.  Therefore, I'll assume the problems are coming
> from the mutexes when the device code (mach-omap2/gpio.c) calls into the
> hwmod layer.  More on this in comments on the next patch.
> 

Sorry, this has not been documented correctly. The issue has more to do unconditional enabling of interrupts. We have received a patch from you on using pm_runtime functions in Idle path. We will try on GPIO and revert back.

> > To summarize,
> > 1. pm_runtime_get_sync() for any gpio bank is called when one of the
> gpios
> >    is requested on the bank, in which, no other gpio is being used (when
> >    mod_usage becomes non-zero)
> > 2. omap_device_enable() is called during gpio resume after idle, only
> >    if the particular bank is being used (if mod_usage is non-zero)
> 
> context is saved/restored in the idle path, but...
> 
> > 3. pm_runtime_put_sync() is called when the last used gpio in that
> >    gpio bank is freed (when mod_usage becomes zero)
> 
> in this path, the bank is now runtime suspended, but context has not
> been saved for it.  That should be fine, since this bank is no longer
> used, but now let's assume there was an off-mode transition and context
> is lost.  Then, gpio_request() is called which will trigger
> a pm_runtime_get_sync() and gpio_bank_runtime_resume() will be called.
> 
> In this case, it's not terribly clear that runtime_resume is doing sane
> things if context has just been lost.  Seems like runtime_resume should
> be a nop in this case since any re-init will be be done in gpio_request().

Runtime_suspend/resume for GPIO is not doing any save/restore context. In that sense, they are NOP. Context save/restore is taken care of only in the Idle path based on target power state and last power state respectively.

> 
> > 4. omap_device_idle() is called during idle, if the particular bank
> >    is being used (if mod_usage is non-zero)
> 
> This mixture of pm_runtime_* and omap_device_* APIs is confusing at
> best.
> 
> There should be a single path into the drivers runtime_suspend hooks.
> Namely, when pm_runtime_put_* is called and the usecount goes to zero.
> If you can't use the runtime PM APIs, then we need to understand
> *exactly* why and work on a solution for that particular problem.
> 
> On my omap34xx/omap3evm, I had to disable the omap_device_* calls in the
> idle path since as they were causing strange crashes, and as stated
> above, I'm not sure what the purpose is.
> 
> > With this patch, GPIO's prepare_for_idle and resume_after_idle APIs
> > makes use of the parameter save_context and restore_context respectively
> > inorder to identify if save context/restore context needs to be done.
> 
> Why?
> 
> > Links to related discussion:
> > http://www.mail-archive.com/linux-omap@vger.kernel.org/msg32833.html
> >
> > For suspend/resume path to work, this patch has dependency of
> > 1. reverting the following patch:
> > OMAP: bus-level PM: enable use of runtime PM API for suspend/resume
> > http://dev.omapzoom.org/?p=swarch/linux-omap-adv.git;a=commitdiff;
> > h=8041359e18e49bf8a3d41f15894db9e476f3a8fc
> > (or)
> > 2. Remove the locking in the omap_hwmod_for_each* function
> 
> Did you mean 'and' instead of 'or'?  If you meant 'or', then clearly
> (20 is preferred over (1), and I have a patch to fix that in the current
> pm-wip/runtime branch.
> 
> If you meant 'and', then you need to describe the root cause for (1).
> 
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Basak, Partha <p-basak2@ti.com>
> > ---
> >  arch/arm/mach-omap2/pm24xx.c           |    4 +-
> >  arch/arm/mach-omap2/pm34xx.c           |   23 +-
> >  arch/arm/plat-omap/gpio.c              |  561 ++++++++++++++++---------
> -------
> >  arch/arm/plat-omap/include/plat/gpio.h |    6 +-
> >  4 files changed, 297 insertions(+), 297 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
> > index 6aeedea..c01e156 100644
> > --- a/arch/arm/mach-omap2/pm24xx.c
> > +++ b/arch/arm/mach-omap2/pm24xx.c
> > @@ -106,7 +106,7 @@ static void omap2_enter_full_retention(void)
> >  	l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) |
> OMAP24XX_USBSTANDBYCTRL;
> >  	omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
> >
> > -	omap2_gpio_prepare_for_idle(PWRDM_POWER_RET);
> > +	omap2_gpio_prepare_for_idle(false);
> >
> >  	if (omap2_pm_debug) {
> >  		omap2_pm_dump(0, 0, 0);
> > @@ -140,7 +140,7 @@ no_sleep:
> >  		tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
> >  		omap2_pm_dump(0, 1, tmp);
> >  	}
> > -	omap2_gpio_resume_after_idle();
> > +	omap2_gpio_resume_after_idle(false);
> >
> >  	clk_enable(osc_ck);
> >
> > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> > index fb4994a..66c7e11 100644
> > --- a/arch/arm/mach-omap2/pm34xx.c
> > +++ b/arch/arm/mach-omap2/pm34xx.c
> > @@ -79,16 +79,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
> >  static struct powerdomain *core_pwrdm, *per_pwrdm;
> >  static struct powerdomain *cam_pwrdm;
> >
> > -static inline void omap3_per_save_context(void)
> > -{
> > -	omap_gpio_save_context();
> > -}
> > -
> > -static inline void omap3_per_restore_context(void)
> > -{
> > -	omap_gpio_restore_context();
> > -}
> > -
> >  static void omap3_enable_io_chain(void)
> >  {
> >  	int timeout = 0;
> > @@ -395,15 +385,17 @@ void omap_sram_idle(void)
> >  	/* PER */
> >  	if (per_next_state < PWRDM_POWER_ON) {
> >  		omap_uart_prepare_idle(2);
> > -		omap2_gpio_prepare_for_idle(per_next_state);
> >  		if (per_next_state == PWRDM_POWER_OFF) {
> >  			if (core_next_state == PWRDM_POWER_ON) {
> >  				per_next_state = PWRDM_POWER_RET;
> >  				pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
> >  				per_state_modified = 1;
> > -			} else
> > -				omap3_per_save_context();
> > +			}
> >  		}
> > +		if (per_next_state == PWRDM_POWER_OFF)
> > +			omap2_gpio_prepare_for_idle(true);
> > +		else
> > +			omap2_gpio_prepare_for_idle(false);
> 
> Why is this better than passing the next power state?

This would keep the GPIO function omap2_gpio_prepare_for_idle agnostic of Power state definition dependencies.
> 
> >  	}
> >
> >  	if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
> > @@ -471,9 +463,10 @@ void omap_sram_idle(void)
> >  	/* PER */
> >  	if (per_next_state < PWRDM_POWER_ON) {
> >  		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
> > -		omap2_gpio_resume_after_idle();
> >  		if (per_prev_state == PWRDM_POWER_OFF)
> > -			omap3_per_restore_context();
> > +			omap2_gpio_resume_after_idle(true);
> > +		else
> > +			omap2_gpio_resume_after_idle(false);
> >  		omap_uart_resume_idle(2);
> >  		if (per_state_modified)
> >  			pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
> > diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
> > index 6a5cf43..6686f9f 100644
> > --- a/arch/arm/plat-omap/gpio.c
> > +++ b/arch/arm/plat-omap/gpio.c
> > @@ -25,12 +25,12 @@
> >  #include <linux/pm_runtime.h>
> >
> >  #include <plat/omap_device.h>
> > +#include <plat/powerdomain.h>
> >  #include <mach/hardware.h>
> >  #include <asm/irq.h>
> >  #include <mach/irqs.h>
> >  #include <mach/gpio.h>
> >  #include <asm/mach/irq.h>
> > -#include <plat/powerdomain.h>
> >
> >  /*
> >   * OMAP1510 GPIO registers
> > @@ -179,7 +179,6 @@ struct gpio_bank {
> >   * related to all instances of the device
> >   */
> >  static struct gpio_bank *gpio_bank;
> > -
> >  static int bank_width;
> >
> >  /* TODO: Analyze removing gpio_bank_count usage from driver code */
> > @@ -1045,6 +1044,9 @@ static int omap_gpio_request(struct gpio_chip
> *chip, unsigned offset)
> >  	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
> >  	unsigned long flags;
> >
> > +	if (!bank->mod_usage)
> > +		pm_runtime_get_sync(bank->dev);
> > +
> 
> Would be fine to skip the 'if' here and let runtime PM continue the
> usecounting.  Since we'll have trace tools that instrument runtime PM,
> it will be nice to be able to trace all the users instead of just the
> first one to request a GPIO in a given bank.
> 
> >  	spin_lock_irqsave(&bank->lock, flags);
> >
> >  	/* Set trigger to none. You need to enable the desired trigger with
> > @@ -1061,22 +1063,19 @@ static int omap_gpio_request(struct gpio_chip
> *chip, unsigned offset)
> >  		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
> >  	}
> >  #endif
> > -	if (!cpu_class_is_omap1()) {
> > -		if (!bank->mod_usage) {
> > -			void __iomem *reg = bank->base;
> > -			u32 ctrl;
> > -
> > -			if (cpu_is_omap24xx() || cpu_is_omap34xx())
> > -				reg += OMAP24XX_GPIO_CTRL;
> > -			else if (cpu_is_omap44xx())
> > -				reg += OMAP4_GPIO_CTRL;
> > -			ctrl = __raw_readl(reg);
> > -			/* Module is enabled, clocks are not gated */
> > -			ctrl &= 0xFFFFFFFE;
> > -			__raw_writel(ctrl, reg);
> > -		}
> > -		bank->mod_usage |= 1 << offset;
> > +	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
> > +		void __iomem *reg = bank->base;
> > +		u32 ctrl;
> > +		if (bank->method == METHOD_GPIO_24XX)
> > +			reg += OMAP24XX_GPIO_CTRL;
> > +		else if (bank->method == METHOD_GPIO_44XX)
> > +			reg += OMAP4_GPIO_CTRL;
> > +		ctrl = __raw_readl(reg);
> > +		/* Module is enabled, clocks are not gated */
> > +		ctrl &= 0xFFFFFFFE;
> > +		__raw_writel(ctrl, reg);
> 
> If you get rid of the 'if (!mod_usage)' check above for the
> pm_runtime_get, you could just get rid of the mod_usage flag all
> together and do this section in the runtime_resume hook.
> 
> >  	}
> > +	bank->mod_usage |= 1 << offset;
> >  	spin_unlock_irqrestore(&bank->lock, flags);
> >
> >  	return 0;
> > @@ -1109,24 +1108,26 @@ static void omap_gpio_free(struct gpio_chip
> *chip, unsigned offset)
> >  		__raw_writel(1 << offset, reg);
> >  	}
> >  #endif
> > -	if (!cpu_class_is_omap1()) {
> > -		bank->mod_usage &= ~(1 << offset);
> > -		if (!bank->mod_usage) {
> > -			void __iomem *reg = bank->base;
> > -			u32 ctrl;
> > -
> > -			if (cpu_is_omap24xx() || cpu_is_omap34xx())
> > -				reg += OMAP24XX_GPIO_CTRL;
> > -			else if (cpu_is_omap44xx())
> > -				reg += OMAP4_GPIO_CTRL;
> > -			ctrl = __raw_readl(reg);
> > -			/* Module is disabled, clocks are gated */
> > -			ctrl |= 1;
> > -			__raw_writel(ctrl, reg);
> > -		}
> > +	bank->mod_usage &= ~(1 << offset);
> > +	if ((!bank->mod_usage) && (!cpu_class_is_omap1())) {
> > +		void __iomem *reg = bank->base;
> > +		u32 ctrl;
> > +
> > +		if (bank->method == METHOD_GPIO_24XX)
> > +			reg += OMAP24XX_GPIO_CTRL;
> > +		else if (bank->method == METHOD_GPIO_44XX)
> > +			reg += OMAP4_GPIO_CTRL;
> > +		ctrl = __raw_readl(reg);
> > +		/* Module is disabled, clocks are gated */
> > +		ctrl |= 1;
> > +		__raw_writel(ctrl, reg);
> 
> ditto, but in the runtime_suspend hook
> 
> >  	}
> > +
> >  	_reset_gpio(bank, bank->chip.base + offset);
> >  	spin_unlock_irqrestore(&bank->lock, flags);
> > +
> > +	if (!bank->mod_usage)
> > +		pm_runtime_put_sync(bank->dev);
> 
> see above
> 
> >  }
> >
> >  /*
> > @@ -1728,7 +1729,6 @@ static int __devinit omap_gpio_probe(struct
> platform_device *pdev)
> >  	}
> >
> >  	pm_runtime_enable(bank->dev);
> > -	pm_runtime_get_sync(bank->dev);
> 
> as mentioned before, this should stay, otherwise mod_init will fault if
> GPIO hwmod is disabled.
> 
> >  	omap_gpio_mod_init(bank, id);
> >  	omap_gpio_chip_init(bank);
> > @@ -1741,294 +1741,222 @@ static int __devinit omap_gpio_probe(struct
> platform_device *pdev)
> 
> and you'd need a matching 'put' here.

Agreed.

> 
> [...]
> 
> Kevin

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

* Re: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-10 11:53                       ` Basak, Partha
@ 2010-08-10 17:59                         ` Kevin Hilman
  2010-08-11  5:47                         ` Paul Walmsley
  1 sibling, 0 replies; 38+ messages in thread
From: Kevin Hilman @ 2010-08-10 17:59 UTC (permalink / raw)
  To: Basak, Partha
  Cc: Varadarajan, Charulatha, linux-omap, paul, Cousson, Benoit,
	Nayak, Rajendra

"Basak, Partha" <p-basak2@ti.com> writes:

>> Instead, please propose an API to hwmod for getting the optional
>> clock(s), or possibly cleaner, an API to directly enable/disable
>> optional clocks for an omap_device.
>
> As per our discussion with Paul & you during workshop, I believe,
> optional clock control should be done using clock APIs. So, I would go
> by your suggestion 1 of exposing an API to expose the optional clocks
> in the hwmod, something like: 
>
> struct omap_hwmod_opt_clk * omap_hwmod_get_opt_clks(struct omap_hwmod
> *oh); 
>
> If agreed, Charu will send updated patch.

OK with me.



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

* Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-10 12:37                           ` Basak, Partha
@ 2010-08-10 18:10                             ` Kevin Hilman
  2010-08-12  7:49                               ` Basak, Partha
  0 siblings, 1 reply; 38+ messages in thread
From: Kevin Hilman @ 2010-08-10 18:10 UTC (permalink / raw)
  To: Basak, Partha
  Cc: Varadarajan, Charulatha, linux-omap, paul, Cousson, Benoit,
	Nayak, Rajendra

"Basak, Partha" <p-basak2@ti.com> writes:

[...]

>> > In the idle path (interrupt disabled context), PM runtime APIs cannot
>> > be used as they are not mutex-free functions. Hence omap_device APIs
>> > are used in the idle and resume after idle path.
>> 
>> This needs much more fleshing out.
>> 
>> Exactly what mutexes are causing the problems here.  As pointed out in
>> previous discussions, the ones in the PM runtime core should not be a
>> problem in this path.  Therefore, I'll assume the problems are coming
>> from the mutexes when the device code (mach-omap2/gpio.c) calls into the
>> hwmod layer.  More on this in comments on the next patch.
>> 
>
> Sorry, this has not been documented correctly. The issue has more to
> do unconditional enabling of interrupts. We have received a patch from
> you on using pm_runtime functions in Idle path. We will try on GPIO
> and revert back.

OK

>
>> > To summarize,
>> > 1. pm_runtime_get_sync() for any gpio bank is called when one of the
>> gpios
>> >    is requested on the bank, in which, no other gpio is being used (when
>> >    mod_usage becomes non-zero)
>> > 2. omap_device_enable() is called during gpio resume after idle, only
>> >    if the particular bank is being used (if mod_usage is non-zero)
>> 
>> context is saved/restored in the idle path, but...
>> 
>> > 3. pm_runtime_put_sync() is called when the last used gpio in that
>> >    gpio bank is freed (when mod_usage becomes zero)
>> 
>> in this path, the bank is now runtime suspended, but context has not
>> been saved for it.  That should be fine, since this bank is no longer
>> used, but now let's assume there was an off-mode transition and context
>> is lost.  Then, gpio_request() is called which will trigger
>> a pm_runtime_get_sync() and gpio_bank_runtime_resume() will be called.
>> 
>> In this case, it's not terribly clear that runtime_resume is doing sane
>> things if context has just been lost.  Seems like runtime_resume should
>> be a nop in this case since any re-init will be be done in gpio_request().
>
> Runtime_suspend/resume for GPIO is not doing any save/restore
> context. In that sense, they are NOP. Context save/restore is taken
> care of only in the Idle path based on target power state and last
> power state respectively.

OK, I didn't explain the problem I'm suspecting very well.  Imagine this
sequence of events:

- mod_usage becomes zero
- pm_runtime_put_sync()
- gpio_bank_runtime_suspend()  [ no context is saved ]
  [ off-mode transition, context is lost]
- gpio_request()
- pm_runtime_get_sync()
- gpio_bank_runtime_resume()

In this path, no context is saved, and no context is restored, which is
what I would expect, since there's no need to save context if nobody is
using that gpio bank anymore.   However, gpio_bank_runtime_resume() is
doing lots of reads/writes and read-modify-writes on GPIO bank registers
that may have undefined contents after a context loss.

The point is that the GPIO register twiddling in
gpio_bank_runtime_resume() does not seem to be needed if there are no
users of that GPIO bank.

[...]

>> >  static void omap3_enable_io_chain(void)
>> >  {
>> >  	int timeout = 0;
>> > @@ -395,15 +385,17 @@ void omap_sram_idle(void)
>> >  	/* PER */
>> >  	if (per_next_state < PWRDM_POWER_ON) {
>> >  		omap_uart_prepare_idle(2);
>> > -		omap2_gpio_prepare_for_idle(per_next_state);
>> >  		if (per_next_state == PWRDM_POWER_OFF) {
>> >  			if (core_next_state == PWRDM_POWER_ON) {
>> >  				per_next_state = PWRDM_POWER_RET;
>> >  				pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
>> >  				per_state_modified = 1;
>> > -			} else
>> > -				omap3_per_save_context();
>> > +			}
>> >  		}
>> > +		if (per_next_state == PWRDM_POWER_OFF)
>> > +			omap2_gpio_prepare_for_idle(true);
>> > +		else
>> > +			omap2_gpio_prepare_for_idle(false);
>> 
>> Why is this better than passing the next power state?
>
> This would keep the GPIO function omap2_gpio_prepare_for_idle agnostic of Power state definition dependencies.
>

And why is this better?  

Personally, I think the GPIO code should be told about the powerdomain
state so it can make it's own decision about whether or not to save
context.

Kevin

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

* RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-10 11:53                       ` Basak, Partha
  2010-08-10 17:59                         ` Kevin Hilman
@ 2010-08-11  5:47                         ` Paul Walmsley
  2010-08-12 12:10                           ` Basak, Partha
  2010-08-23 15:46                           ` Basak, Partha
  1 sibling, 2 replies; 38+ messages in thread
From: Paul Walmsley @ 2010-08-11  5:47 UTC (permalink / raw)
  To: Basak, Partha
  Cc: Kevin Hilman, Varadarajan, Charulatha, linux-omap, Cousson,
	Benoit, Nayak, Rajendra

On Tue, 10 Aug 2010, Basak, Partha wrote:

> As per our discussion with Paul & you during workshop, I believe, 
> optional clock control should be done using clock APIs. So, I would go 
> by your suggestion 1 of exposing an API to expose the optional clocks in 
> the hwmod, something like:
>
> struct omap_hwmod_opt_clk * omap_hwmod_get_opt_clks(struct omap_hwmod 
> *oh);
>
> If agreed, Charu will send updated patch.

This should be done by modifying the hwmod code to call clk_add_alias() 
for the clock names for the optional clocks.  I don't think any extra API 
is needed.


- Paul

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

* RE: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-10 18:10                             ` Kevin Hilman
@ 2010-08-12  7:49                               ` Basak, Partha
  2010-08-12 14:07                                 ` Kevin Hilman
  0 siblings, 1 reply; 38+ messages in thread
From: Basak, Partha @ 2010-08-12  7:49 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Varadarajan, Charulatha, linux-omap, paul, Cousson, Benoit,
	Nayak, Rajendra



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Tuesday, August 10, 2010 11:40 PM
> To: Basak, Partha
> Cc: Varadarajan, Charulatha; linux-omap@vger.kernel.org; paul@pwsan.com;
> Cousson, Benoit; Nayak, Rajendra
> Subject: Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of
> sys_dev_class
> 
> "Basak, Partha" <p-basak2@ti.com> writes:
> 
> [...]
> 
> >> > In the idle path (interrupt disabled context), PM runtime APIs cannot
> >> > be used as they are not mutex-free functions. Hence omap_device APIs
> >> > are used in the idle and resume after idle path.
> >>
> >> This needs much more fleshing out.
> >>
> >> Exactly what mutexes are causing the problems here.  As pointed out in
> >> previous discussions, the ones in the PM runtime core should not be a
> >> problem in this path.  Therefore, I'll assume the problems are coming
> >> from the mutexes when the device code (mach-omap2/gpio.c) calls into
> the
> >> hwmod layer.  More on this in comments on the next patch.
> >>
> >
> > Sorry, this has not been documented correctly. The issue has more to
> > do unconditional enabling of interrupts. We have received a patch from
> > you on using pm_runtime functions in Idle path. We will try on GPIO
> > and revert back.
> 
> OK
> 
> >
> >> > To summarize,
> >> > 1. pm_runtime_get_sync() for any gpio bank is called when one of the
> >> gpios
> >> >    is requested on the bank, in which, no other gpio is being used
> (when
> >> >    mod_usage becomes non-zero)
> >> > 2. omap_device_enable() is called during gpio resume after idle, only
> >> >    if the particular bank is being used (if mod_usage is non-zero)
> >>
> >> context is saved/restored in the idle path, but...
> >>
> >> > 3. pm_runtime_put_sync() is called when the last used gpio in that
> >> >    gpio bank is freed (when mod_usage becomes zero)
> >>
> >> in this path, the bank is now runtime suspended, but context has not
> >> been saved for it.  That should be fine, since this bank is no longer
> >> used, but now let's assume there was an off-mode transition and context
> >> is lost.  Then, gpio_request() is called which will trigger
> >> a pm_runtime_get_sync() and gpio_bank_runtime_resume() will be called.
> >>
> >> In this case, it's not terribly clear that runtime_resume is doing sane
> >> things if context has just been lost.  Seems like runtime_resume should
> >> be a nop in this case since any re-init will be be done in
> gpio_request().
> >
> > Runtime_suspend/resume for GPIO is not doing any save/restore
> > context. In that sense, they are NOP. Context save/restore is taken
> > care of only in the Idle path based on target power state and last
> > power state respectively.
> 
> OK, I didn't explain the problem I'm suspecting very well.  Imagine this
> sequence of events:
> 
> - mod_usage becomes zero
> - pm_runtime_put_sync()
> - gpio_bank_runtime_suspend()  [ no context is saved ]
>   [ off-mode transition, context is lost]
> - gpio_request()
> - pm_runtime_get_sync()
> - gpio_bank_runtime_resume()
> 
> In this path, no context is saved, and no context is restored, which is
> what I would expect, since there's no need to save context if nobody is
> using that gpio bank anymore.   However, gpio_bank_runtime_resume() is
> doing lots of reads/writes and read-modify-writes on GPIO bank registers
> that may have undefined contents after a context loss.
> 
> The point is that the GPIO register twiddling in
> gpio_bank_runtime_resume() does not seem to be needed if there are no
> users of that GPIO bank.
> 
> [...]
> 
> >> >  static void omap3_enable_io_chain(void)
> >> >  {
> >> >  	int timeout = 0;
> >> > @@ -395,15 +385,17 @@ void omap_sram_idle(void)
> >> >  	/* PER */
> >> >  	if (per_next_state < PWRDM_POWER_ON) {
> >> >  		omap_uart_prepare_idle(2);
> >> > -		omap2_gpio_prepare_for_idle(per_next_state);
> >> >  		if (per_next_state == PWRDM_POWER_OFF) {
> >> >  			if (core_next_state == PWRDM_POWER_ON) {
> >> >  				per_next_state = PWRDM_POWER_RET;
> >> >  				pwrdm_set_next_pwrst(per_pwrdm,
> per_next_state);
> >> >  				per_state_modified = 1;
> >> > -			} else
> >> > -				omap3_per_save_context();
> >> > +			}
> >> >  		}
> >> > +		if (per_next_state == PWRDM_POWER_OFF)
> >> > +			omap2_gpio_prepare_for_idle(true);
> >> > +		else
> >> > +			omap2_gpio_prepare_for_idle(false);
> >>
> >> Why is this better than passing the next power state?
> >
> > This would keep the GPIO function omap2_gpio_prepare_for_idle agnostic
> of Power state definition dependencies.
> >
> 
> And why is this better?
> 
> Personally, I think the GPIO code should be told about the powerdomain
> state so it can make it's own decision about whether or not to save
> context.
> 

I see your point. 

But, in the approach we have followed so far, we are trying to localize all Power domain related logic and information in pm_34xxx.c. If we refer to all 
other such functions like omap_uart_prepare_idle(),omap3_intc_prepare_idle(), musb_context_save_restore()(newly introduced by USB patches for HWMOD), they are all following the same paradigm. None of these functions receive the Power state information as a parameter. The idea is to segregate the Power domain related information into the power layer. 

In omap2_gpio_prepare_for_idle() implementation, we are just being consistent with this approach.

> Kevin

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

* RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-11  5:47                         ` Paul Walmsley
@ 2010-08-12 12:10                           ` Basak, Partha
  2010-08-23 15:46                           ` Basak, Partha
  1 sibling, 0 replies; 38+ messages in thread
From: Basak, Partha @ 2010-08-12 12:10 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Varadarajan, Charulatha, linux-omap, Cousson,
	Benoit, Nayak, Rajendra



> -----Original Message-----
> From: Paul Walmsley [mailto:paul@pwsan.com]
> Sent: Wednesday, August 11, 2010 11:17 AM
> To: Basak, Partha
> Cc: Kevin Hilman; Varadarajan, Charulatha; linux-omap@vger.kernel.org;
> Cousson, Benoit; Nayak, Rajendra
> Subject: RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform
> device
> 
> On Tue, 10 Aug 2010, Basak, Partha wrote:
> 
> > As per our discussion with Paul & you during workshop, I believe,
> > optional clock control should be done using clock APIs. So, I would go
> > by your suggestion 1 of exposing an API to expose the optional clocks in
> > the hwmod, something like:
> >
> > struct omap_hwmod_opt_clk * omap_hwmod_get_opt_clks(struct omap_hwmod
> > *oh);
> >
> > If agreed, Charu will send updated patch.
> 
> This should be done by modifying the hwmod code to call clk_add_alias()
> for the clock names for the optional clocks.  I don't think any extra API
> is needed.
> 

Lets see, if I got it right:

Refer to the OMAP3 hwmod data-base (omap_hwmod_3xxx.c): 
static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
	{ .role = "dbclk", .clk = "gpio1_dbck", },
};
Clock database(Clock3xxx_data.c):
	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),


Refer to the OMAP4 hwmod database(omap_hwmod_44xx.c): 
	static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
		{ .role = "dbclk", .clk = "sys_32k_ck" },

Clock database(Clock44xx_data.c):

CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_443X),


/*int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
	struct device *dev);*/

I believe, you are suggesting to do the following in the hwmod framework, say _setup(?):

clk_add_alias ( <gpio1_>opt_clks.role,
			 oh->od.pdev.name, 
			<gpio1_>opt_clks.clk,
			NULL);

Then, from the driver, we can simply do a 
	clk_get(dev_ptr, 
			<role-->"dbclk">); /*hard-coded in the driver to be same 			as in the hwmod database*/

> 
> - Paul

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

* RE: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-10  0:21                         ` Kevin Hilman
  2010-08-10 12:37                           ` Basak, Partha
@ 2010-08-12 12:43                           ` Basak, Partha
  1 sibling, 0 replies; 38+ messages in thread
From: Basak, Partha @ 2010-08-12 12:43 UTC (permalink / raw)
  To: Basak, Partha, Kevin Hilman, Varadarajan, Charulatha
  Cc: linux-omap, paul, Cousson, Benoit, Nayak, Rajendra

> 
> > -----Original Message-----
> > From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> > Sent: Tuesday, August 10, 2010 5:51 AM
> > To: Varadarajan, Charulatha
> > Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Nayak,
> > Rajendra; Basak, Partha
> > Subject: Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of
> > sys_dev_class
> >
> > Charulatha V <charu@ti.com> writes:
> >
> > > This patch makes GPIO driver to use dev_pm_ops instead of
> > > sysdev_class. With this approach, gpio_bank_suspend & gpio_bank_resume
> > > are not part of sys_dev_class.
> > >
> > > According to this patch, a GPIO bank relinquishes the clock using
> > > PM runtime APIs when all the gpios in that bank are freed.
> >
> > This does not match the code.
> >
> > The only clock associated with a GPIO hwmod is the optional clock for
> > the debounce clock.  This clock is managed by the driver itself, not
> > by using the PM runtime API.
> >
> > > It also
> > > relinquishes the clocks in the idle-path too, as it is possible to
> > > have a GPIO bank requested and still allow PER domain to go to OFF
> > state.
> >
> > This doesn't make sense to me.  What clocks are you referring to?
> >
> 
> The main clock is there for OMAP24xx, but not relevant for OMAP3 & 4.
> 

Are you aligned?

> > > In the idle path (interrupt disabled context), PM runtime APIs cannot
> > > be used as they are not mutex-free functions. Hence omap_device APIs
> > > are used in the idle and resume after idle path.
> >
> > This needs much more fleshing out.
> >
> > Exactly what mutexes are causing the problems here.  As pointed out in
> > previous discussions, the ones in the PM runtime core should not be a
> > problem in this path.  Therefore, I'll assume the problems are coming
> > from the mutexes when the device code (mach-omap2/gpio.c) calls into the
> > hwmod layer.  More on this in comments on the next patch.
> >
> 
> Sorry, this has not been documented correctly. The issue has more to do
> unconditional enabling of interrupts. We have received a patch from you on
> using pm_runtime functions in Idle path. We will try on GPIO and revert
> back.
> 
> >
> > >
> > >> > To summarize,
> > >> > 1. pm_runtime_get_sync() for any gpio bank is called when one of
> the
> > >> gpios
> > >> >    is requested on the bank, in which, no other gpio is being used
> > (when
> > >> >    mod_usage becomes non-zero)
> > >> > 2. omap_device_enable() is called during gpio resume after idle,
> only
> > >> >    if the particular bank is being used (if mod_usage is non-zero)
> > >>
> > >> context is saved/restored in the idle path, but...
> > >>
> > >> > 3. pm_runtime_put_sync() is called when the last used gpio in that
> > >> >    gpio bank is freed (when mod_usage becomes zero)
> > >>
> > >> in this path, the bank is now runtime suspended, but context has not
> > >> been saved for it.  That should be fine, since this bank is no longer
> > >> used, but now let's assume there was an off-mode transition and
> context
> > >> is lost.  Then, gpio_request() is called which will trigger
> > >> a pm_runtime_get_sync() and gpio_bank_runtime_resume() will be
> called.
> > >>
> > >> In this case, it's not terribly clear that runtime_resume is doing
> sane
> > >> things if context has just been lost.  Seems like runtime_resume
> should
> > >> be a nop in this case since any re-init will be be done in
> > gpio_request().
> > >
> > > Runtime_suspend/resume for GPIO is not doing any save/restore
> > > context. In that sense, they are NOP. Context save/restore is taken
> > > care of only in the Idle path based on target power state and last
> > > power state respectively.
> >
> > OK, I didn't explain the problem I'm suspecting very well.  Imagine this
> > sequence of events:
> >
> > - mod_usage becomes zero
> > - pm_runtime_put_sync()
> > - gpio_bank_runtime_suspend()  [ no context is saved ]
> >   [ off-mode transition, context is lost]
> > - gpio_request()
> > - pm_runtime_get_sync()
> > - gpio_bank_runtime_resume()
> >
> > In this path, no context is saved, and no context is restored, which is
> > what I would expect, since there's no need to save context if nobody is
> > using that gpio bank anymore.   However, gpio_bank_runtime_resume() is
> > doing lots of reads/writes and read-modify-writes on GPIO bank registers
> > that may have undefined contents after a context loss.
> >

Agreed. This can be resolved by saving the Init configurations when a GPIO bank is released & restoring the same during GPIO bank request.

> > The point is that the GPIO register twiddling in
> > gpio_bank_runtime_resume() does not seem to be needed if there are no
> > users of that GPIO bank.
> >

Can you elaborate more?

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

* Re: [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class
  2010-08-12  7:49                               ` Basak, Partha
@ 2010-08-12 14:07                                 ` Kevin Hilman
  0 siblings, 0 replies; 38+ messages in thread
From: Kevin Hilman @ 2010-08-12 14:07 UTC (permalink / raw)
  To: Basak, Partha
  Cc: Varadarajan, Charulatha, linux-omap, paul, Cousson, Benoit,
	Nayak, Rajendra

"Basak, Partha" <p-basak2@ti.com> writes:

[...]

>> >>
>> >> Why is this better than passing the next power state?
>> >
>> > This would keep the GPIO function omap2_gpio_prepare_for_idle agnostic
>> of Power state definition dependencies.
>> >
>> 
>> And why is this better?
>> 
>> Personally, I think the GPIO code should be told about the powerdomain
>> state so it can make it's own decision about whether or not to save
>> context.
>> 
>
> I see your point. 
>
> But, in the approach we have followed so far, we are trying to
> localize all Power domain related logic and information in
> pm_34xxx.c. If we refer to all other such functions like
> omap_uart_prepare_idle(),omap3_intc_prepare_idle(),
> musb_context_save_restore()(newly introduced by USB patches for
> HWMOD), they are all following the same paradigm. None of these
> functions receive the Power state information as a parameter. The idea
> is to segregate the Power domain related information into the power
> layer.
>
> In omap2_gpio_prepare_for_idle() implementation, we are just being
> consistent with this approach.
>

Yes, you're following the existing approach, but the existing approach
is wrong, so I'm suggesting you change.  There was no common design for
any of these, and they all behave slightly differently.

For example, we should be passing the power state in the UART hook so
the UART code doesn't have to check 'enable_off_mode' to know whether or
not to save context.

IOW, instead of keeping the decision making centralized in the PM core,
we should just be notifiying the drivers about the state change.  The
idle loop is kept simple, and all the inteligence should be in the
drivers.

Also, the PM core should no be telling a module to save context.  It
should be notifying the module of a state change.  IOW, instead of
calling these functions save/restore context, they should be called
prepare/resume idle.

In the linux-pm community, there are increasing discussions on how to
combine CPUidle and runtime PM.  So in the medium term, we'll probably
be coming up with a more standard way for the idle path to notify
drivers using runtime PM.  Until that happens, all these prepare/resume
idle hooks are just temporary.

Kevin





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

* RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device
  2010-08-11  5:47                         ` Paul Walmsley
  2010-08-12 12:10                           ` Basak, Partha
@ 2010-08-23 15:46                           ` Basak, Partha
  1 sibling, 0 replies; 38+ messages in thread
From: Basak, Partha @ 2010-08-23 15:46 UTC (permalink / raw)
  To: Basak, Partha, Paul Walmsley
  Cc: Kevin Hilman, Varadarajan, Charulatha, linux-omap, Cousson,
	Benoit, Nayak, Rajendra



> -----Original Message-----
> From: Basak, Partha
> Sent: Thursday, August 12, 2010 5:35 PM
> To: 'Paul Walmsley'
> Cc: Kevin Hilman; Varadarajan, Charulatha; linux-omap@vger.kernel.org;
> Cousson, Benoit; Nayak, Rajendra
> Subject: RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform
> device
> 
> 
> 
> > -----Original Message-----
> > From: Paul Walmsley [mailto:paul@pwsan.com]
> > Sent: Wednesday, August 11, 2010 11:17 AM
> > To: Basak, Partha
> > Cc: Kevin Hilman; Varadarajan, Charulatha; linux-omap@vger.kernel.org;
> > Cousson, Benoit; Nayak, Rajendra
> > Subject: RE: [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform
> > device
> >
> > On Tue, 10 Aug 2010, Basak, Partha wrote:
> >
> > > As per our discussion with Paul & you during workshop, I believe,
> > > optional clock control should be done using clock APIs. So, I would go
> > > by your suggestion 1 of exposing an API to expose the optional clocks
> in
> > > the hwmod, something like:
> > >
> > > struct omap_hwmod_opt_clk * omap_hwmod_get_opt_clks(struct omap_hwmod
> > > *oh);
> > >
> > > If agreed, Charu will send updated patch.
> >
> > This should be done by modifying the hwmod code to call clk_add_alias()
> > for the clock names for the optional clocks.  I don't think any extra
> API
> > is needed.
> >
> 
> Lets see, if I got it right:
> 
> Refer to the OMAP3 hwmod data-base (omap_hwmod_3xxx.c):
> static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
> 	{ .role = "dbclk", .clk = "gpio1_dbck", },
> };
> Clock database(Clock3xxx_data.c):
> 	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
> 
> 
> Refer to the OMAP4 hwmod database(omap_hwmod_44xx.c):
> 	static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
> 		{ .role = "dbclk", .clk = "sys_32k_ck" },
> 
> Clock database(Clock44xx_data.c):
> 
> CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_443X),
> 
> 
> /*int clk_add_alias(const char *alias, const char *alias_dev_name, char
> *id,
> 	struct device *dev);*/
> 
> I believe, you are suggesting to do the following in the hwmod framework,
> say _setup(?):
> 
> clk_add_alias ( <gpio1_>opt_clks.role,
> 			 oh->od.pdev.name,
> 			<gpio1_>opt_clks.clk,
> 			NULL);
> 
> Then, from the driver, we can simply do a
> 	clk_get(dev_ptr,
> 			<role-->"dbclk">); /*hard-coded in the driver to be same
> 			as in the hwmod database*/
> 
Sent patch [PATCH] OMAP: HWMOD: Handle opt clocks using clk_add_alias.
 
> >
> > - Paul

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

end of thread, other threads:[~2010-08-23 15:47 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-06 12:34 [PATCH 00/13 v5] OMAP: GPIO: Implement GPIO in HWMOD way Charulatha V
2010-08-06 12:34 ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Charulatha V
2010-08-06 12:34   ` [PATCH 02/13 v5] OMAP: GPIO: Introduce support for OMAP15xx chip GPIO init Charulatha V
2010-08-06 12:34     ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " Charulatha V
2010-08-06 12:34       ` [PATCH 04/13 v5] OMAP: GPIO: Introduce support for OMAP7xx " Charulatha V
2010-08-06 12:34         ` [PATCH 05/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP3 Charulatha V
2010-08-06 12:34           ` [PATCH 06/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP242X Charulatha V
2010-08-06 12:34             ` [PATCH 07/13 v5] OMAP: GPIO: add GPIO hwmods structures for OMAP243X Charulatha V
2010-08-06 12:34               ` [PATCH 08/13 v5] OMAP: GPIO: Add gpio dev_attr and correct clks in OMAP4 hwmod struct Charulatha V
2010-08-06 12:34                 ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Charulatha V
2010-08-06 12:34                   ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Charulatha V
2010-08-06 12:34                     ` [PATCH 11/13 v5] OMAP: GPIO: Make gpio_context as part of gpio_bank structure Charulatha V
2010-08-06 12:34                       ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Charulatha V
2010-08-06 12:34                         ` [PATCH 13/13 v5] OMAP: GPIO: Remove omap_gpio_init() Charulatha V
2010-08-09 23:00                           ` Kevin Hilman
2010-08-10  5:22                             ` Varadarajan, Charulatha
2010-08-09 21:45                         ` [PATCH 12/13 v5] OMAP: GPIO: Use dev_pm_ops instead of sys_dev_class Kevin Hilman
2010-08-10  0:21                         ` Kevin Hilman
2010-08-10 12:37                           ` Basak, Partha
2010-08-10 18:10                             ` Kevin Hilman
2010-08-12  7:49                               ` Basak, Partha
2010-08-12 14:07                                 ` Kevin Hilman
2010-08-12 12:43                           ` Basak, Partha
2010-08-09 23:06                     ` [PATCH 10/13 v5] OMAP: GPIO: Implement GPIO as a platform device Kevin Hilman
2010-08-10 11:53                       ` Basak, Partha
2010-08-10 17:59                         ` Kevin Hilman
2010-08-11  5:47                         ` Paul Walmsley
2010-08-12 12:10                           ` Basak, Partha
2010-08-23 15:46                           ` Basak, Partha
2010-08-09 23:58                   ` [PATCH 09/13 v5] OMAP: GPIO: Introduce support for OMAP2PLUS chip GPIO init Kevin Hilman
2010-08-10  5:56                     ` Varadarajan, Charulatha
2010-08-10  0:21                   ` Kevin Hilman
2010-08-09  3:51       ` [PATCH 03/13 v5] OMAP: GPIO: Introduce support for OMAP16xx " DebBarma, Tarun Kanti
2010-08-09 22:20   ` [PATCH 01/13 v5] OMAP: GPIO: Modify init() in preparation for platform device implementation Kevin Hilman
2010-08-10  5:18     ` Varadarajan, Charulatha
2010-08-10  7:20       ` Basak, Partha
2010-08-10 10:44         ` Cousson, Benoit
2010-08-10 11:31           ` Basak, Partha

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.