All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
@ 2010-04-22 15:55 Charulatha V
  2010-04-22 15:55 ` [PATCH 1/9] OMAP:GPIO: Modify init() in preparation for platform device implementation Charulatha V
  2010-05-07  6:57 ` [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Varadarajan, Charulatha
  0 siblings, 2 replies; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

This patch series implements GPIO as an early platform driver.
It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
OMAP1 specific GPIO is implemented as early platform device.

This patch series is created on "origin/pm-wip/hwmods". In addition,
the following patches are required to avoid compilation and
boottime errors:
1. i2c-omap: Fix reg_shift init (by Tony Lindgren)
2. OMAP:GPIO:hwmod: Fix mmc compile errors (by Charulatha V)
3. OMAP: DSS2: VRAM: Fix early_param for vram (by Thomas Weber)

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

Charulatha V (9):
  OMAP:GPIO: Modify init() in preparation for platform device
    implementation
  OMAP:GPIO: Introduce support for OMAP15xx chip specific GPIO
  OMAP:GPIO: Introduce support for OMAP16xx chip specific GPIO
  OMAP:GPIO: Introduce support for OMAP7xx chip specific GPIO
  OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3
  OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420
  OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2430
  OMAP:GPIO: Implement GPIO as a platform device

 arch/arm/mach-omap1/Makefile               |    6 +
 arch/arm/mach-omap1/clock_data.c           |    2 +-
 arch/arm/mach-omap1/gpio15xx.c             |  102 +++++
 arch/arm/mach-omap1/gpio16xx.c             |  196 +++++++++
 arch/arm/mach-omap1/gpio7xx.c              |  258 +++++++++++
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/clock2420_data.c       |   10 +-
 arch/arm/mach-omap2/clock2430_data.c       |   14 +-
 arch/arm/mach-omap2/clock3xxx_data.c       |   24 +-
 arch/arm/mach-omap2/clock44xx_data.c       |   24 +-
 arch/arm/mach-omap2/gpio.c                 |  101 +++++
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  215 ++++++++++
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  262 ++++++++++++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  346 +++++++++++++++-
 arch/arm/plat-omap/gpio.c                  |  640 +++++++++++-----------------
 arch/arm/plat-omap/include/plat/gpio.h     |   89 ++++-
 16 files changed, 1863 insertions(+), 428 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] 33+ messages in thread

* [PATCH 1/9] OMAP:GPIO: Modify init() in preparation for platform device implementation
  2010-04-22 15:55 [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Charulatha V
@ 2010-04-22 15:55 ` Charulatha V
  2010-04-22 15:55   ` [PATCH 2/9] OMAP:GPIO: Introduce support for OMAP15xx chip specific GPIO Charulatha V
  2010-05-07  6:57 ` [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Varadarajan, Charulatha
  1 sibling, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

This is in prepartion for making GPIO an early platform device.
For making GPIO an early 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>
---
 arch/arm/plat-omap/gpio.c              |  277 ++++++++++++++------------------
 arch/arm/plat-omap/include/plat/gpio.h |   68 ++++++++-
 2 files changed, 185 insertions(+), 160 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 76a347b..c8f2c3c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -31,7 +31,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
@@ -40,15 +39,9 @@
 #define OMAP1510_GPIO_INT_STATUS	0x14
 #define OMAP1510_GPIO_PIN_CONTROL	0x18
 
-#define OMAP1510_IH_GPIO_BASE		64
-
 /*
  * 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
@@ -70,12 +63,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
@@ -83,22 +70,9 @@
 #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
@@ -150,26 +124,6 @@
 #define OMAP4_GPIO_DEBOUNCINGTIME	0x0154
 #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;
@@ -181,14 +135,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;
@@ -1669,6 +1621,122 @@ 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()) {
+		static const u32 non_wakeup_gpios[] = {
+			0xe203ffc0, 0x08700040
+		};
+		if (id < ARRAY_SIZE(non_wakeup_gpios))
+			bank->non_wakeup_gpios = non_wakeup_gpios[id];
+
+		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())
+			/* 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, gpio_bank_bits = 16;
+	static int gpio;
+
+	if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
+		gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
+
+	if ((bank->method == METHOD_GPIO_24XX) ||
+			(bank->method == METHOD_GPIO_44XX))
+		gpio_bank_bits = 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 = 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_bank_bits;
+	}
+	bank->chip.ngpio = gpio_bank_bits;
+
+	gpiochip_add(&bank->chip);
+
+	for (j = bank->virtual_irq_start;
+		     j < bank->virtual_irq_start + gpio_bank_bits; 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;
@@ -1779,7 +1847,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);
@@ -1791,105 +1858,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 (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 = 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);
@@ -1899,17 +1869,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;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index de7c547..a06acb6 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -29,7 +29,8 @@
 #include <linux/io.h>
 #include <mach/irqs.h>
 
-#define OMAP1_MPUIO_BASE			0xfffb5000
+#define OMAP1_MPUIO_BASE		0xfffb5000
+#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 
 #if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
 
@@ -62,8 +63,73 @@
 #define OMAP_MPUIO_LATCH		0x34
 #endif
 
+/*
+ * OMAP1510 GPIO base addresses
+ */
+#define OMAP1510_GPIO_BASE		0xfffce000
+#define OMAP1510_IH_GPIO_BASE		64
+
+/*
+ * OMAP1610 GPIO base addresses
+ */
+#define OMAP1610_GPIO1_BASE		0xfffbe400
+#define OMAP1610_GPIO2_BASE		0xfffbec00
+#define OMAP1610_GPIO3_BASE		0xfffbb400
+#define OMAP1610_GPIO4_BASE		0xfffbbc00
+
+/*
+ * OMAP7XX GPIO base addresses
+ */
+#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
+
+/*
+ * omap24xx GPIO base addresses
+ */
+#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
+
+/*
+ * omap34xx GPIO base addresses
+ */
+#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
+
 #define OMAP34XX_NR_GPIOS		6
 
+/*
+ * OMAP44XX GPIO base addresses
+ */
+#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
+
+#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
+
 #define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
 
-- 
1.6.3.3


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

* [PATCH 2/9] OMAP:GPIO: Introduce support for OMAP15xx chip specific GPIO
  2010-04-22 15:55 ` [PATCH 1/9] OMAP:GPIO: Modify init() in preparation for platform device implementation Charulatha V
@ 2010-04-22 15:55   ` Charulatha V
  2010-04-22 15:55     ` [PATCH 3/9] OMAP:GPIO: Introduce support for OMAP16xx " Charulatha V
  0 siblings, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

This patch 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>
---
 arch/arm/mach-omap1/gpio15xx.c |  102 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 102 insertions(+), 0 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..99c4017
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -0,0 +1,102 @@
+/*
+ * gpio15xx.c - 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>
+
+/*
+ * 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,
+	.method	= METHOD_MPUIO,
+};
+
+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,
+	.method	= METHOD_GPIO_1510,
+};
+
+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,
+};
+
+static struct __initdata platform_device * omap15xx_gpio_dev[] = {
+	&omap15xx_mpu_gpio,
+	&omap15xx_gpio,
+};
+
+int __init omap15xx_gpio_init(void)
+{
+	if (cpu_is_omap15xx()) {
+		early_platform_add_devices(omap15xx_gpio_dev,
+						sizeof(omap15xx_gpio_dev));
+		early_platform_driver_register_all("earlygpio");
+		early_platform_driver_probe("earlygpio",
+						sizeof(omap15xx_gpio_dev), 0);
+	}
+	return 0;
+}
+
+int __init omap15xx_gpio_dev_reg(void)
+{
+	if (cpu_is_omap15xx()) {
+		platform_device_register(&omap15xx_mpu_gpio);
+		platform_device_register(&omap15xx_gpio);
+	}
+
+	return 0;
+}
+arch_initcall(omap15xx_gpio_dev_reg);
-- 
1.6.3.3


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

* [PATCH 3/9] OMAP:GPIO: Introduce support for OMAP16xx chip specific GPIO
  2010-04-22 15:55   ` [PATCH 2/9] OMAP:GPIO: Introduce support for OMAP15xx chip specific GPIO Charulatha V
@ 2010-04-22 15:55     ` Charulatha V
  2010-04-22 15:55       ` [PATCH 4/9] OMAP:GPIO: Introduce support for OMAP7xx " Charulatha V
  0 siblings, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

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>
---
 arch/arm/mach-omap1/gpio16xx.c |  196 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 196 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..c047d1d
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -0,0 +1,196 @@
+/*
+ * gpio16xx.c - 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>
+
+/*
+ * 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,
+	.method	= METHOD_MPUIO,
+};
+
+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,
+	.method	= METHOD_GPIO_1610,
+};
+
+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,
+	.method	= METHOD_GPIO_1610,
+};
+
+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,
+	.method	= METHOD_GPIO_1610,
+};
+
+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,
+	.method	= METHOD_GPIO_1610,
+};
+
+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,
+};
+
+int __init omap16xx_gpio_init(void)
+{
+	if (cpu_is_omap16xx()) {
+		early_platform_add_devices(omap16xx_gpio_dev,
+					sizeof(omap16xx_gpio_dev));
+		early_platform_driver_register_all("earlygpio");
+		early_platform_driver_probe("earlygpio",
+					sizeof(omap16xx_gpio_dev), 0);
+	}
+	return 0;
+}
+
+int __init omap16xx_gpio_dev_reg(void)
+{
+	if (cpu_is_omap16xx()) {
+		int i;
+
+		for (i = 0; i < sizeof(omap16xx_gpio_dev); i++)
+			platform_device_register(omap16xx_gpio_dev[i]);
+	}
+	return 0;
+}
+arch_initcall(omap16xx_gpio_dev_reg);
-- 
1.6.3.3


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

* [PATCH 4/9] OMAP:GPIO: Introduce support for OMAP7xx chip specific GPIO
  2010-04-22 15:55     ` [PATCH 3/9] OMAP:GPIO: Introduce support for OMAP16xx " Charulatha V
@ 2010-04-22 15:55       ` Charulatha V
  2010-04-22 15:55         ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS " Charulatha V
  0 siblings, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

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>
---
 arch/arm/mach-omap1/gpio7xx.c |  258 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 258 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..3cf1d54
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -0,0 +1,258 @@
+/*
+ * gpio7xx.c - 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>
+
+/*
+ * 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,
+	.method	= METHOD_MPUIO,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+	.method	= METHOD_GPIO_7XX,
+};
+
+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,
+};
+
+int __init omap7xx_gpio_init(void)
+{
+	if (cpu_is_omap7xx()) {
+		early_platform_add_devices(omap7xx_gpio_dev,
+						sizeof(omap7xx_gpio_dev));
+		early_platform_driver_register_all("earlygpio");
+		early_platform_driver_probe("earlygpio",
+						sizeof(omap7xx_gpio_dev), 0);
+	}
+	return 0;
+}
+
+int __init omap7xx_gpio_dev_reg(void)
+{
+	if (cpu_is_omap7xx()) {
+		int i;
+
+		for (i = 0; i < sizeof(omap7xx_gpio_dev); i++)
+			platform_device_register(omap7xx_gpio_dev[i]);
+	}
+	return 0;
+}
+arch_initcall(omap7xx_gpio_dev_reg);
-- 
1.6.3.3


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

* [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-04-22 15:55       ` [PATCH 4/9] OMAP:GPIO: Introduce support for OMAP7xx " Charulatha V
@ 2010-04-22 15:55         ` Charulatha V
  2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
                             ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

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

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap2/gpio.c |  101 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 101 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..6424050
--- /dev/null
+++ b/arch/arm/mach-omap2/gpio.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static int gpio_bank_count;
+
+struct omap_device_pm_latency omap_gpio_latency[] = {
+	[0] = {
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func   = omap_device_enable_hwmods,
+		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	},
+};
+
+int __init gpio_init(void)
+{
+	int i = 0;
+	static int is_early_device = true;
+
+	do {
+		struct omap_device *od;
+		struct omap_hwmod *oh;
+		int hw_mod_name_len = 16;
+		int l;
+		char oh_name[hw_mod_name_len];
+		struct omap_gpio_platform_data *pdata;
+		char *name = "omap-gpio";
+
+		l = snprintf(oh_name, hw_mod_name_len, "gpio%d_hwmod", i + 1);
+		WARN(l >= hw_mod_name_len,
+			"String buffer overflow in GPIO device setup\n");
+
+		oh = omap_hwmod_lookup(oh_name);
+		if (!oh) {
+			pr_err("Could not look up %s\n", oh_name);
+			i++;
+			continue;
+		}
+
+		pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
+					GFP_KERNEL);
+		if (!pdata) {
+			pr_err("Memory allocation failed gpio%d\n", i + 1);
+			return -ENOMEM;
+		}
+		pdata->base = oh->_rt_va;
+		pdata->irq = oh->mpu_irqs[0].irq;
+		if (cpu_is_omap24xx() || cpu_is_omap34xx())
+			pdata->method = METHOD_GPIO_24XX;
+		if (cpu_is_omap44xx())
+			pdata->method = METHOD_GPIO_44XX;
+		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
+		pdata->device_enable = omap_device_enable;
+		pdata->device_idle = omap_device_idle;
+		pdata->device_shutdown = omap_device_shutdown;
+
+		od = omap_device_build(name, i, oh, pdata,
+					sizeof(*pdata),	omap_gpio_latency,
+					ARRAY_SIZE(omap_gpio_latency),
+					is_early_device);
+		WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
+					name, oh->name);
+
+		i++;
+	} while (i < gpio_bank_count);
+	is_early_device = false;
+
+	return 0;
+}
+arch_initcall(gpio_init);
+
+int __init omap2_gpio_init(void)
+{
+	if (cpu_is_omap242x())
+		gpio_bank_count = 4;
+	else if (cpu_is_omap243x())
+		gpio_bank_count = 5;
+	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
+		gpio_bank_count = OMAP34XX_NR_GPIOS;
+
+	if (gpio_init())
+		return -EINVAL;
+
+	early_platform_driver_register_all("earlygpio");
+	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
+	return 0;
+}
-- 
1.6.3.3


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

* [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3
  2010-04-22 15:55         ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS " Charulatha V
@ 2010-04-22 15:55           ` Charulatha V
  2010-04-22 15:55             ` [PATCH 7/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420 Charulatha V
  2010-05-20 10:13             ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Benoit Cousson
  2010-04-30 23:03           ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO Kevin Hilman
  2010-05-05 22:31           ` Tony Lindgren
  2 siblings, 2 replies; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

Add hwmod structures for GPIO module on OMAP3

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

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5f74c34..6124d62 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -20,6 +20,7 @@
 #include <plat/serial.h>
 #include <plat/l4_3xxx.h>
 #include <plat/mmc.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -89,6 +90,12 @@ static struct omap_hwmod omap3xxx_uart3_hwmod;
 static struct omap_hwmod omap3xxx_mmc1_hwmod;
 static struct omap_hwmod omap3xxx_mmc2_hwmod;
 static struct omap_hwmod omap3xxx_mmc3_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;
 
 /* L4_CORE -> L4_WKUP interface */
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
@@ -226,6 +233,114 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc3 = {
 	.flags		= OMAP_FIREWALL_L4
 };
 
+/* L4 WKUP -> GPIO1 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio1_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO1_BASE,
+		.pa_end		= OMAP34XX_GPIO1_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio1_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO2 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio2_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO2_BASE,
+		.pa_end		= OMAP34XX_GPIO2_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio2_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO3 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio3_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO3_BASE,
+		.pa_end		= OMAP34XX_GPIO3_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio3_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO4 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio4_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO4_BASE,
+		.pa_end		= OMAP34XX_GPIO4_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio4_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO5 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio5_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO5_BASE,
+		.pa_end		= OMAP34XX_GPIO5_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio5_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> GPIO6 interface */
+static struct omap_hwmod_addr_space omap3xxx_gpio6_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_GPIO6_BASE,
+		.pa_end		= OMAP34XX_GPIO6_BASE + SZ_4K - 1,
+		.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_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio6_addr_space),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
 	&omap3xxx_l3__l4_core,
@@ -257,6 +372,11 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
 /* Master interfaces on the L4_PER interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
 	&omap3_l4_per__uart3,
+	&omap3xxx_l4_per__gpio2,
+	&omap3xxx_l4_per__gpio3,
+	&omap3xxx_l4_per__gpio4,
+	&omap3xxx_l4_per__gpio5,
+	&omap3xxx_l4_per__gpio6,
 };
 
 /* L4 PER */
@@ -273,10 +393,12 @@ static struct omap_hwmod omap3xxx_l4_per_hwmod = {
 /* Slave interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_slaves[] = {
 	&omap3xxx_l4_core__l4_wkup,
+	&omap3xxx_l4_wkup__gpio1,
 };
 
 /* Master interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
+	&omap3xxx_l4_wkup__gpio1,
 };
 
 /* L4 WKUP */
@@ -442,7 +564,6 @@ static struct omap_hwmod_class mmc_class = {
 	.sysc = &mmc_sysc,
 };
 
-
 /* MMC/SD/SDIO1 */
 
 static struct mmc_dev_attr mmc1_dev_attr = {
@@ -576,6 +697,223 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/* GPIO common */
+
+static struct omap_hwmod_class_sysconfig gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class gpio_class = {
+	.name = "gpio",
+	.sysc = &gpio_sysc,
+};
+
+/* GPIO1 */
+
+static struct omap_hwmod_irq_info gpio1_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK1 },
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+	{ .role = "gpio1_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_hwmod",
+	.mpu_irqs	= gpio1_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio1_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio1_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info gpio2_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK2 },
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+	{ .role = "gpio2_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_hwmod",
+	.mpu_irqs	= gpio2_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio2_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio2_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info gpio3_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK3 },
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+	{ .role = "gpio3_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_hwmod",
+	.mpu_irqs	= gpio3_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio3_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio3_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info gpio4_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK4 },
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+	{ .role = "gpio4_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_hwmod",
+	.mpu_irqs	= gpio4_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio4_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio4_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+
+/* GPIO5 */
+
+static struct omap_hwmod_irq_info gpio5_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK5 },
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+	{ .role = "gpio5_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_hwmod",
+	.mpu_irqs	= gpio5_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio5_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio5_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio5_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* GPIO6 */
+
+static struct omap_hwmod_irq_info gpio6_mpu_irqs[] = {
+	{ .name = "gpio_mpu_irq", .irq = INT_34XX_GPIO_BANK6 },
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+	{ .role = "gpio6_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_hwmod",
+	.mpu_irqs	= gpio6_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio6_mpu_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,
+		},
+	},
+	.slaves		= omap3xxx_gpio6_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio6_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -588,6 +926,12 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_mmc1_hwmod,
 	&omap3xxx_mmc2_hwmod,
 	&omap3xxx_mmc3_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] 33+ messages in thread

* [PATCH 7/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420
  2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
@ 2010-04-22 15:55             ` Charulatha V
  2010-04-22 15:55               ` [PATCH 8/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2430 Charulatha V
  2010-05-20 10:13             ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Benoit Cousson
  1 sibling, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

Add hwmod structures for GPIO module on OMAP2420.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  215 ++++++++++++++++++++++++++++
 1 files changed, 215 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 eb7ee24..b3fe521 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"
 
@@ -32,6 +33,10 @@
 static struct omap_hwmod omap2420_mpu_hwmod;
 static struct omap_hwmod omap2420_l3_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__l4_core = {
@@ -87,6 +92,78 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
 	&omap2420_l4_core__l4_wkup,
 };
 
+/* L4 WKUP -> GPIO1 interface */
+static struct omap_hwmod_addr_space omap2420_gpio1_addr_space[] = {
+	{
+		.pa_start	= OMAP242X_GPIO1_BASE,
+		.pa_end		= OMAP242X_GPIO1_BASE + SZ_4K - 1,
+		.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	= OMAP242X_GPIO2_BASE,
+		.pa_end		= OMAP242X_GPIO2_BASE + SZ_4K - 1,
+		.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	= OMAP242X_GPIO3_BASE,
+		.pa_end		= OMAP242X_GPIO3_BASE + SZ_4K - 1,
+		.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	= OMAP242X_GPIO4_BASE,
+		.pa_end		= OMAP242X_GPIO4_BASE + SZ_4K - 1,
+		.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,
+};
+
 /* L4 CORE */
 static struct omap_hwmod omap2420_l4_core_hwmod = {
 	.name		= "l4_core_hwmod",
@@ -101,10 +178,18 @@ static struct omap_hwmod omap2420_l4_core_hwmod = {
 /* Slave interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
 	&omap2420_l4_core__l4_wkup,
+	&omap2420_l4_wkup__gpio1,
+	&omap2420_l4_wkup__gpio2,
+	&omap2420_l4_wkup__gpio3,
+	&omap2420_l4_wkup__gpio4,
 };
 
 /* Master interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
+	&omap2420_l4_wkup__gpio1,
+	&omap2420_l4_wkup__gpio2,
+	&omap2420_l4_wkup__gpio3,
+	&omap2420_l4_wkup__gpio4,
 };
 
 /* L4 WKUP */
@@ -133,11 +218,141 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
 };
 
+/* GPIO common */
+
+static struct omap_hwmod_class_sysconfig gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class gpio_class = {
+	.name = "gpio",
+	.sysc = &gpio_sysc,
+};
+
+/* GPIO1 */
+
+static struct omap_hwmod_irq_info gpio1_mpu_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_hwmod",
+	.mpu_irqs	= gpio1_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio1_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio1_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info gpio2_mpu_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_hwmod",
+	.mpu_irqs	= gpio2_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio2_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio2_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info gpio3_mpu_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_hwmod",
+	.mpu_irqs	= gpio3_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio3_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio3_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info gpio4_mpu_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_hwmod",
+	.mpu_irqs	= gpio4_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio4_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2420_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio4_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
 static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_l3_hwmod,
 	&omap2420_l4_core_hwmod,
 	&omap2420_l4_wkup_hwmod,
 	&omap2420_mpu_hwmod,
+	&omap2420_gpio1_hwmod,
+	&omap2420_gpio2_hwmod,
+	&omap2420_gpio3_hwmod,
+	&omap2420_gpio4_hwmod,
 	NULL,
 };
 
-- 
1.6.3.3


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

* [PATCH 8/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2430
  2010-04-22 15:55             ` [PATCH 7/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420 Charulatha V
@ 2010-04-22 15:55               ` Charulatha V
  2010-04-22 15:55                 ` [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device Charulatha V
  0 siblings, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

Add hwmod structures for GPIO module on OMAP2430.

Signed-off-by: Charulatha V <charu@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  262 ++++++++++++++++++++++++++++
 1 files changed, 262 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 d9c92aa..585ff21 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -16,6 +16,7 @@
 #include <plat/cpu.h>
 #include <plat/dma.h>
 #include <plat/mmc.h>
+#include <plat/gpio.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -73,6 +74,11 @@ static struct omap_hwmod omap2430_l3_hwmod = {
 static struct omap_hwmod omap2430_l4_wkup_hwmod;
 static struct omap_hwmod omap2430_mmc1_hwmod;
 static struct omap_hwmod omap2430_mmc2_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;
 
 /* L4_CORE -> L4_WKUP interface */
 static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -117,6 +123,95 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* L4 WKUP -> GPIO1 interface */
+static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = {
+	{
+		.pa_start	= OMAP243X_GPIO1_BASE,
+		.pa_end		= OMAP243X_GPIO1_BASE + SZ_4K - 1,
+		.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	= OMAP243X_GPIO2_BASE,
+		.pa_end		= OMAP243X_GPIO2_BASE + SZ_4K - 1,
+		.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	= OMAP243X_GPIO3_BASE,
+		.pa_end		= OMAP243X_GPIO3_BASE + SZ_4K - 1,
+		.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	= OMAP243X_GPIO4_BASE,
+		.pa_end		= OMAP243X_GPIO4_BASE + SZ_4K - 1,
+		.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	= OMAP243X_GPIO5_BASE,
+		.pa_end		= OMAP243X_GPIO5_BASE + SZ_4K - 1,
+		.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,
+};
 
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
@@ -128,6 +223,7 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
 	&omap2430_l4_core__l4_wkup,
 	&omap2430_l4_core__mmc1,
 	&omap2430_l4_core__mmc2,
+	&omap2430_l4_core__gpio5,
 };
 
 /* L4 CORE */
@@ -144,10 +240,18 @@ static struct omap_hwmod omap2430_l4_core_hwmod = {
 /* Slave interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
 	&omap2430_l4_core__l4_wkup,
+	&omap2430_l4_wkup__gpio1,
+	&omap2430_l4_wkup__gpio2,
+	&omap2430_l4_wkup__gpio3,
+	&omap2430_l4_wkup__gpio4,
 };
 
 /* Master interfaces on the L4_WKUP interconnect */
 static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
+	&omap2430_l4_wkup__gpio1,
+	&omap2430_l4_wkup__gpio2,
+	&omap2430_l4_wkup__gpio3,
+	&omap2430_l4_wkup__gpio4,
 };
 
 /* L4 WKUP */
@@ -283,11 +387,169 @@ static struct omap_hwmod omap2430_mmc2_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
+/* GPIO common */
+
+static struct omap_hwmod_class_sysconfig gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+			   SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class gpio_class = {
+	.name = "gpio",
+	.sysc = &gpio_sysc,
+};
+
+/* GPIO1 */
+
+static struct omap_hwmod_irq_info gpio1_mpu_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_hwmod",
+	.mpu_irqs	= gpio1_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio1_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio1_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO2 */
+
+static struct omap_hwmod_irq_info gpio2_mpu_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_hwmod",
+	.mpu_irqs	= gpio2_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio2_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio2_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO3 */
+
+static struct omap_hwmod_irq_info gpio3_mpu_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_hwmod",
+	.mpu_irqs	= gpio3_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio3_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio3_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO4 */
+
+static struct omap_hwmod_irq_info gpio4_mpu_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_hwmod",
+	.mpu_irqs	= gpio4_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio4_mpu_irqs),
+	.main_clk	= "gpios_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio4_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* GPIO5 */
+
+static struct omap_hwmod_irq_info gpio5_mpu_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_hwmod",
+	.mpu_irqs	= gpio5_mpu_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(gpio5_mpu_irqs),
+	.main_clk	= "gpio5_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+		},
+	},
+	.slaves		= omap2430_gpio5_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio5_slaves),
+	.class		= &gpio_class,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
 static __initdata struct omap_hwmod *omap2430_hwmods[] = {
 	&omap2430_l3_hwmod,
 	&omap2430_l4_core_hwmod,
 	&omap2430_l4_wkup_hwmod,
 	&omap2430_mpu_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] 33+ messages in thread

* [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-04-22 15:55               ` [PATCH 8/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2430 Charulatha V
@ 2010-04-22 15:55                 ` Charulatha V
  2010-05-01  0:04                   ` Kevin Hilman
  0 siblings, 1 reply; 33+ messages in thread
From: Charulatha V @ 2010-04-22 15:55 UTC (permalink / raw)
  To: linux-omap; +Cc: rnayak, paul, tony, khilman, Charulatha V

This patch implements GPIO as a early platform device. Also it
implements OMAP2PLUS specific GPIO as HWMOD FW adapted driver.

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

Currently early platform device register does not do device_pm_init.
Hence pm_runtime functions are not used to enable the GPIO device
since gpio is early platform device.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap1/Makefile           |    6 +
 arch/arm/mach-omap1/clock_data.c       |    2 +-
 arch/arm/mach-omap2/Makefile           |    2 +-
 arch/arm/mach-omap2/clock2420_data.c   |   10 +-
 arch/arm/mach-omap2/clock2430_data.c   |   14 +-
 arch/arm/mach-omap2/clock3xxx_data.c   |   24 +-
 arch/arm/mach-omap2/clock44xx_data.c   |   24 +-
 arch/arm/plat-omap/gpio.c              |  405 ++++++++++++--------------------
 arch/arm/plat-omap/include/plat/gpio.h |   21 ++
 9 files changed, 220 insertions(+), 288 deletions(-)

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index b6a537c..dabd2be 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -45,6 +45,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 aa8558a..9bc2aa1 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -589,7 +589,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", "arm_gpio_ck", &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 4b9fc57..6bb8042 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
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o gpio.o
 
 omap-2-3-common				= irq.o sdrc.o
 hwmod-common				= omap_hwmod.o \
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index d932b14..a693403 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1802,8 +1802,14 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_242X),
 	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_242X),
 	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_242X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_242X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
+	CLK("omap-gpio.0",	"ick",	&gpios_ick,	CK_242X),
+	CLK("omap-gpio.1",	"ick",	&gpios_ick,	CK_242X),
+	CLK("omap-gpio.2",	"ick",	&gpios_ick,	CK_242X),
+	CLK("omap-gpio.3",	"ick",	&gpios_ick,	CK_242X),
+	CLK("omap-gpio.0",	"fck",	&gpios_fck,	CK_242X),
+	CLK("omap-gpio.1",	"fck",	&gpios_fck,	CK_242X),
+	CLK("omap-gpio.2",	"fck",	&gpios_fck,	CK_242X),
+	CLK("omap-gpio.3",	"fck",	&gpios_fck,	CK_242X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_242X),
 	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 0438b6e..56bbcbc 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1896,8 +1896,14 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X),
 	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X),
 	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
+	CLK("omap-gpio.0",	"ick",	&gpios_ick,	CK_243X),
+	CLK("omap-gpio.1",	"ick",	&gpios_ick,	CK_243X),
+	CLK("omap-gpio.2",	"ick",	&gpios_ick,	CK_243X),
+	CLK("omap-gpio.3",	"ick",	&gpios_ick,	CK_243X),
+	CLK("omap-gpio.0",	"fck",	&gpios_fck,	CK_243X),
+	CLK("omap-gpio.1",	"fck",	&gpios_fck,	CK_243X),
+	CLK("omap-gpio.2",	"fck",	&gpios_fck,	CK_243X),
+	CLK("omap-gpio.3",	"fck",	&gpios_fck,	CK_243X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X),
 	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
@@ -1934,8 +1940,8 @@ static struct omap_clk omap2430_clks[] = {
 	CLK("mmci-omap-hs.0", "fck",	&mmchs1_fck,	CK_243X),
 	CLK("mmci-omap-hs.1", "ick",	&mmchs2_ick,	CK_243X),
 	CLK("mmci-omap-hs.1", "fck",	&mmchs2_fck,	CK_243X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
-	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
+	CLK("omap-gpio.4",	"ick",	&gpio5_ick,	CK_243X),
+	CLK("omap-gpio.4",	"fck",	&gpio5_fck,	CK_243X),
 	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
 	CLK("mmci-omap-hs.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
 	CLK("mmci-omap-hs.1", "mmchsdb_fck", 	&mmchsdb2_fck,	CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index d5153b6..9efbaac 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3407,13 +3407,13 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
 	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
-	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
+	CLK("omap-gpio.0",	"dbck",	&gpio1_dbck,	CK_3XXX),
 	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_3XXX),
 	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_343X),
 	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2),
 	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
-	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
+	CLK("omap-gpio.0",	"ick",	&gpio1_ick,	CK_3XXX),
 	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
 	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
@@ -3429,18 +3429,18 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_3XXX),
 	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_3XXX),
 	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
-	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_3XXX),
+	CLK("omap-gpio.5",	"dbck",	&gpio6_dbck,	CK_3XXX),
+	CLK("omap-gpio.4",	"dbck",	&gpio5_dbck,	CK_3XXX),
+	CLK("omap-gpio.3",	"dbck",	&gpio4_dbck,	CK_3XXX),
+	CLK("omap-gpio.2",	"dbck",	&gpio3_dbck,	CK_3XXX),
+	CLK("omap-gpio.1",	"dbck",	&gpio2_dbck,	CK_3XXX),
 	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_3XXX),
 	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_3XXX),
-	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_3XXX),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_3XXX),
-	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_3XXX),
-	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_3XXX),
-	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_3XXX),
+	CLK("omap-gpio.5",	"ick",	&gpio6_ick,	CK_3XXX),
+	CLK("omap-gpio.4",	"ick",	&gpio5_ick,	CK_3XXX),
+	CLK("omap-gpio.3",	"ick",	&gpio4_ick,	CK_3XXX),
+	CLK("omap-gpio.2",	"ick",	&gpio3_ick,	CK_3XXX),
+	CLK("omap-gpio.1",	"ick",	&gpio2_ick,	CK_3XXX),
 	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_3XXX),
 	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_3XXX),
 	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 28b1079..1cfb323 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -2566,12 +2566,12 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"fdif_fck",			&fdif_fck,	CK_443X),
 	CLK(NULL,	"per_sgx_fclk",			&per_sgx_fclk,	CK_443X),
 	CLK(NULL,	"gfx_fck",			&gfx_fck,	CK_443X),
-	CLK(NULL,	"gpio1_ick",			&gpio1_ick,	CK_443X),
-	CLK(NULL,	"gpio2_ick",			&gpio2_ick,	CK_443X),
-	CLK(NULL,	"gpio3_ick",			&gpio3_ick,	CK_443X),
-	CLK(NULL,	"gpio4_ick",			&gpio4_ick,	CK_443X),
-	CLK(NULL,	"gpio5_ick",			&gpio5_ick,	CK_443X),
-	CLK(NULL,	"gpio6_ick",			&gpio6_ick,	CK_443X),
+	CLK("omap-gpio.0",	"ick",			&gpio1_ick,	CK_443X),
+	CLK("omap-gpio.1",	"ick",			&gpio2_ick,	CK_443X),
+	CLK("omap-gpio.2",	"ick",			&gpio3_ick,	CK_443X),
+	CLK("omap-gpio.3",	"ick",			&gpio4_ick,	CK_443X),
+	CLK("omap-gpio.4",	"ick",			&gpio5_ick,	CK_443X),
+	CLK("omap-gpio.5",	"ick",			&gpio6_ick,	CK_443X),
 	CLK(NULL,	"gpmc_ick",			&gpmc_ick,	CK_443X),
 	CLK(NULL,	"gpt1_fck",			&gpt1_fck,	CK_443X),
 	CLK(NULL,	"gpt10_fck",			&gpt10_fck,	CK_443X),
@@ -2645,12 +2645,12 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
 	CLK(NULL,	"utmi_p1_gfclk_ck",		&utmi_p1_gfclk_ck,	CK_443X),
 	CLK(NULL,	"utmi_p2_gfclk_ck",		&utmi_p2_gfclk_ck,	CK_443X),
-	CLK(NULL,	"gpio1_dbck",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"gpio2_dbck",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"gpio3_dbck",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"gpio4_dbck",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"gpio5_dbck",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"gpio6_dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.0",	"dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.1",	"dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.2",	"dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.3",	"dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.4",	"dbck",			&dummy_ck,	CK_443X),
+	CLK("omap-gpio.5",	"dbck",			&dummy_ck,	CK_443X),
 	CLK(NULL,	"gpmc_ck",			&dummy_ck,	CK_443X),
 	CLK(NULL,	"gpt1_ick",			&dummy_ck,	CK_443X),
 	CLK(NULL,	"gpt2_ick",			&dummy_ck,	CK_443X),
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index c8f2c3c..f0fee4c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -27,6 +27,7 @@
 #include <mach/irqs.h>
 #include <mach/gpio.h>
 #include <asm/mach/irq.h>
+#include <plat/clock.h>
 
 /*
  * OMAP1510 GPIO registers
@@ -147,102 +148,13 @@ struct gpio_bank {
 	struct gpio_chip chip;
 	struct clk *dbck;
 	u32 mod_usage;
+	u8  initialized;
+	int (*device_enable)(struct platform_device *pdev);
+	int (*device_idle)(struct platform_device *pdev);
+	int (*device_shutdown) (struct platform_device *pdev);
 };
 
-#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,
-		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;
@@ -262,26 +174,9 @@ 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 },
-};
-
-#endif
-
 static struct gpio_bank *gpio_bank;
 static int gpio_bank_count;
+static int gpio_bank_bits;
 
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 {
@@ -1467,7 +1362,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);
@@ -1582,22 +1478,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)
 {
@@ -1621,6 +1501,34 @@ static void __init omap_gpio_show_rev(void)
  */
 static struct lock_class_key gpio_lock_class;
 
+static int init_gpio_info(void)
+{
+	gpio_bank_bits = 32;
+
+	if (cpu_is_omap15xx()) {
+		gpio_bank_count = 2;
+		gpio_bank_bits = 16;
+	} else if (cpu_is_omap16xx()) {
+		gpio_bank_count = 5;
+		gpio_bank_bits = 16;
+	} else if (cpu_is_omap7xx())
+		gpio_bank_count = 7;
+	else if (cpu_is_omap242x())
+		gpio_bank_count = 4;
+	else if (cpu_is_omap243x())
+		gpio_bank_count = 5;
+	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
+		gpio_bank_count = OMAP34XX_NR_GPIOS;
+
+	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
+				GFP_KERNEL);
+	if (!gpio_bank) {
+		pr_err("Memory allocation 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()) {
@@ -1686,16 +1594,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, gpio_bank_bits = 16;
+	int j;
 	static int gpio;
 
-	if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
-		gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
-
-	if ((bank->method == METHOD_GPIO_24XX) ||
-			(bank->method == METHOD_GPIO_44XX))
-		gpio_bank_bits = 32;
-
 	bank->mod_usage = 0;
 	/* REVISIT eventually switch from OMAP-specific gpio structs
 	 * over to the generic ones
@@ -1737,140 +1638,103 @@ 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 inline void get_gpio_dbck(struct platform_device *pdev,
+				struct gpio_bank *bank)
 {
-	int i;
-	int gpio = 0;
+	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+		bank->dbck = clk_get(&pdev->dev, "dbck");
+		if (IS_ERR(bank->dbck))
+			pr_err("GPIO: Could not get dbck\n");
+	}
+}
+
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
+{
+	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 (!gpio_init_done)
+		init_gpio_info();
 
-#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);
+	if (!pdev || !pdev->dev.platform_data) {
+		pr_err("GPIO device initialize without"
+					"platform data\n");
+		return -EINVAL;
 	}
-#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);
 
-		/*
-		 * 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
+	pdata = pdev->dev.platform_data;
 
-#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]);
-		}
+	id = pdev->id;
+	if (id > gpio_bank_count) {
+		pr_err("Invalid GPIO device id (%d)\n", id);
+		return -EINVAL;
 	}
-#endif
 
+	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;
+	if (bank->initialized == 1) {
+		/*
+		 * Currently, for early platform_devices,
+		 * clk_get() using dev ptr does not seem to be working
+		 * Hence getting dbck during regular device probe
+		 */
+		get_gpio_dbck(pdev, bank);
+		return 0;
 	}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	if (cpu_is_omap44xx()) {
-		gpio_bank_count = OMAP34XX_NR_GPIOS;
-		gpio_bank = gpio_bank_44xx;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (unlikely(!res)) {
+		pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
+		return -ENODEV;
 	}
-#endif
-	for (i = 0; i < gpio_bank_count; i++) {
+	bank->irq = res->start;
+	bank->virtual_irq_start = pdata->virtual_irq_start;
+	bank->base = pdata->base;
+	bank->method = pdata->method;
 
-		bank = &gpio_bank[i];
-		spin_lock_init(&bank->lock);
+	spin_lock_init(&bank->lock);
 
+	if (cpu_class_is_omap2()) {
+		bank->device_enable = pdata->device_enable;
+		bank->device_idle = pdata->device_idle;
+		bank->device_shutdown = pdata->device_shutdown;
+		pdata->device_enable(pdev);
+	} else if (cpu_class_is_omap1()) {
 		/* 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;
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (unlikely(!res)) {
+			pr_err("GPIO Bank %i Invalid mem resource\n", id);
+			return -ENODEV;
 		}
 
-		omap_gpio_mod_init(bank, i);
-		omap_gpio_chip_init(bank);
+		bank->base = ioremap(res->start, resource_size(res));
+		if (!bank->base) {
+			pr_err("Could not ioremap gpio bank%i\n", id);
+			return -ENOMEM;
+		}
 
-		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 (cpu_is_omap15xx() && (id == 0)) {
+			static struct clk *gpio_clk;
+			gpio_clk = clk_get(&pdev->dev, "arm_gpio_ck");
+			if (IS_ERR(gpio_clk))
+				pr_err("Could not get arm_gpio_ck\n");
+			else
+				clk_enable(gpio_clk);
 		}
 	}
 
-	omap_gpio_show_rev();
+	omap_gpio_mod_init(bank, id);
+	omap_gpio_chip_init(bank);
 
+	if (!gpio_init_done) {
+		omap_gpio_show_rev();
+		gpio_init_done = 1;
+	}
+
+	bank->initialized = 1;
 	return 0;
 }
 
@@ -2210,16 +2074,42 @@ void omap_gpio_restore_context(void)
 }
 #endif
 
-/*
- * This may get called early from board specific init
- * for boards that have interrupts routed via FPGA.
- */
+static struct platform_driver omap_gpio_driver = {
+	.probe		= omap_gpio_probe,
+	.driver		= {
+		.name	= "omap-gpio",
+	},
+};
+
+int __init omap_gpio_drv_reg(void)
+{
+	return platform_driver_register(&omap_gpio_driver);
+}
+
+early_platform_init("earlygpio", &omap_gpio_driver);
+
 int __init omap_gpio_init(void)
 {
-	if (!initialized)
-		return _omap_gpio_init();
-	else
+	int ret = 0;
+
+	if (initialized)
 		return 0;
+
+#ifdef CONFIG_ARCH_OMAP1
+	if (cpu_is_omap7xx())
+		ret = omap7xx_gpio_init();
+	if (cpu_is_omap15xx())
+		ret = omap15xx_gpio_init();
+	if (cpu_is_omap16xx())
+		ret = omap16xx_gpio_init();
+#endif
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	if (cpu_class_is_omap2())
+		ret = omap2_gpio_init();
+#endif
+	initialized = 1;
+
+	return ret;
 }
 
 static int __init omap_gpio_sysinit(void)
@@ -2227,7 +2117,10 @@ static int __init omap_gpio_sysinit(void)
 	int ret = 0;
 
 	if (!initialized)
-		ret = _omap_gpio_init();
+		ret = omap_gpio_init();
+
+	if (!ret)
+		ret = omap_gpio_drv_reg();
 
 	mpuio_init();
 
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index a06acb6..7dca19a 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
 #define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
@@ -137,6 +138,16 @@
 				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
 				 IH_GPIO_BASE + (nr))
 
+struct omap_gpio_platform_data {
+	void __iomem *base;
+	u16 irq;
+	u16 virtual_irq_start;
+	int method;
+	int (*device_enable)(struct platform_device *pdev);
+	int (*device_idle)(struct platform_device *pdev);
+	int (*device_shutdown) (struct platform_device *pdev);
+};
+
 extern int omap_gpio_init(void);	/* Call from board init only */
 extern void omap2_gpio_prepare_for_retention(void);
 extern void omap2_gpio_resume_after_retention(void);
@@ -144,6 +155,16 @@ 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);
+
+#ifdef CONFIG_ARCH_OMAP1
+extern int omap7xx_gpio_init(void);
+extern int omap15xx_gpio_init(void);
+extern int omap16xx_gpio_init(void);
+#endif
+#ifdef CONFIG_ARCH_OMAP2PLUS
+extern int omap2_gpio_init(void);
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 /* Wrappers for "new style" GPIO calls, using the new infrastructure
-- 
1.6.3.3


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

* Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-04-22 15:55         ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS " Charulatha V
  2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
@ 2010-04-30 23:03           ` Kevin Hilman
  2010-05-04 15:59             ` Varadarajan, Charulatha
  2010-05-05 22:31           ` Tony Lindgren
  2 siblings, 1 reply; 33+ messages in thread
From: Kevin Hilman @ 2010-04-30 23:03 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, rnayak, paul, tony

Charulatha V <charu@ti.com> writes:

> This patch adds support for handling GPIO as a HWMOD adapted
> platform device for OMAP2PLUS chips.
>
> Signed-off-by: Charulatha V <charu@ti.com>
> ---
>  arch/arm/mach-omap2/gpio.c |  101 ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 101 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..6424050
> --- /dev/null
> +++ b/arch/arm/mach-omap2/gpio.c
> @@ -0,0 +1,101 @@
> +/*
> + * 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 <plat/omap_hwmod.h>
> +#include <plat/omap_device.h>
> +
> +static int gpio_bank_count;
> +
> +struct omap_device_pm_latency omap_gpio_latency[] = {
> +	[0] = {
> +		.deactivate_func = omap_device_idle_hwmods,
> +		.activate_func   = omap_device_enable_hwmods,
> +		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
> +	},
> +};
> +
> +int __init gpio_init(void)
> +{
> +	int i = 0;
> +	static int is_early_device = true;
> +
> +	do {
> +		struct omap_device *od;
> +		struct omap_hwmod *oh;
> +		int hw_mod_name_len = 16;
> +		int l;
> +		char oh_name[hw_mod_name_len];
> +		struct omap_gpio_platform_data *pdata;
> +		char *name = "omap-gpio";
> +
> +		l = snprintf(oh_name, hw_mod_name_len, "gpio%d_hwmod", i + 1);
> +		WARN(l >= hw_mod_name_len,
> +			"String buffer overflow in GPIO device setup\n");
> +

Rather than iterating over the name, you should have a hwmod_class for
GPIOs and use omap_hwmod_for_each_by_class() to iterate over all the
hwmods in the GPIO class.

> +		oh = omap_hwmod_lookup(oh_name);
> +		if (!oh) {
> +			pr_err("Could not look up %s\n", oh_name);
> +			i++;
> +			continue;
> +		}
> +
> +		pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> +					GFP_KERNEL);
> +		if (!pdata) {
> +			pr_err("Memory allocation failed gpio%d\n", i + 1);
> +			return -ENOMEM;
> +		}
> +		pdata->base = oh->_rt_va;
> +		pdata->irq = oh->mpu_irqs[0].irq;

base address and IRQ should not be part of platform_data.   platform
driver should be using platform_get_resource() for both.

> +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
> +			pdata->method = METHOD_GPIO_24XX;
> +		if (cpu_is_omap44xx())
> +			pdata->method = METHOD_GPIO_44XX;
> +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
> +		pdata->device_enable = omap_device_enable;
> +		pdata->device_idle = omap_device_idle;
> +		pdata->device_shutdown = omap_device_shutdown;

These aren't valid for GPIO1 which is in WKUP.  Maybe we need
to check if the hwmod is not in wkup_pwrdm before setting these?

> +		od = omap_device_build(name, i, oh, pdata,
> +					sizeof(*pdata),	omap_gpio_latency,
> +					ARRAY_SIZE(omap_gpio_latency),
> +					is_early_device);
> +		WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> +					name, oh->name);
> +
> +		i++;
> +	} while (i < gpio_bank_count);
> +	is_early_device = false;
> +
> +	return 0;
> +}
> +arch_initcall(gpio_init);
> +
> +int __init omap2_gpio_init(void)
> +{
> +	if (cpu_is_omap242x())
> +		gpio_bank_count = 4;
> +	else if (cpu_is_omap243x())
> +		gpio_bank_count = 5;
> +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> +		gpio_bank_count = OMAP34XX_NR_GPIOS;

The count should be gathered after iterating over the GPIO hwmod class.
and should not need cpu_is checks.

> +	if (gpio_init())
> +		return -EINVAL;
> +
> +	early_platform_driver_register_all("earlygpio");
> +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
> +	return 0;
> +}
> -- 
> 1.6.3.3

Kevin

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

* Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-04-22 15:55                 ` [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device Charulatha V
@ 2010-05-01  0:04                   ` Kevin Hilman
  2010-05-04 15:59                     ` Varadarajan, Charulatha
  0 siblings, 1 reply; 33+ messages in thread
From: Kevin Hilman @ 2010-05-01  0:04 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, rnayak, paul, tony

Charulatha V <charu@ti.com> writes:

> This patch implements GPIO as a early platform device. Also it
> implements OMAP2PLUS specific GPIO as HWMOD FW adapted driver.

Should include a summary explanation of why you're converting to an
early platform device as well.

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

ok

> Currently early platform device register does not do device_pm_init.
> Hence pm_runtime functions are not used to enable the GPIO device
> since gpio is early platform device.

OK for now, since this isn't using runtime PM, but maybe we need a
late_initcall() here to do the device_pm_init() + pm_runtime_enable()

This change log needs more description of the intended init sequence.
Right now it seems that there are multiple init paths.  Now that GPIO
is an early_platform_device, we should be able to at least make
omap_gpio_init() static and remove its usage from all the board files.

Also, the driver and device separation and init is totally mixed
together and very confusing. The platform_driver is in
plat-omap/gpio.c and should be doing the driver init:
[early_]platform_driver_register() and _probe(). The platform_device
setup is in mach-omapX/gpio*.c and where the device init should be, in
this case early_platform_add_devices().


> Signed-off-by: Charulatha V <charu@ti.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
>  arch/arm/mach-omap1/Makefile           |    6 +
>  arch/arm/mach-omap1/clock_data.c       |    2 +-
>  arch/arm/mach-omap2/Makefile           |    2 +-
>  arch/arm/mach-omap2/clock2420_data.c   |   10 +-
>  arch/arm/mach-omap2/clock2430_data.c   |   14 +-
>  arch/arm/mach-omap2/clock3xxx_data.c   |   24 +-
>  arch/arm/mach-omap2/clock44xx_data.c   |   24 +-
>  arch/arm/plat-omap/gpio.c              |  405 ++++++++++++--------------------
>  arch/arm/plat-omap/include/plat/gpio.h |   21 ++
>  9 files changed, 220 insertions(+), 288 deletions(-)

[...]

> @@ -1621,6 +1501,34 @@ static void __init omap_gpio_show_rev(void)
>   */
>  static struct lock_class_key gpio_lock_class;
>  
> +static int init_gpio_info(void)
> +{
> +	gpio_bank_bits = 32;
> +
> +	if (cpu_is_omap15xx()) {
> +		gpio_bank_count = 2;
> +		gpio_bank_bits = 16;
> +	} else if (cpu_is_omap16xx()) {
> +		gpio_bank_count = 5;
> +		gpio_bank_bits = 16;
> +	} else if (cpu_is_omap7xx())
> +		gpio_bank_count = 7;
> +	else if (cpu_is_omap242x())
> +		gpio_bank_count = 4;
> +	else if (cpu_is_omap243x())
> +		gpio_bank_count = 5;
> +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> +		gpio_bank_count = OMAP34XX_NR_GPIOS;

Both the bank count and bank bits could be part of platform_data
and set in the SoC specific init.  This is the GPIO driver part
and we're trying to make this as SoC independent as possible.  Anytime
you need to add a cpu_is* or #ifdef in this code indicates something
that should be part of SoC specific init and passed in.

> +	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
> +				GFP_KERNEL);
> +	if (!gpio_bank) {
> +		pr_err("Memory allocation 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()) {
> @@ -1686,16 +1594,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, gpio_bank_bits = 16;
> +	int j;
>  	static int gpio;
>  
> -	if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
> -		gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
> -
> -	if ((bank->method == METHOD_GPIO_24XX) ||
> -			(bank->method == METHOD_GPIO_44XX))
> -		gpio_bank_bits = 32;
> -
>  	bank->mod_usage = 0;
>  	/* REVISIT eventually switch from OMAP-specific gpio structs
>  	 * over to the generic ones
> @@ -1737,140 +1638,103 @@ 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 inline void get_gpio_dbck(struct platform_device *pdev,
> +				struct gpio_bank *bank)
>  {
> -	int i;
> -	int gpio = 0;
> +	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
> +		bank->dbck = clk_get(&pdev->dev, "dbck");
> +		if (IS_ERR(bank->dbck))
> +			pr_err("GPIO: Could not get dbck\n");
> +	}
> +}
> +static int __devinit omap_gpio_probe(struct platform_device *pdev)
> +{
> +	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 (!gpio_init_done)
> +		init_gpio_info();
>  
> -#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);
> +	if (!pdev || !pdev->dev.platform_data) {
> +		pr_err("GPIO device initialize without"
> +					"platform data\n");
> +		return -EINVAL;
>  	}
> -#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);
>  
> -		/*
> -		 * 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
> +	pdata = pdev->dev.platform_data;
>  
> -#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]);
> -		}
> +	id = pdev->id;
> +	if (id > gpio_bank_count) {
> +		pr_err("Invalid GPIO device id (%d)\n", id);
> +		return -EINVAL;
>  	}
> -#endif
>  
> +	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;
> +	if (bank->initialized == 1) {

is_early_platform_device() can be used to tell if the _probe() is
being called as part of early platform driver probe or "regular".

> +		/*
> +		 * Currently, for early platform_devices,
> +		 * clk_get() using dev ptr does not seem to be working
> +		 * Hence getting dbck during regular device probe
> +		 */

Need a better explanation here.  "does not seem to work" is not
quite good enough.

> +		get_gpio_dbck(pdev, bank);

In any case, maybe it's better to defer the clk_get() into
the debounce setup and only use if needed.

> +		return 0;
>  	}
> -#endif
> -#ifdef CONFIG_ARCH_OMAP4
> -	if (cpu_is_omap44xx()) {
> -		gpio_bank_count = OMAP34XX_NR_GPIOS;
> -		gpio_bank = gpio_bank_44xx;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +	if (unlikely(!res)) {
> +		pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
> +		return -ENODEV;
>  	}
> -#endif
> -	for (i = 0; i < gpio_bank_count; i++) {
> +	bank->irq = res->start;
> +	bank->virtual_irq_start = pdata->virtual_irq_start;
> +	bank->base = pdata->base;

Why are you using pdata->base for OMAP2+ base addresses...

> +	bank->method = pdata->method;
>  
> -		bank = &gpio_bank[i];
> -		spin_lock_init(&bank->lock);
> +	spin_lock_init(&bank->lock);
>  
> +	if (cpu_class_is_omap2()) {
> +		bank->device_enable = pdata->device_enable;
> +		bank->device_idle = pdata->device_idle;
> +		bank->device_shutdown = pdata->device_shutdown;
> +		pdata->device_enable(pdev);
> +	} else if (cpu_class_is_omap1()) {
>  		/* 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;
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

... and doing it the right way here for OMAP1?

platform_get_resource() should be used for both.

> +		if (unlikely(!res)) {
> +			pr_err("GPIO Bank %i Invalid mem resource\n", id);
> +			return -ENODEV;
>  		}
>  
> -		omap_gpio_mod_init(bank, i);
> -		omap_gpio_chip_init(bank);
> +		bank->base = ioremap(res->start, resource_size(res));
> +		if (!bank->base) {
> +			pr_err("Could not ioremap gpio bank%i\n", id);
> +			return -ENOMEM;
> +		}
>  
> -		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 (cpu_is_omap15xx() && (id == 0)) {
> +			static struct clk *gpio_clk;
> +			gpio_clk = clk_get(&pdev->dev, "arm_gpio_ck");
> +			if (IS_ERR(gpio_clk))
> +				pr_err("Could not get arm_gpio_ck\n");
> +			else
> +				clk_enable(gpio_clk);
>  		}
>  	}
>  
> -	omap_gpio_show_rev();
> +	omap_gpio_mod_init(bank, id);
> +	omap_gpio_chip_init(bank);
>  
> +	if (!gpio_init_done) {
> +		omap_gpio_show_rev();
> +		gpio_init_done = 1;
> +	}
> +
> +	bank->initialized = 1;

I think you can drop this flag, and use is_early_platform_device() if
needed.

>  	return 0;
>  }
>  
> @@ -2210,16 +2074,42 @@ void omap_gpio_restore_context(void)
>  }
>  #endif
>  
> -/*
> - * This may get called early from board specific init
> - * for boards that have interrupts routed via FPGA.
> - */
> +static struct platform_driver omap_gpio_driver = {
> +	.probe		= omap_gpio_probe,
> +	.driver		= {
> +		.name	= "omap-gpio",
> +	},
> +};
> +
> +int __init omap_gpio_drv_reg(void)
> +{
> +	return platform_driver_register(&omap_gpio_driver);
> +}
> +
> +early_platform_init("earlygpio", &omap_gpio_driver);
> +
>  int __init omap_gpio_init(void)
>  {
> -	if (!initialized)
> -		return _omap_gpio_init();
> -	else
> +	int ret = 0;
> +
> +	if (initialized)
>  		return 0;
> +
> +#ifdef CONFIG_ARCH_OMAP1
> +	if (cpu_is_omap7xx())
> +		ret = omap7xx_gpio_init();
> +	if (cpu_is_omap15xx())
> +		ret = omap15xx_gpio_init();
> +	if (cpu_is_omap16xx())
> +		ret = omap16xx_gpio_init();
> +#endif
> +#ifdef CONFIG_ARCH_OMAP2PLUS
> +	if (cpu_class_is_omap2())
> +		ret = omap2_gpio_init();
> +#endif

No thanks.  driver init should not be calling device init.  The device
init should have it's own initcall or be called by other early device
init.

> +	initialized = 1;
> +
> +	return ret;
>  }
>  
>  static int __init omap_gpio_sysinit(void)
> @@ -2227,7 +2117,10 @@ static int __init omap_gpio_sysinit(void)
>  	int ret = 0;
>  
>  	if (!initialized)
> -		ret = _omap_gpio_init();
> +		ret = omap_gpio_init();
> +
> +	if (!ret)
> +		ret = omap_gpio_drv_reg();
>  
>  	mpuio_init();

Kevin

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

* RE: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-01  0:04                   ` Kevin Hilman
@ 2010-05-04 15:59                     ` Varadarajan, Charulatha
  2010-05-05 20:59                       ` Kevin Hilman
  0 siblings, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-04 15:59 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, Nayak, Rajendra, paul, tony



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Saturday, May 01, 2010 5:34 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com; tony@atomide.com
> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
>
> Charulatha V <charu@ti.com> writes:
>
> > This patch implements GPIO as a early platform device. Also it
> > implements OMAP2PLUS specific GPIO as HWMOD FW adapted driver.
>
> Should include a summary explanation of why you're converting to an
> early platform device as well.

Okay.

>
> > Inorder to convert GPIO as platform device, modifications are
> > required in clockxxxx_data.c files so that device names can be
> > used to obtain clock instead of getting clocks by name/NULL ptr.
>
> ok
>
> > Currently early platform device register does not do device_pm_init.
> > Hence pm_runtime functions are not used to enable the GPIO device
> > since gpio is early platform device.
>
> OK for now, since this isn't using runtime PM, but maybe we need a
> late_initcall() here to do the device_pm_init() + pm_runtime_enable()
>
> This change log needs more description of the intended init sequence.
> Right now it seems that there are multiple init paths.  Now that GPIO
> is an early_platform_device, we should be able to at least make
> omap_gpio_init() static and remove its usage from all the board files.

This was the implementation that I initially did in my previous patch
series. The following needs to be considered:

1. omap2_init_devices() might be too late for early_gpio_init() to
be placed in it.

2. omap_init_irq() needs to be completed before calling early_gpio_init().
So, if early_gpio_init() is called from omap2_init_common_hw(), we need to
have omap_init_irq() called before omap2_init_common_hw(). But Tony
objected this approach mentioning that board might not boot up as
omap2_init_common_hw() has to be done asap.

That's why, I had not moved the omap_gpio_init() usage from board files.

>
> Also, the driver and device separation and init is totally mixed
> together and very confusing. The platform_driver is in

Agreed. Please see my comment at the end of this patch in reply to your
other similar comment.


> plat-omap/gpio.c and should be doing the driver init:
> [early_]platform_driver_register() and _probe(). The platform_device
> setup is in mach-omapX/gpio*.c and where the device init should be, in
> this case early_platform_add_devices().

In early_gpio_init, omap_device_build() (device specific) and
early_platform_driver_register_all() (driver specific), _probe() are
done in a sequence. This is because early_gpio_init needs to be called
asap and if we try to split this device specific and driver specific
early_inits, we will end up having two init calls for each early drivers.

I feel that multiple function calls for early_init (one for driver probe and
one for device register) should be avoided as we need to find the right place
to call them.

>
>
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > ---
> >  arch/arm/mach-omap1/Makefile           |    6 +
> >  arch/arm/mach-omap1/clock_data.c       |    2 +-
> >  arch/arm/mach-omap2/Makefile           |    2 +-
> >  arch/arm/mach-omap2/clock2420_data.c   |   10 +-
> >  arch/arm/mach-omap2/clock2430_data.c   |   14 +-
> >  arch/arm/mach-omap2/clock3xxx_data.c   |   24 +-
> >  arch/arm/mach-omap2/clock44xx_data.c   |   24 +-
> >  arch/arm/plat-omap/gpio.c              |  405 ++++++++++++--------------------
> >  arch/arm/plat-omap/include/plat/gpio.h |   21 ++
> >  9 files changed, 220 insertions(+), 288 deletions(-)
>
> [...]
>
> > @@ -1621,6 +1501,34 @@ static void __init omap_gpio_show_rev(void)
> >   */
> >  static struct lock_class_key gpio_lock_class;
> >
> > +static int init_gpio_info(void)
> > +{
> > +   gpio_bank_bits = 32;
> > +
> > +   if (cpu_is_omap15xx()) {
> > +           gpio_bank_count = 2;
> > +           gpio_bank_bits = 16;
> > +   } else if (cpu_is_omap16xx()) {
> > +           gpio_bank_count = 5;
> > +           gpio_bank_bits = 16;
> > +   } else if (cpu_is_omap7xx())
> > +           gpio_bank_count = 7;
> > +   else if (cpu_is_omap242x())
> > +           gpio_bank_count = 4;
> > +   else if (cpu_is_omap243x())
> > +           gpio_bank_count = 5;
> > +   else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> > +           gpio_bank_count = OMAP34XX_NR_GPIOS;
>
> Both the bank count and bank bits could be part of platform_data
> and set in the SoC specific init.  This is the GPIO driver part
> and we're trying to make this as SoC independent as possible.  Anytime
> you need to add a cpu_is* or #ifdef in this code indicates something
> that should be part of SoC specific init and passed in.

bank count and bank bits are not specific to each device, but SoC specific.
Hence I did not consider passing it as part of platform_data, because this information would be duplicated across all devices in that SoC.

It would be good if we have a way to pass the SoC specific data which is
common for all the devices rather than duplicating them by sending them via
platform_data.

Anyways, I can move it to platform_data if there is no other way.

>
> > +   gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
> > +                           GFP_KERNEL);
> > +   if (!gpio_bank) {
> > +           pr_err("Memory allocation 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()) {
> > @@ -1686,16 +1594,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, gpio_bank_bits = 16;
> > +   int j;
> >     static int gpio;
> >
> > -   if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
> > -           gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
> > -
> > -   if ((bank->method == METHOD_GPIO_24XX) ||
> > -                   (bank->method == METHOD_GPIO_44XX))
> > -           gpio_bank_bits = 32;
> > -
> >     bank->mod_usage = 0;
> >     /* REVISIT eventually switch from OMAP-specific gpio structs
> >      * over to the generic ones
> > @@ -1737,140 +1638,103 @@ 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 inline void get_gpio_dbck(struct platform_device *pdev,
> > +                           struct gpio_bank *bank)
> >  {
> > -   int i;
> > -   int gpio = 0;
> > +   if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
> > +           bank->dbck = clk_get(&pdev->dev, "dbck");
> > +           if (IS_ERR(bank->dbck))
> > +                   pr_err("GPIO: Could not get dbck\n");
> > +   }
> > +}
> > +static int __devinit omap_gpio_probe(struct platform_device *pdev)
> > +{
> > +   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 (!gpio_init_done)
> > +           init_gpio_info();
> >
> > -#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);
> > +   if (!pdev || !pdev->dev.platform_data) {
> > +           pr_err("GPIO device initialize without"
> > +                                   "platform data\n");
> > +           return -EINVAL;
> >     }
> > -#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);
> >
> > -           /*
> > -            * 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
> > +   pdata = pdev->dev.platform_data;
> >
> > -#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]);
> > -           }
> > +   id = pdev->id;
> > +   if (id > gpio_bank_count) {
> > +           pr_err("Invalid GPIO device id (%d)\n", id);
> > +           return -EINVAL;
> >     }
> > -#endif
> >
> > +   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;
> > +   if (bank->initialized == 1) {
>
> is_early_platform_device() can be used to tell if the _probe() is
> being called as part of early platform driver probe or "regular".

Okay.

>
> > +           /*
> > +            * Currently, for early platform_devices,
> > +            * clk_get() using dev ptr does not seem to be working
> > +            * Hence getting dbck during regular device probe
> > +            */
>
> Need a better explanation here.  "does not seem to work" is not
> quite good enough.

Okay.
The reason for "does not seem to work" is that device_initialize()
is not called as part of omap_early_device_register and the clk_get
could not find the clock using dev pointer.

>
> > +           get_gpio_dbck(pdev, bank);
>
> In any case, maybe it's better to defer the clk_get() into
> the debounce setup and only use if needed.

Then, this needs to be done only in omap_set_gpio_debounce() which does
not have pdev->dev info. I can take care of this.
>
> > +           return 0;
> >     }
> > -#endif
> > -#ifdef CONFIG_ARCH_OMAP4
> > -   if (cpu_is_omap44xx()) {
> > -           gpio_bank_count = OMAP34XX_NR_GPIOS;
> > -           gpio_bank = gpio_bank_44xx;
> > +
> > +   res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> > +   if (unlikely(!res)) {
> > +           pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
> > +           return -ENODEV;
> >     }
> > -#endif
> > -   for (i = 0; i < gpio_bank_count; i++) {
> > +   bank->irq = res->start;
> > +   bank->virtual_irq_start = pdata->virtual_irq_start;
> > +   bank->base = pdata->base;
>
> Why are you using pdata->base for OMAP2+ base addresses...
Thanks for pointing this. I will correct it.

>
> > +   bank->method = pdata->method;
> >
> > -           bank = &gpio_bank[i];
> > -           spin_lock_init(&bank->lock);
> > +   spin_lock_init(&bank->lock);
> >
> > +   if (cpu_class_is_omap2()) {
> > +           bank->device_enable = pdata->device_enable;
> > +           bank->device_idle = pdata->device_idle;
> > +           bank->device_shutdown = pdata->device_shutdown;
> > +           pdata->device_enable(pdev);
> > +   } else if (cpu_class_is_omap1()) {
> >             /* 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;
> > +           res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> ... and doing it the right way here for OMAP1?
>
> platform_get_resource() should be used for both.

Yes.

>
> > +           if (unlikely(!res)) {
> > +                   pr_err("GPIO Bank %i Invalid mem resource\n", id);
> > +                   return -ENODEV;
> >             }
> >
> > -           omap_gpio_mod_init(bank, i);
> > -           omap_gpio_chip_init(bank);
> > +           bank->base = ioremap(res->start, resource_size(res));
> > +           if (!bank->base) {
> > +                   pr_err("Could not ioremap gpio bank%i\n", id);
> > +                   return -ENOMEM;
> > +           }
> >
> > -           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 (cpu_is_omap15xx() && (id == 0)) {
> > +                   static struct clk *gpio_clk;
> > +                   gpio_clk = clk_get(&pdev->dev, "arm_gpio_ck");
> > +                   if (IS_ERR(gpio_clk))
> > +                           pr_err("Could not get arm_gpio_ck\n");
> > +                   else
> > +                           clk_enable(gpio_clk);
> >             }
> >     }
> >
> > -   omap_gpio_show_rev();
> > +   omap_gpio_mod_init(bank, id);
> > +   omap_gpio_chip_init(bank);
> >
> > +   if (!gpio_init_done) {
> > +           omap_gpio_show_rev();
> > +           gpio_init_done = 1;
> > +   }
> > +
> > +   bank->initialized = 1;
>
> I think you can drop this flag, and use is_early_platform_device() if
> needed.

Sure.
>
> >     return 0;
> >  }
> >
> > @@ -2210,16 +2074,42 @@ void omap_gpio_restore_context(void)
> >  }
> >  #endif
> >
> > -/*
> > - * This may get called early from board specific init
> > - * for boards that have interrupts routed via FPGA.
> > - */
> > +static struct platform_driver omap_gpio_driver = {
> > +   .probe          = omap_gpio_probe,
> > +   .driver         = {
> > +           .name   = "omap-gpio",
> > +   },
> > +};
> > +
> > +int __init omap_gpio_drv_reg(void)
> > +{
> > +   return platform_driver_register(&omap_gpio_driver);
> > +}
> > +
> > +early_platform_init("earlygpio", &omap_gpio_driver);
> > +
> >  int __init omap_gpio_init(void)
> >  {
> > -   if (!initialized)
> > -           return _omap_gpio_init();
> > -   else
> > +   int ret = 0;
> > +
> > +   if (initialized)
> >             return 0;
> > +
> > +#ifdef CONFIG_ARCH_OMAP1
> > +   if (cpu_is_omap7xx())
> > +           ret = omap7xx_gpio_init();
> > +   if (cpu_is_omap15xx())
> > +           ret = omap15xx_gpio_init();
> > +   if (cpu_is_omap16xx())
> > +           ret = omap16xx_gpio_init();
> > +#endif
> > +#ifdef CONFIG_ARCH_OMAP2PLUS
> > +   if (cpu_class_is_omap2())
> > +           ret = omap2_gpio_init();
> > +#endif
>
> No thanks.  driver init should not be calling device init.  The device
> init should have it's own initcall or be called by other early device
> init.

Agreed. omap_gpio_init() does nothing but calling device_init().

But having omap_gpio_init() isn't a problem for OMAP2+, whereas it
would break multi-omap build for OMAP1 because there are 3 files in
mach-omap1 for each omap.

1. I can club all the 3 gpio files in mach-omap1 in to one file
mach-omap1/gpio.c and use omap_gpio_init() in it. But the patch
size and file size might be much bigger as the platform_data for all
OMAP1 GPIO devices would be available in this file.

2. (or) While maintaining 3 different files for mach-omap1/gpio_xxx.c,
modify the board files (about 20 files) of mach-omap1 and make use
of SoC specific omap_gpio_init.

3. (or) Call gpio_init() from omap_init_common_hw() by removing the calls
from board files and do a cpu_is check (for mach-omap1) in it.

Please suggest if we have any other ways to handle this and the better
way to handle this.

>
> > +   initialized = 1;
> > +
> > +   return ret;
> >  }
> >
> >  static int __init omap_gpio_sysinit(void)
> > @@ -2227,7 +2117,10 @@ static int __init omap_gpio_sysinit(void)
> >     int ret = 0;
> >
> >     if (!initialized)
> > -           ret = _omap_gpio_init();
> > +           ret = omap_gpio_init();
> > +
> > +   if (!ret)
> > +           ret = omap_gpio_drv_reg();
> >
> >     mpuio_init();
>
> Kevin

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

* RE: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-04-30 23:03           ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO Kevin Hilman
@ 2010-05-04 15:59             ` Varadarajan, Charulatha
  2010-05-11 14:43               ` Varadarajan, Charulatha
  0 siblings, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-04 15:59 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, Nayak, Rajendra, paul, tony



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Saturday, May 01, 2010 4:33 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com; tony@atomide.com
> Subject: Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific
> GPIO
> 
> Charulatha V <charu@ti.com> writes:
> 
> > This patch adds support for handling GPIO as a HWMOD adapted
> > platform device for OMAP2PLUS chips.
> >
> > Signed-off-by: Charulatha V <charu@ti.com>
> > ---
> >  arch/arm/mach-omap2/gpio.c |  101 ++++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 101 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..6424050
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/gpio.c
> > @@ -0,0 +1,101 @@
> > +/*
> > + * 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 <plat/omap_hwmod.h>
> > +#include <plat/omap_device.h>
> > +
> > +static int gpio_bank_count;
> > +
> > +struct omap_device_pm_latency omap_gpio_latency[] = {
> > +	[0] = {
> > +		.deactivate_func = omap_device_idle_hwmods,
> > +		.activate_func   = omap_device_enable_hwmods,
> > +		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
> > +	},
> > +};
> > +
> > +int __init gpio_init(void)
> > +{
> > +	int i = 0;
> > +	static int is_early_device = true;
> > +
> > +	do {
> > +		struct omap_device *od;
> > +		struct omap_hwmod *oh;
> > +		int hw_mod_name_len = 16;
> > +		int l;
> > +		char oh_name[hw_mod_name_len];
> > +		struct omap_gpio_platform_data *pdata;
> > +		char *name = "omap-gpio";
> > +
> > +		l = snprintf(oh_name, hw_mod_name_len, "gpio%d_hwmod", i + 1);
> > +		WARN(l >= hw_mod_name_len,
> > +			"String buffer overflow in GPIO device setup\n");
> > +
> 
> Rather than iterating over the name, you should have a hwmod_class for
> GPIOs and use omap_hwmod_for_each_by_class() to iterate over all the
> hwmods in the GPIO class.

Ok.

> 
> > +		oh = omap_hwmod_lookup(oh_name);
> > +		if (!oh) {
> > +			pr_err("Could not look up %s\n", oh_name);
> > +			i++;
> > +			continue;
> > +		}
> > +
> > +		pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> > +					GFP_KERNEL);
> > +		if (!pdata) {
> > +			pr_err("Memory allocation failed gpio%d\n", i + 1);
> > +			return -ENOMEM;
> > +		}
> > +		pdata->base = oh->_rt_va;
> > +		pdata->irq = oh->mpu_irqs[0].irq;
> 
> base address and IRQ should not be part of platform_data.   platform
> driver should be using platform_get_resource() for both.

Agreed. Will modify.

> 
> > +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
> > +			pdata->method = METHOD_GPIO_24XX;
> > +		if (cpu_is_omap44xx())
> > +			pdata->method = METHOD_GPIO_44XX;
> > +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
> > +		pdata->device_enable = omap_device_enable;
> > +		pdata->device_idle = omap_device_idle;
> > +		pdata->device_shutdown = omap_device_shutdown;
> 
> These aren't valid for GPIO1 which is in WKUP.  Maybe we need
> to check if the hwmod is not in wkup_pwrdm before setting these?

I need to check how to implement this. 

> 
> > +		od = omap_device_build(name, i, oh, pdata,
> > +					sizeof(*pdata),	omap_gpio_latency,
> > +					ARRAY_SIZE(omap_gpio_latency),
> > +					is_early_device);
> > +		WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> > +					name, oh->name);
> > +
> > +		i++;
> > +	} while (i < gpio_bank_count);
> > +	is_early_device = false;
> > +
> > +	return 0;
> > +}
> > +arch_initcall(gpio_init);
> > +
> > +int __init omap2_gpio_init(void)
> > +{
> > +	if (cpu_is_omap242x())
> > +		gpio_bank_count = 4;
> > +	else if (cpu_is_omap243x())
> > +		gpio_bank_count = 5;
> > +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> > +		gpio_bank_count = OMAP34XX_NR_GPIOS;
> 
> The count should be gathered after iterating over the GPIO hwmod class.
> and should not need cpu_is checks.

Sure.

> 
> > +	if (gpio_init())
> > +		return -EINVAL;
> > +
> > +	early_platform_driver_register_all("earlygpio");
> > +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
> > +	return 0;
> > +}
> > --
> > 1.6.3.3
> 
> Kevin

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

* Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-04 15:59                     ` Varadarajan, Charulatha
@ 2010-05-05 20:59                       ` Kevin Hilman
  2010-05-05 22:37                         ` Tony Lindgren
                                           ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Kevin Hilman @ 2010-05-05 20:59 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: linux-omap, Nayak, Rajendra, paul, tony

"Varadarajan, Charulatha" <charu@ti.com> writes:

>> -----Original Message-----
>> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>> Sent: Saturday, May 01, 2010 5:34 AM
>> To: Varadarajan, Charulatha
>> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com; tony@atomide.com
>> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
>>
>> Charulatha V <charu@ti.com> writes:
>>
>> > This patch implements GPIO as a early platform device. Also it
>> > implements OMAP2PLUS specific GPIO as HWMOD FW adapted driver.
>>
>> Should include a summary explanation of why you're converting to an
>> early platform device as well.
>
> Okay.
>
>>
>> > Inorder to convert GPIO as platform device, modifications are
>> > required in clockxxxx_data.c files so that device names can be
>> > used to obtain clock instead of getting clocks by name/NULL ptr.
>>
>> ok
>>
>> > Currently early platform device register does not do device_pm_init.
>> > Hence pm_runtime functions are not used to enable the GPIO device
>> > since gpio is early platform device.
>>
>> OK for now, since this isn't using runtime PM, but maybe we need a
>> late_initcall() here to do the device_pm_init() + pm_runtime_enable()
>>
>> This change log needs more description of the intended init sequence.
>> Right now it seems that there are multiple init paths.  Now that GPIO
>> is an early_platform_device, we should be able to at least make
>> omap_gpio_init() static and remove its usage from all the board files.
>
> This was the implementation that I initially did in my previous patch
> series. The following needs to be considered:
>
> 1. omap2_init_devices() might be too late for early_gpio_init() to
> be placed in it.
>
> 2. omap_init_irq() needs to be completed before calling early_gpio_init().
> So, if early_gpio_init() is called from omap2_init_common_hw(), we need to
> have omap_init_irq() called before omap2_init_common_hw(). But Tony
> objected this approach mentioning that board might not boot up as
> omap2_init_common_hw() has to be done asap.
>
> That's why, I had not moved the omap_gpio_init() usage from board files.

OK... for now.  I'd still like to see GPIO init consolidated as there's
no (good) reason why every board file has to init GPIOs when it's common
for all SoCs, but this doesn't necessarily have to be done in your series.
Although, if you do it for OMAP1 (as proposed below) you should do similar
for OMAP2+.

>>
>> Also, the driver and device separation and init is totally mixed
>> together and very confusing. The platform_driver is in
>
> Agreed. Please see my comment at the end of this patch in reply to your
> other similar comment.
>
>
>> plat-omap/gpio.c and should be doing the driver init:
>> [early_]platform_driver_register() and _probe(). The platform_device
>> setup is in mach-omapX/gpio*.c and where the device init should be, in
>> this case early_platform_add_devices().
>
> In early_gpio_init, omap_device_build() (device specific) and
> early_platform_driver_register_all() (driver specific), _probe() are
> done in a sequence. This is because early_gpio_init needs to be called
> asap and if we try to split this device specific and driver specific
> early_inits, we will end up having two init calls for each early drivers.
>
> I feel that multiple function calls for early_init (one for driver probe and
> one for device register) should be avoided as we need to find the right place
> to call them.

But your driver probe is already in a separate init path (via
arch_initcall) from your device init path omap_gpio_init().

My problem is that there is a 2nd driver init path:
board file -> [driver]omap_gpio_init() -> [device] <soc>_gpio_init()

The fact that it goes through the driver is what I don't like.

>>
>>
>> > Signed-off-by: Charulatha V <charu@ti.com>
>> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
>> > ---
>> >  arch/arm/mach-omap1/Makefile           |    6 +
>> >  arch/arm/mach-omap1/clock_data.c       |    2 +-
>> >  arch/arm/mach-omap2/Makefile           |    2 +-
>> >  arch/arm/mach-omap2/clock2420_data.c   |   10 +-
>> >  arch/arm/mach-omap2/clock2430_data.c   |   14 +-
>> >  arch/arm/mach-omap2/clock3xxx_data.c   |   24 +-
>> >  arch/arm/mach-omap2/clock44xx_data.c   |   24 +-
>> >  arch/arm/plat-omap/gpio.c              |  405 ++++++++++++--------------------
>> >  arch/arm/plat-omap/include/plat/gpio.h |   21 ++
>> >  9 files changed, 220 insertions(+), 288 deletions(-)
>>
>> [...]
>>
>> > @@ -1621,6 +1501,34 @@ static void __init omap_gpio_show_rev(void)
>> >   */
>> >  static struct lock_class_key gpio_lock_class;
>> >
>> > +static int init_gpio_info(void)
>> > +{
>> > +   gpio_bank_bits = 32;
>> > +
>> > +   if (cpu_is_omap15xx()) {
>> > +           gpio_bank_count = 2;
>> > +           gpio_bank_bits = 16;
>> > +   } else if (cpu_is_omap16xx()) {
>> > +           gpio_bank_count = 5;
>> > +           gpio_bank_bits = 16;
>> > +   } else if (cpu_is_omap7xx())
>> > +           gpio_bank_count = 7;
>> > +   else if (cpu_is_omap242x())
>> > +           gpio_bank_count = 4;
>> > +   else if (cpu_is_omap243x())
>> > +           gpio_bank_count = 5;
>> > +   else if (cpu_is_omap34xx() || cpu_is_omap44xx())
>> > +           gpio_bank_count = OMAP34XX_NR_GPIOS;
>>
>> Both the bank count and bank bits could be part of platform_data
>> and set in the SoC specific init.  This is the GPIO driver part
>> and we're trying to make this as SoC independent as possible.  Anytime
>> you need to add a cpu_is* or #ifdef in this code indicates something
>> that should be part of SoC specific init and passed in.
>
> bank count and bank bits are not specific to each device, but SoC specific.
> Hence I did not consider passing it as part of platform_data, because this information would be duplicated across all devices in that SoC.
>
> It would be good if we have a way to pass the SoC specific data which is
> common for all the devices rather than duplicating them by sending them via
> platform_data.
>
> Anyways, I can move it to platform_data if there is no other way.

Probably the right place for the SoC specifics is attached to the SoC
specific hwmod using the dev_attr pointer.  That struct can then
be passed in via platform_data.

You can see how Thara did this for SmartReflex as an example.

>>
>> > +   gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
>> > +                           GFP_KERNEL);
>> > +   if (!gpio_bank) {
>> > +           pr_err("Memory allocation 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()) {
>> > @@ -1686,16 +1594,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, gpio_bank_bits = 16;
>> > +   int j;
>> >     static int gpio;
>> >
>> > -   if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
>> > -           gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
>> > -
>> > -   if ((bank->method == METHOD_GPIO_24XX) ||
>> > -                   (bank->method == METHOD_GPIO_44XX))
>> > -           gpio_bank_bits = 32;
>> > -
>> >     bank->mod_usage = 0;
>> >     /* REVISIT eventually switch from OMAP-specific gpio structs
>> >      * over to the generic ones
>> > @@ -1737,140 +1638,103 @@ 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 inline void get_gpio_dbck(struct platform_device *pdev,
>> > +                           struct gpio_bank *bank)
>> >  {
>> > -   int i;
>> > -   int gpio = 0;
>> > +   if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
>> > +           bank->dbck = clk_get(&pdev->dev, "dbck");
>> > +           if (IS_ERR(bank->dbck))
>> > +                   pr_err("GPIO: Could not get dbck\n");
>> > +   }
>> > +}
>> > +static int __devinit omap_gpio_probe(struct platform_device *pdev)
>> > +{
>> > +   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 (!gpio_init_done)
>> > +           init_gpio_info();
>> >
>> > -#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);
>> > +   if (!pdev || !pdev->dev.platform_data) {
>> > +           pr_err("GPIO device initialize without"
>> > +                                   "platform data\n");
>> > +           return -EINVAL;
>> >     }
>> > -#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);
>> >
>> > -           /*
>> > -            * 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
>> > +   pdata = pdev->dev.platform_data;
>> >
>> > -#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]);
>> > -           }
>> > +   id = pdev->id;
>> > +   if (id > gpio_bank_count) {
>> > +           pr_err("Invalid GPIO device id (%d)\n", id);
>> > +           return -EINVAL;
>> >     }
>> > -#endif
>> >
>> > +   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;
>> > +   if (bank->initialized == 1) {
>>
>> is_early_platform_device() can be used to tell if the _probe() is
>> being called as part of early platform driver probe or "regular".
>
> Okay.
>
>>
>> > +           /*
>> > +            * Currently, for early platform_devices,
>> > +            * clk_get() using dev ptr does not seem to be working
>> > +            * Hence getting dbck during regular device probe
>> > +            */
>>
>> Need a better explanation here.  "does not seem to work" is not
>> quite good enough.
>
> Okay.
> The reason for "does not seem to work" is that device_initialize()
> is not called as part of omap_early_device_register and the clk_get
> could not find the clock using dev pointer.

OK, should be as part of this comment if you keep it here.

>>
>> > +           get_gpio_dbck(pdev, bank);
>>
>> In any case, maybe it's better to defer the clk_get() into
>> the debounce setup and only use if needed.
>
> Then, this needs to be done only in omap_set_gpio_debounce() which does
> not have pdev->dev info. I can take care of this.

OK good. That's probably cleaner than doing it at init time anyways.

>>
>> > +           return 0;
>> >     }
>> > -#endif
>> > -#ifdef CONFIG_ARCH_OMAP4
>> > -   if (cpu_is_omap44xx()) {
>> > -           gpio_bank_count = OMAP34XX_NR_GPIOS;
>> > -           gpio_bank = gpio_bank_44xx;
>> > +
>> > +   res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
>> > +   if (unlikely(!res)) {
>> > +           pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
>> > +           return -ENODEV;
>> >     }
>> > -#endif
>> > -   for (i = 0; i < gpio_bank_count; i++) {
>> > +   bank->irq = res->start;
>> > +   bank->virtual_irq_start = pdata->virtual_irq_start;
>> > +   bank->base = pdata->base;
>>
>> Why are you using pdata->base for OMAP2+ base addresses...
> Thanks for pointing this. I will correct it.
>
>>
>> > +   bank->method = pdata->method;
>> >
>> > -           bank = &gpio_bank[i];
>> > -           spin_lock_init(&bank->lock);
>> > +   spin_lock_init(&bank->lock);
>> >
>> > +   if (cpu_class_is_omap2()) {
>> > +           bank->device_enable = pdata->device_enable;
>> > +           bank->device_idle = pdata->device_idle;
>> > +           bank->device_shutdown = pdata->device_shutdown;
>> > +           pdata->device_enable(pdev);
>> > +   } else if (cpu_class_is_omap1()) {
>> >             /* 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;
>> > +           res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>
>> ... and doing it the right way here for OMAP1?
>>
>> platform_get_resource() should be used for both.
>
> Yes.
>
>>
>> > +           if (unlikely(!res)) {
>> > +                   pr_err("GPIO Bank %i Invalid mem resource\n", id);
>> > +                   return -ENODEV;
>> >             }
>> >
>> > -           omap_gpio_mod_init(bank, i);
>> > -           omap_gpio_chip_init(bank);
>> > +           bank->base = ioremap(res->start, resource_size(res));
>> > +           if (!bank->base) {
>> > +                   pr_err("Could not ioremap gpio bank%i\n", id);
>> > +                   return -ENOMEM;
>> > +           }
>> >
>> > -           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 (cpu_is_omap15xx() && (id == 0)) {
>> > +                   static struct clk *gpio_clk;
>> > +                   gpio_clk = clk_get(&pdev->dev, "arm_gpio_ck");
>> > +                   if (IS_ERR(gpio_clk))
>> > +                           pr_err("Could not get arm_gpio_ck\n");
>> > +                   else
>> > +                           clk_enable(gpio_clk);
>> >             }
>> >     }
>> >
>> > -   omap_gpio_show_rev();
>> > +   omap_gpio_mod_init(bank, id);
>> > +   omap_gpio_chip_init(bank);
>> >
>> > +   if (!gpio_init_done) {
>> > +           omap_gpio_show_rev();
>> > +           gpio_init_done = 1;
>> > +   }
>> > +
>> > +   bank->initialized = 1;
>>
>> I think you can drop this flag, and use is_early_platform_device() if
>> needed.
>
> Sure.
>>
>> >     return 0;
>> >  }
>> >
>> > @@ -2210,16 +2074,42 @@ void omap_gpio_restore_context(void)
>> >  }
>> >  #endif
>> >
>> > -/*
>> > - * This may get called early from board specific init
>> > - * for boards that have interrupts routed via FPGA.
>> > - */
>> > +static struct platform_driver omap_gpio_driver = {
>> > +   .probe          = omap_gpio_probe,
>> > +   .driver         = {
>> > +           .name   = "omap-gpio",
>> > +   },
>> > +};
>> > +
>> > +int __init omap_gpio_drv_reg(void)
>> > +{
>> > +   return platform_driver_register(&omap_gpio_driver);
>> > +}
>> > +
>> > +early_platform_init("earlygpio", &omap_gpio_driver);
>> > +
>> >  int __init omap_gpio_init(void)
>> >  {
>> > -   if (!initialized)
>> > -           return _omap_gpio_init();
>> > -   else
>> > +   int ret = 0;
>> > +
>> > +   if (initialized)
>> >             return 0;
>> > +
>> > +#ifdef CONFIG_ARCH_OMAP1
>> > +   if (cpu_is_omap7xx())
>> > +           ret = omap7xx_gpio_init();
>> > +   if (cpu_is_omap15xx())
>> > +           ret = omap15xx_gpio_init();
>> > +   if (cpu_is_omap16xx())
>> > +           ret = omap16xx_gpio_init();
>> > +#endif
>> > +#ifdef CONFIG_ARCH_OMAP2PLUS
>> > +   if (cpu_class_is_omap2())
>> > +           ret = omap2_gpio_init();
>> > +#endif
>>
>> No thanks.  driver init should not be calling device init.  The device
>> init should have it's own initcall or be called by other early device
>> init.
>
> Agreed. omap_gpio_init() does nothing but calling device_init().
>
> But having omap_gpio_init() isn't a problem for OMAP2+, whereas it
> would break multi-omap build for OMAP1 because there are 3 files in
> mach-omap1 for each omap.
>
> 1. I can club all the 3 gpio files in mach-omap1 in to one file
> mach-omap1/gpio.c and use omap_gpio_init() in it. But the patch
> size and file size might be much bigger as the platform_data for all
> OMAP1 GPIO devices would be available in this file.
>
> 2. (or) While maintaining 3 different files for mach-omap1/gpio_xxx.c,
> modify the board files (about 20 files) of mach-omap1 and make use
> of SoC specific omap_gpio_init.
>
> 3. (or) Call gpio_init() from omap_init_common_hw() by removing the calls
> from board files and do a cpu_is check (for mach-omap1) in it.
>
> Please suggest if we have any other ways to handle this and the better
> way to handle this.

I prefer 3.

Kevin

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

* Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-04-22 15:55         ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS " Charulatha V
  2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
  2010-04-30 23:03           ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO Kevin Hilman
@ 2010-05-05 22:31           ` Tony Lindgren
  2010-05-07  6:52             ` Varadarajan, Charulatha
  2010-05-12 12:29             ` Varadarajan, Charulatha
  2 siblings, 2 replies; 33+ messages in thread
From: Tony Lindgren @ 2010-05-05 22:31 UTC (permalink / raw)
  To: Charulatha V; +Cc: linux-omap, rnayak, paul, khilman

* Charulatha V <charu@ti.com> [100422 08:50]:
> This patch adds support for handling GPIO as a HWMOD adapted
> platform device for OMAP2PLUS chips.

<snip>

> +int __init gpio_init(void)
> +{
> +	int i = 0;
> +	static int is_early_device = true;
> +
> +	do {
> +		struct omap_device *od;
> +		struct omap_hwmod *oh;
> +		int hw_mod_name_len = 16;
> +		int l;
> +		char oh_name[hw_mod_name_len];
> +		struct omap_gpio_platform_data *pdata;
> +		char *name = "omap-gpio";
> +
> +		l = snprintf(oh_name, hw_mod_name_len, "gpio%d_hwmod", i + 1);
> +		WARN(l >= hw_mod_name_len,
> +			"String buffer overflow in GPIO device setup\n");
> +
> +		oh = omap_hwmod_lookup(oh_name);
> +		if (!oh) {
> +			pr_err("Could not look up %s\n", oh_name);
> +			i++;
> +			continue;
> +		}
> +
> +		pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> +					GFP_KERNEL);
> +		if (!pdata) {
> +			pr_err("Memory allocation failed gpio%d\n", i + 1);
> +			return -ENOMEM;
> +		}
> +		pdata->base = oh->_rt_va;
> +		pdata->irq = oh->mpu_irqs[0].irq;
> +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
> +			pdata->method = METHOD_GPIO_24XX;
> +		if (cpu_is_omap44xx())
> +			pdata->method = METHOD_GPIO_44XX;
> +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
> +		pdata->device_enable = omap_device_enable;
> +		pdata->device_idle = omap_device_idle;
> +		pdata->device_shutdown = omap_device_shutdown;
> +
> +		od = omap_device_build(name, i, oh, pdata,
> +					sizeof(*pdata),	omap_gpio_latency,
> +					ARRAY_SIZE(omap_gpio_latency),
> +					is_early_device);
> +		WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> +					name, oh->name);
> +
> +		i++;
> +	} while (i < gpio_bank_count);
> +	is_early_device = false;
> +
> +	return 0;
> +}
> +arch_initcall(gpio_init);

You can get rid of most of the cpu_is_omapxxxx in gpio_init if you pass
the method as a parameter to gpio_init(int method). We should only need
to use cpu_is_omap exactly once for every init.

> +int __init omap2_gpio_init(void)
> +{
> +	if (cpu_is_omap242x())
> +		gpio_bank_count = 4;
> +	else if (cpu_is_omap243x())
> +		gpio_bank_count = 5;
> +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> +		gpio_bank_count = OMAP34XX_NR_GPIOS;
> +
> +	if (gpio_init())
> +		return -EINVAL;
> +
> +	early_platform_driver_register_all("earlygpio");
> +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
> +	return 0;
> +}

Then please replace this init with something like:

#ifdef CONFIG_ARCH_OMAP2
int __init omap242x_gpio_init(void)
{
	if (!cpu_is_omap2420())
		return -EINVAL;

	gpio_bank_count = 4;

	return gpio_init(METHOD_GPIO_24XX);
}
subsys_initcall(omap242x_gpio_init);

int __init omap243x_gpio_init(void)
{
	if (!cpu_is_omap2430())
		return -EINVAL;

	gpio_bank_count = 5;

	return gpio_init(METHOD_GPIO_24XX);
}
subsys_initcall(omap243x_gpio_init);
#endif

#ifdef CONFIG_ARCH_OMAP3
int __init omap34xx_gpio_init(void)
{
	if (!cpu_is_omap34xx())
		return -EINVAL;

	gpio_bank_count = OMAP34X_NR_GPIOS;

	return gpio_init(METHOD_GPIO_34XX);
}
subsys_initcall(omap34xx_gpio_init);
#endif
...

This way it will be more future proof when new omaps get added
and the if else stuff disappears. Also then you'll have an omap
specific function to initialize the gpio stuff.

Note that then early_platform_driver_register_all and
early_platform_driver_probe can be moved to gpio_init.

With multi-omap build the subsys_initcall runs for all of the
selected platforms, but returns early except for the machine
we're running on. All the code is optimized out for omap
specific product kernels.

Regards,

Tony

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

* Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-05 20:59                       ` Kevin Hilman
@ 2010-05-05 22:37                         ` Tony Lindgren
  2010-05-07  6:52                         ` Varadarajan, Charulatha
  2010-05-12 12:29                         ` Varadarajan, Charulatha
  2 siblings, 0 replies; 33+ messages in thread
From: Tony Lindgren @ 2010-05-05 22:37 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Varadarajan, Charulatha, linux-omap, Nayak, Rajendra, paul

* Kevin Hilman <khilman@deeprootsystems.com> [100505 13:54]:
> "Varadarajan, Charulatha" <charu@ti.com> writes:
> 
> >> -----Original Message-----
> >> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> >
> > 2. omap_init_irq() needs to be completed before calling early_gpio_init().
> > So, if early_gpio_init() is called from omap2_init_common_hw(), we need to
> > have omap_init_irq() called before omap2_init_common_hw(). But Tony
> > objected this approach mentioning that board might not boot up as
> > omap2_init_common_hw() has to be done asap.
> >
> > That's why, I had not moved the omap_gpio_init() usage from board files.
> 
> OK... for now.  I'd still like to see GPIO init consolidated as there's
> no (good) reason why every board file has to init GPIOs when it's common
> for all SoCs, but this doesn't necessarily have to be done in your series.
> Although, if you do it for OMAP1 (as proposed below) you should do similar
> for OMAP2+.

Let's try to use just arch/subsys_initcall for starting the GPIO. AFAIK
we don't need it earlier than that. See also my comments to the patch 5/9.

Regards,

Tony
 

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

* RE: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-05 20:59                       ` Kevin Hilman
  2010-05-05 22:37                         ` Tony Lindgren
@ 2010-05-07  6:52                         ` Varadarajan, Charulatha
  2010-05-12 12:29                         ` Varadarajan, Charulatha
  2 siblings, 0 replies; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-07  6:52 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, Nayak, Rajendra, paul, tony



> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> Sent: Thursday, May 06, 2010 2:30 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com; tony@atomide.com
> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
>
> "Varadarajan, Charulatha" <charu@ti.com> writes:
>
> >> -----Original Message-----
> >> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> >> Sent: Saturday, May 01, 2010 5:34 AM
> >> To: Varadarajan, Charulatha
> >> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
> tony@atomide.com
> >> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
> >>
> >> Charulatha V <charu@ti.com> writes:
> >>
> >> > This patch implements GPIO as a early platform device. Also it
> >> > implements OMAP2PLUS specific GPIO as HWMOD FW adapted driver.
> >>
> >> Should include a summary explanation of why you're converting to an
> >> early platform device as well.
> >
> > Okay.
> >
> >>
> >> > Inorder to convert GPIO as platform device, modifications are
> >> > required in clockxxxx_data.c files so that device names can be
> >> > used to obtain clock instead of getting clocks by name/NULL ptr.
> >>
> >> ok
> >>
> >> > Currently early platform device register does not do device_pm_init.
> >> > Hence pm_runtime functions are not used to enable the GPIO device
> >> > since gpio is early platform device.
> >>
> >> OK for now, since this isn't using runtime PM, but maybe we need a
> >> late_initcall() here to do the device_pm_init() + pm_runtime_enable()
> >>
> >> This change log needs more description of the intended init sequence.
> >> Right now it seems that there are multiple init paths.  Now that GPIO
> >> is an early_platform_device, we should be able to at least make
> >> omap_gpio_init() static and remove its usage from all the board files.
> >
> > This was the implementation that I initially did in my previous patch
> > series. The following needs to be considered:
> >
> > 1. omap2_init_devices() might be too late for early_gpio_init() to
> > be placed in it.
> >
> > 2. omap_init_irq() needs to be completed before calling early_gpio_init().
> > So, if early_gpio_init() is called from omap2_init_common_hw(), we need to
> > have omap_init_irq() called before omap2_init_common_hw(). But Tony
> > objected this approach mentioning that board might not boot up as
> > omap2_init_common_hw() has to be done asap.
> >
> > That's why, I had not moved the omap_gpio_init() usage from board files.
>
> OK... for now.  I'd still like to see GPIO init consolidated as there's
> no (good) reason why every board file has to init GPIOs when it's common
> for all SoCs, but this doesn't necessarily have to be done in your series.
> Although, if you do it for OMAP1 (as proposed below) you should do similar
> for OMAP2+.

Okay. Will use arch/subsys_initcall for starting the GPIO as per Tony's
suggestion.

>
> >>
> >> Also, the driver and device separation and init is totally mixed
> >> together and very confusing. The platform_driver is in
> >
> > Agreed. Please see my comment at the end of this patch in reply to your
> > other similar comment.
> >
> >
> >> plat-omap/gpio.c and should be doing the driver init:
> >> [early_]platform_driver_register() and _probe(). The platform_device
> >> setup is in mach-omapX/gpio*.c and where the device init should be, in
> >> this case early_platform_add_devices().
> >
> > In early_gpio_init, omap_device_build() (device specific) and
> > early_platform_driver_register_all() (driver specific), _probe() are
> > done in a sequence. This is because early_gpio_init needs to be called
> > asap and if we try to split this device specific and driver specific
> > early_inits, we will end up having two init calls for each early drivers.
> >
> > I feel that multiple function calls for early_init (one for driver probe and
> > one for device register) should be avoided as we need to find the right place
> > to call them.
>
> But your driver probe is already in a separate init path (via
> arch_initcall) from your device init path omap_gpio_init().
>
> My problem is that there is a 2nd driver init path:
> board file -> [driver]omap_gpio_init() -> [device] <soc>_gpio_init()
>
> The fact that it goes through the driver is what I don't like.
>

Okay.

> >>
> >>
> >> > Signed-off-by: Charulatha V <charu@ti.com>
> >> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> >> > ---
> >> >  arch/arm/mach-omap1/Makefile           |    6 +
> >> >  arch/arm/mach-omap1/clock_data.c       |    2 +-
> >> >  arch/arm/mach-omap2/Makefile           |    2 +-
> >> >  arch/arm/mach-omap2/clock2420_data.c   |   10 +-
> >> >  arch/arm/mach-omap2/clock2430_data.c   |   14 +-
> >> >  arch/arm/mach-omap2/clock3xxx_data.c   |   24 +-
> >> >  arch/arm/mach-omap2/clock44xx_data.c   |   24 +-
> >> >  arch/arm/plat-omap/gpio.c              |  405 ++++++++++++------------------
> --
> >> >  arch/arm/plat-omap/include/plat/gpio.h |   21 ++
> >> >  9 files changed, 220 insertions(+), 288 deletions(-)
> >>
> >> [...]
> >>
> >> > @@ -1621,6 +1501,34 @@ static void __init omap_gpio_show_rev(void)
> >> >   */
> >> >  static struct lock_class_key gpio_lock_class;
> >> >
> >> > +static int init_gpio_info(void)
> >> > +{
> >> > +   gpio_bank_bits = 32;
> >> > +
> >> > +   if (cpu_is_omap15xx()) {
> >> > +           gpio_bank_count = 2;
> >> > +           gpio_bank_bits = 16;
> >> > +   } else if (cpu_is_omap16xx()) {
> >> > +           gpio_bank_count = 5;
> >> > +           gpio_bank_bits = 16;
> >> > +   } else if (cpu_is_omap7xx())
> >> > +           gpio_bank_count = 7;
> >> > +   else if (cpu_is_omap242x())
> >> > +           gpio_bank_count = 4;
> >> > +   else if (cpu_is_omap243x())
> >> > +           gpio_bank_count = 5;
> >> > +   else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> >> > +           gpio_bank_count = OMAP34XX_NR_GPIOS;
> >>
> >> Both the bank count and bank bits could be part of platform_data
> >> and set in the SoC specific init.  This is the GPIO driver part
> >> and we're trying to make this as SoC independent as possible.  Anytime
> >> you need to add a cpu_is* or #ifdef in this code indicates something
> >> that should be part of SoC specific init and passed in.
> >
> > bank count and bank bits are not specific to each device, but SoC specific.
> > Hence I did not consider passing it as part of platform_data, because this
> information would be duplicated across all devices in that SoC.
> >
> > It would be good if we have a way to pass the SoC specific data which is
> > common for all the devices rather than duplicating them by sending them via
> > platform_data.
> >
> > Anyways, I can move it to platform_data if there is no other way.
>
> Probably the right place for the SoC specifics is attached to the SoC
> specific hwmod using the dev_attr pointer.  That struct can then
> be passed in via platform_data.
>
> You can see how Thara did this for SmartReflex as an example.

Okay.

>
> >>
> >> > +   gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
> >> > +                           GFP_KERNEL);
> >> > +   if (!gpio_bank) {
> >> > +           pr_err("Memory allocation 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()) {
> >> > @@ -1686,16 +1594,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, gpio_bank_bits = 16;
> >> > +   int j;
> >> >     static int gpio;
> >> >
> >> > -   if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX)
> >> > -           gpio_bank_bits = 32; /* 7xx has 32-bit GPIOs */
> >> > -
> >> > -   if ((bank->method == METHOD_GPIO_24XX) ||
> >> > -                   (bank->method == METHOD_GPIO_44XX))
> >> > -           gpio_bank_bits = 32;
> >> > -
> >> >     bank->mod_usage = 0;
> >> >     /* REVISIT eventually switch from OMAP-specific gpio structs
> >> >      * over to the generic ones
> >> > @@ -1737,140 +1638,103 @@ 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 inline void get_gpio_dbck(struct platform_device *pdev,
> >> > +                           struct gpio_bank *bank)
> >> >  {
> >> > -   int i;
> >> > -   int gpio = 0;
> >> > +   if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
> >> > +           bank->dbck = clk_get(&pdev->dev, "dbck");
> >> > +           if (IS_ERR(bank->dbck))
> >> > +                   pr_err("GPIO: Could not get dbck\n");
> >> > +   }
> >> > +}
> >> > +static int __devinit omap_gpio_probe(struct platform_device *pdev)
> >> > +{
> >> > +   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 (!gpio_init_done)
> >> > +           init_gpio_info();
> >> >
> >> > -#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);
> >> > +   if (!pdev || !pdev->dev.platform_data) {
> >> > +           pr_err("GPIO device initialize without"
> >> > +                                   "platform data\n");
> >> > +           return -EINVAL;
> >> >     }
> >> > -#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);
> >> >
> >> > -           /*
> >> > -            * 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
> >> > +   pdata = pdev->dev.platform_data;
> >> >
> >> > -#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]);
> >> > -           }
> >> > +   id = pdev->id;
> >> > +   if (id > gpio_bank_count) {
> >> > +           pr_err("Invalid GPIO device id (%d)\n", id);
> >> > +           return -EINVAL;
> >> >     }
> >> > -#endif
> >> >
> >> > +   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;
> >> > +   if (bank->initialized == 1) {
> >>
> >> is_early_platform_device() can be used to tell if the _probe() is
> >> being called as part of early platform driver probe or "regular".
> >
> > Okay.
> >
> >>
> >> > +           /*
> >> > +            * Currently, for early platform_devices,
> >> > +            * clk_get() using dev ptr does not seem to be working
> >> > +            * Hence getting dbck during regular device probe
> >> > +            */
> >>
> >> Need a better explanation here.  "does not seem to work" is not
> >> quite good enough.
> >
> > Okay.
> > The reason for "does not seem to work" is that device_initialize()
> > is not called as part of omap_early_device_register and the clk_get
> > could not find the clock using dev pointer.
>
> OK, should be as part of this comment if you keep it here.
>
> >>
> >> > +           get_gpio_dbck(pdev, bank);
> >>
> >> In any case, maybe it's better to defer the clk_get() into
> >> the debounce setup and only use if needed.
> >
> > Then, this needs to be done only in omap_set_gpio_debounce() which does
> > not have pdev->dev info. I can take care of this.
>
> OK good. That's probably cleaner than doing it at init time anyways.
>
> >>
> >> > +           return 0;
> >> >     }
> >> > -#endif
> >> > -#ifdef CONFIG_ARCH_OMAP4
> >> > -   if (cpu_is_omap44xx()) {
> >> > -           gpio_bank_count = OMAP34XX_NR_GPIOS;
> >> > -           gpio_bank = gpio_bank_44xx;
> >> > +
> >> > +   res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> >> > +   if (unlikely(!res)) {
> >> > +           pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
> >> > +           return -ENODEV;
> >> >     }
> >> > -#endif
> >> > -   for (i = 0; i < gpio_bank_count; i++) {
> >> > +   bank->irq = res->start;
> >> > +   bank->virtual_irq_start = pdata->virtual_irq_start;
> >> > +   bank->base = pdata->base;
> >>
> >> Why are you using pdata->base for OMAP2+ base addresses...
> > Thanks for pointing this. I will correct it.
> >
> >>
> >> > +   bank->method = pdata->method;
> >> >
> >> > -           bank = &gpio_bank[i];
> >> > -           spin_lock_init(&bank->lock);
> >> > +   spin_lock_init(&bank->lock);
> >> >
> >> > +   if (cpu_class_is_omap2()) {
> >> > +           bank->device_enable = pdata->device_enable;
> >> > +           bank->device_idle = pdata->device_idle;
> >> > +           bank->device_shutdown = pdata->device_shutdown;
> >> > +           pdata->device_enable(pdev);
> >> > +   } else if (cpu_class_is_omap1()) {
> >> >             /* 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;
> >> > +           res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>
> >> ... and doing it the right way here for OMAP1?
> >>
> >> platform_get_resource() should be used for both.
> >
> > Yes.
> >
> >>
> >> > +           if (unlikely(!res)) {
> >> > +                   pr_err("GPIO Bank %i Invalid mem resource\n", id);
> >> > +                   return -ENODEV;
> >> >             }
> >> >
> >> > -           omap_gpio_mod_init(bank, i);
> >> > -           omap_gpio_chip_init(bank);
> >> > +           bank->base = ioremap(res->start, resource_size(res));
> >> > +           if (!bank->base) {
> >> > +                   pr_err("Could not ioremap gpio bank%i\n", id);
> >> > +                   return -ENOMEM;
> >> > +           }
> >> >
> >> > -           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 (cpu_is_omap15xx() && (id == 0)) {
> >> > +                   static struct clk *gpio_clk;
> >> > +                   gpio_clk = clk_get(&pdev->dev, "arm_gpio_ck");
> >> > +                   if (IS_ERR(gpio_clk))
> >> > +                           pr_err("Could not get arm_gpio_ck\n");
> >> > +                   else
> >> > +                           clk_enable(gpio_clk);
> >> >             }
> >> >     }
> >> >
> >> > -   omap_gpio_show_rev();
> >> > +   omap_gpio_mod_init(bank, id);
> >> > +   omap_gpio_chip_init(bank);
> >> >
> >> > +   if (!gpio_init_done) {
> >> > +           omap_gpio_show_rev();
> >> > +           gpio_init_done = 1;
> >> > +   }
> >> > +
> >> > +   bank->initialized = 1;
> >>
> >> I think you can drop this flag, and use is_early_platform_device() if
> >> needed.
> >
> > Sure.
> >>
> >> >     return 0;
> >> >  }
> >> >
> >> > @@ -2210,16 +2074,42 @@ void omap_gpio_restore_context(void)
> >> >  }
> >> >  #endif
> >> >
> >> > -/*
> >> > - * This may get called early from board specific init
> >> > - * for boards that have interrupts routed via FPGA.
> >> > - */
> >> > +static struct platform_driver omap_gpio_driver = {
> >> > +   .probe          = omap_gpio_probe,
> >> > +   .driver         = {
> >> > +           .name   = "omap-gpio",
> >> > +   },
> >> > +};
> >> > +
> >> > +int __init omap_gpio_drv_reg(void)
> >> > +{
> >> > +   return platform_driver_register(&omap_gpio_driver);
> >> > +}
> >> > +
> >> > +early_platform_init("earlygpio", &omap_gpio_driver);
> >> > +
> >> >  int __init omap_gpio_init(void)
> >> >  {
> >> > -   if (!initialized)
> >> > -           return _omap_gpio_init();
> >> > -   else
> >> > +   int ret = 0;
> >> > +
> >> > +   if (initialized)
> >> >             return 0;
> >> > +
> >> > +#ifdef CONFIG_ARCH_OMAP1
> >> > +   if (cpu_is_omap7xx())
> >> > +           ret = omap7xx_gpio_init();
> >> > +   if (cpu_is_omap15xx())
> >> > +           ret = omap15xx_gpio_init();
> >> > +   if (cpu_is_omap16xx())
> >> > +           ret = omap16xx_gpio_init();
> >> > +#endif
> >> > +#ifdef CONFIG_ARCH_OMAP2PLUS
> >> > +   if (cpu_class_is_omap2())
> >> > +           ret = omap2_gpio_init();
> >> > +#endif
> >>
> >> No thanks.  driver init should not be calling device init.  The device
> >> init should have it's own initcall or be called by other early device
> >> init.
> >
> > Agreed. omap_gpio_init() does nothing but calling device_init().
> >
> > But having omap_gpio_init() isn't a problem for OMAP2+, whereas it
> > would break multi-omap build for OMAP1 because there are 3 files in
> > mach-omap1 for each omap.
> >
> > 1. I can club all the 3 gpio files in mach-omap1 in to one file
> > mach-omap1/gpio.c and use omap_gpio_init() in it. But the patch
> > size and file size might be much bigger as the platform_data for all
> > OMAP1 GPIO devices would be available in this file.
> >
> > 2. (or) While maintaining 3 different files for mach-omap1/gpio_xxx.c,
> > modify the board files (about 20 files) of mach-omap1 and make use
> > of SoC specific omap_gpio_init.
> >
> > 3. (or) Call gpio_init() from omap_init_common_hw() by removing the calls
> > from board files and do a cpu_is check (for mach-omap1) in it.
> >
> > Please suggest if we have any other ways to handle this and the better
> > way to handle this.
>
> I prefer 3.

Okay. New patch series would be posted in another 2 weeks.

>
> Kevin

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

* RE: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-05-05 22:31           ` Tony Lindgren
@ 2010-05-07  6:52             ` Varadarajan, Charulatha
  2010-05-12 12:29             ` Varadarajan, Charulatha
  1 sibling, 0 replies; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-07  6:52 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap, Nayak, Rajendra, paul, khilman



> -----Original Message-----
> From: Tony Lindgren [mailto:tony@atomide.com]
> Sent: Thursday, May 06, 2010 4:02 AM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
> khilman@deeprootsystems.com
> Subject: Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific
> GPIO
> 
> * Charulatha V <charu@ti.com> [100422 08:50]:
> > This patch adds support for handling GPIO as a HWMOD adapted
> > platform device for OMAP2PLUS chips.
> 
> <snip>
> 
> > +int __init gpio_init(void)
> > +{
> > +	int i = 0;
> > +	static int is_early_device = true;
> > +
> > +	do {
> > +		struct omap_device *od;
> > +		struct omap_hwmod *oh;
> > +		int hw_mod_name_len = 16;
> > +		int l;
> > +		char oh_name[hw_mod_name_len];
> > +		struct omap_gpio_platform_data *pdata;
> > +		char *name = "omap-gpio";
> > +
> > +		l = snprintf(oh_name, hw_mod_name_len, "gpio%d_hwmod", i + 1);
> > +		WARN(l >= hw_mod_name_len,
> > +			"String buffer overflow in GPIO device setup\n");
> > +
> > +		oh = omap_hwmod_lookup(oh_name);
> > +		if (!oh) {
> > +			pr_err("Could not look up %s\n", oh_name);
> > +			i++;
> > +			continue;
> > +		}
> > +
> > +		pdata = kzalloc(sizeof(struct omap_gpio_platform_data),
> > +					GFP_KERNEL);
> > +		if (!pdata) {
> > +			pr_err("Memory allocation failed gpio%d\n", i + 1);
> > +			return -ENOMEM;
> > +		}
> > +		pdata->base = oh->_rt_va;
> > +		pdata->irq = oh->mpu_irqs[0].irq;
> > +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
> > +			pdata->method = METHOD_GPIO_24XX;
> > +		if (cpu_is_omap44xx())
> > +			pdata->method = METHOD_GPIO_44XX;
> > +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
> > +		pdata->device_enable = omap_device_enable;
> > +		pdata->device_idle = omap_device_idle;
> > +		pdata->device_shutdown = omap_device_shutdown;
> > +
> > +		od = omap_device_build(name, i, oh, pdata,
> > +					sizeof(*pdata),	omap_gpio_latency,
> > +					ARRAY_SIZE(omap_gpio_latency),
> > +					is_early_device);
> > +		WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
> > +					name, oh->name);
> > +
> > +		i++;
> > +	} while (i < gpio_bank_count);
> > +	is_early_device = false;
> > +
> > +	return 0;
> > +}
> > +arch_initcall(gpio_init);
> 
> You can get rid of most of the cpu_is_omapxxxx in gpio_init if you pass
> the method as a parameter to gpio_init(int method). We should only need
> to use cpu_is_omap exactly once for every init.

Okay.

> 
> > +int __init omap2_gpio_init(void)
> > +{
> > +	if (cpu_is_omap242x())
> > +		gpio_bank_count = 4;
> > +	else if (cpu_is_omap243x())
> > +		gpio_bank_count = 5;
> > +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> > +		gpio_bank_count = OMAP34XX_NR_GPIOS;
> > +
> > +	if (gpio_init())
> > +		return -EINVAL;
> > +
> > +	early_platform_driver_register_all("earlygpio");
> > +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
> > +	return 0;
> > +}
> 
> Then please replace this init with something like:

Okay.

> 
> #ifdef CONFIG_ARCH_OMAP2
> int __init omap242x_gpio_init(void)
> {
> 	if (!cpu_is_omap2420())
> 		return -EINVAL;
> 
> 	gpio_bank_count = 4;
> 
> 	return gpio_init(METHOD_GPIO_24XX);
> }
> subsys_initcall(omap242x_gpio_init);
> 
> int __init omap243x_gpio_init(void)
> {
> 	if (!cpu_is_omap2430())
> 		return -EINVAL;
> 
> 	gpio_bank_count = 5;
> 
> 	return gpio_init(METHOD_GPIO_24XX);
> }
> subsys_initcall(omap243x_gpio_init);
> #endif
> 
> #ifdef CONFIG_ARCH_OMAP3
> int __init omap34xx_gpio_init(void)
> {
> 	if (!cpu_is_omap34xx())
> 		return -EINVAL;
> 
> 	gpio_bank_count = OMAP34X_NR_GPIOS;
> 
> 	return gpio_init(METHOD_GPIO_34XX);
> }
> subsys_initcall(omap34xx_gpio_init);
> #endif
> ...
> 
> This way it will be more future proof when new omaps get added
> and the if else stuff disappears. Also then you'll have an omap
> specific function to initialize the gpio stuff.
> 
> Note that then early_platform_driver_register_all and
> early_platform_driver_probe can be moved to gpio_init.
> 
> With multi-omap build the subsys_initcall runs for all of the
> selected platforms, but returns early except for the machine
> we're running on. All the code is optimized out for omap
> specific product kernels.

Okay. Will do the needful and send new patch series in 2 weeks.

> 
> Regards,
> 
> Tony

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

* RE: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-04-22 15:55 [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Charulatha V
  2010-04-22 15:55 ` [PATCH 1/9] OMAP:GPIO: Modify init() in preparation for platform device implementation Charulatha V
@ 2010-05-07  6:57 ` Varadarajan, Charulatha
  2010-05-07 15:32   ` Tony Lindgren
  1 sibling, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-07  6:57 UTC (permalink / raw)
  To: tony, khilman; +Cc: Nayak, Rajendra, paul, linux-omap

Tony/ Kevin,

> -----Original Message-----
> From: Varadarajan, Charulatha
> Sent: Thursday, April 22, 2010 9:25 PM
> To: linux-omap@vger.kernel.org
> Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
> khilman@deeprootsystems.com; Varadarajan, Charulatha
> Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
> 
> This patch series implements GPIO as an early platform driver.
> It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
> OMAP1 specific GPIO is implemented as early platform device.
> 
> This patch series is created on "origin/pm-wip/hwmods". 

Planning to send few more patches for adapting some other
drivers to HWMOD FW. 
Which tree should those patches be created on?
LO mainline? or hwmods branch? or runtime branch?

-V Charulatha

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

* Re: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-05-07  6:57 ` [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Varadarajan, Charulatha
@ 2010-05-07 15:32   ` Tony Lindgren
  2010-05-10 15:14     ` Kevin Hilman
  0 siblings, 1 reply; 33+ messages in thread
From: Tony Lindgren @ 2010-05-07 15:32 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: khilman, Nayak, Rajendra, paul, linux-omap

* Varadarajan, Charulatha <charu@ti.com> [100506 23:52]:
> Tony/ Kevin,
> 
> > -----Original Message-----
> > From: Varadarajan, Charulatha
> > Sent: Thursday, April 22, 2010 9:25 PM
> > To: linux-omap@vger.kernel.org
> > Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
> > khilman@deeprootsystems.com; Varadarajan, Charulatha
> > Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
> > 
> > This patch series implements GPIO as an early platform driver.
> > It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
> > OMAP1 specific GPIO is implemented as early platform device.
> > 
> > This patch series is created on "origin/pm-wip/hwmods". 
> 
> Planning to send few more patches for adapting some other
> drivers to HWMOD FW. 
> Which tree should those patches be created on?
> LO mainline? or hwmods branch? or runtime branch?

All the patches should be against the most recent tag
in Linus' mainline tree, currently v2.6.34-rc6.

If there are some dependencies to other patches, we need
to get those upstream immediately.

Regards,

Tony

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

* Re: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-05-07 15:32   ` Tony Lindgren
@ 2010-05-10 15:14     ` Kevin Hilman
  2010-05-10 22:22       ` Tony Lindgren
  0 siblings, 1 reply; 33+ messages in thread
From: Kevin Hilman @ 2010-05-10 15:14 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Varadarajan, Charulatha, Nayak, Rajendra, paul, linux-omap

Tony Lindgren <tony@atomide.com> writes:

> * Varadarajan, Charulatha <charu@ti.com> [100506 23:52]:
>> Tony/ Kevin,
>> 
>> > -----Original Message-----
>> > From: Varadarajan, Charulatha
>> > Sent: Thursday, April 22, 2010 9:25 PM
>> > To: linux-omap@vger.kernel.org
>> > Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
>> > khilman@deeprootsystems.com; Varadarajan, Charulatha
>> > Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
>> > 
>> > This patch series implements GPIO as an early platform driver.
>> > It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
>> > OMAP1 specific GPIO is implemented as early platform device.
>> > 
>> > This patch series is created on "origin/pm-wip/hwmods". 
>> 
>> Planning to send few more patches for adapting some other
>> drivers to HWMOD FW. 
>> Which tree should those patches be created on?
>> LO mainline? or hwmods branch? or runtime branch?
>
> All the patches should be against the most recent tag
> in Linus' mainline tree, currently v2.6.34-rc6.
>
> If there are some dependencies to other patches, we need
> to get those upstream immediately.

Please use pm-wip/runtime, which is currently based on v2.6.34-rc6
+ PM changes already submitted for 2.6.35 (3 patches)

In addition, this has the in-progress UART + MMC hwmod changes.

Kevin

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

* Re: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-05-10 15:14     ` Kevin Hilman
@ 2010-05-10 22:22       ` Tony Lindgren
  2010-05-11 15:21         ` Kevin Hilman
  0 siblings, 1 reply; 33+ messages in thread
From: Tony Lindgren @ 2010-05-10 22:22 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Varadarajan, Charulatha, Nayak, Rajendra, paul, linux-omap

* Kevin Hilman <khilman@deeprootsystems.com> [100510 08:09]:
> Tony Lindgren <tony@atomide.com> writes:
> 
> > * Varadarajan, Charulatha <charu@ti.com> [100506 23:52]:
> >> Tony/ Kevin,
> >> 
> >> > -----Original Message-----
> >> > From: Varadarajan, Charulatha
> >> > Sent: Thursday, April 22, 2010 9:25 PM
> >> > To: linux-omap@vger.kernel.org
> >> > Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
> >> > khilman@deeprootsystems.com; Varadarajan, Charulatha
> >> > Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
> >> > 
> >> > This patch series implements GPIO as an early platform driver.
> >> > It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
> >> > OMAP1 specific GPIO is implemented as early platform device.
> >> > 
> >> > This patch series is created on "origin/pm-wip/hwmods". 
> >> 
> >> Planning to send few more patches for adapting some other
> >> drivers to HWMOD FW. 
> >> Which tree should those patches be created on?
> >> LO mainline? or hwmods branch? or runtime branch?
> >
> > All the patches should be against the most recent tag
> > in Linus' mainline tree, currently v2.6.34-rc6.
> >
> > If there are some dependencies to other patches, we need
> > to get those upstream immediately.
> 
> Please use pm-wip/runtime, which is currently based on v2.6.34-rc6
> + PM changes already submitted for 2.6.35 (3 patches)

That's for the "few more patches for adapting some other drivers",
not for the GPIO patches, right?

AFAIK, the GPIO patches should not have dependencies to the pm-wip.

Kevin, let me know if you got some things ready to go that can
be pulled into omap-for-linus.

> In addition, this has the in-progress UART + MMC hwmod changes.

Sounds like those are not ready to go yet then. So I guess it's
currently only your pm-next that's ready to go?

Cheers,

Tony

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

* RE: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-05-04 15:59             ` Varadarajan, Charulatha
@ 2010-05-11 14:43               ` Varadarajan, Charulatha
  2010-05-11 15:25                 ` Kevin Hilman
  0 siblings, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-11 14:43 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, Nayak, Rajendra, paul, tony

Kevin,

> > -----Original Message-----
> > From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> > Sent: Saturday, May 01, 2010 4:33 AM
> > To: Varadarajan, Charulatha
> > Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
> tony@atomide.com
> > Subject: Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip
> specific
> > GPIO
> >
> > Charulatha V <charu@ti.com> writes:
> >
> > > This patch adds support for handling GPIO as a HWMOD adapted
> > > platform device for OMAP2PLUS chips.
> > >
> > > Signed-off-by: Charulatha V <charu@ti.com>
> > > ---
> > >  arch/arm/mach-omap2/gpio.c |  101
> ++++++++++++++++++++++++++++++++++++++++++++
> > >  1 files changed, 101 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..6424050
> > > --- /dev/null
> > > +++ b/arch/arm/mach-omap2/gpio.c
> > > @@ -0,0 +1,101 @@

..[snip]..

> > > +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
> > > +			pdata->method = METHOD_GPIO_24XX;
> > > +		if (cpu_is_omap44xx())
> > > +			pdata->method = METHOD_GPIO_44XX;
> > > +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
> > > +		pdata->device_enable = omap_device_enable;
> > > +		pdata->device_idle = omap_device_idle;
> > > +		pdata->device_shutdown = omap_device_shutdown;
> >
> > These aren't valid for GPIO1 which is in WKUP.  Maybe we need
> > to check if the hwmod is not in wkup_pwrdm before setting these?
> 
> I need to check how to implement this.
> 

There are two ways to implement this:
1. Use a flag in dev_attr of the device to indicate if the device belongs to
   WKUP domain
2. We can add an API in powerdomain FW to provide information if the 
   device belongs to a "always_on" domain or otherwise, and use 
   this API for each device.

Kindly suggest. 

-V Charulatha



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

* Re: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-05-10 22:22       ` Tony Lindgren
@ 2010-05-11 15:21         ` Kevin Hilman
  2010-05-11 15:54           ` Tony Lindgren
  0 siblings, 1 reply; 33+ messages in thread
From: Kevin Hilman @ 2010-05-11 15:21 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Varadarajan, Charulatha, Nayak, Rajendra, paul, linux-omap

Tony Lindgren <tony@atomide.com> writes:

> * Kevin Hilman <khilman@deeprootsystems.com> [100510 08:09]:
>> Tony Lindgren <tony@atomide.com> writes:
>> 
>> > * Varadarajan, Charulatha <charu@ti.com> [100506 23:52]:
>> >> Tony/ Kevin,
>> >> 
>> >> > -----Original Message-----
>> >> > From: Varadarajan, Charulatha
>> >> > Sent: Thursday, April 22, 2010 9:25 PM
>> >> > To: linux-omap@vger.kernel.org
>> >> > Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
>> >> > khilman@deeprootsystems.com; Varadarajan, Charulatha
>> >> > Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
>> >> > 
>> >> > This patch series implements GPIO as an early platform driver.
>> >> > It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
>> >> > OMAP1 specific GPIO is implemented as early platform device.
>> >> > 
>> >> > This patch series is created on "origin/pm-wip/hwmods". 
>> >> 
>> >> Planning to send few more patches for adapting some other
>> >> drivers to HWMOD FW. 
>> >> Which tree should those patches be created on?
>> >> LO mainline? or hwmods branch? or runtime branch?
>> >
>> > All the patches should be against the most recent tag
>> > in Linus' mainline tree, currently v2.6.34-rc6.
>> >
>> > If there are some dependencies to other patches, we need
>> > to get those upstream immediately.
>> 
>> Please use pm-wip/runtime, which is currently based on v2.6.34-rc6
>> + PM changes already submitted for 2.6.35 (3 patches)
>
> That's for the "few more patches for adapting some other drivers",
> not for the GPIO patches, right?
>
> AFAIK, the GPIO patches should not have dependencies to the pm-wip.

Basing on pm-wip/runtime is for a couple reasons, but the most
important is to avoid conflicts in the hwmod data files.  Since all the
hwmods are in the same file, it makes it easy for me to track them
if they apply onto existing hwmods.

> Kevin, let me know if you got some things ready to go that can
> be pulled into omap-for-linus.

Nothing yet for hwmod.  The stuff that's mostly done is UART + MMC,
but those both still need validation on OMAP2 and OMAP4.

>> In addition, this has the in-progress UART + MMC hwmod changes.
>
> Sounds like those are not ready to go yet then. So I guess it's
> currently only your pm-next that's ready to go?

I've submitted PM core stuff in pm-next and I've also submitted some
GPIO changes for 2.6.35.

I have a few more things to add to pm-next, and I'll be doing that
today.

Kevin

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

* Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-05-11 14:43               ` Varadarajan, Charulatha
@ 2010-05-11 15:25                 ` Kevin Hilman
  0 siblings, 0 replies; 33+ messages in thread
From: Kevin Hilman @ 2010-05-11 15:25 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: linux-omap, Nayak, Rajendra, paul, tony

"Varadarajan, Charulatha" <charu@ti.com> writes:


>> > -----Original Message-----
>> > From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>> > Sent: Saturday, May 01, 2010 4:33 AM
>> > To: Varadarajan, Charulatha
>> > Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
>> tony@atomide.com
>> > Subject: Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip
>> specific
>> > GPIO
>> >
>> > Charulatha V <charu@ti.com> writes:
>> >
>> > > This patch adds support for handling GPIO as a HWMOD adapted
>> > > platform device for OMAP2PLUS chips.
>> > >
>> > > Signed-off-by: Charulatha V <charu@ti.com>
>> > > ---
>> > >  arch/arm/mach-omap2/gpio.c |  101
>> ++++++++++++++++++++++++++++++++++++++++++++
>> > >  1 files changed, 101 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..6424050
>> > > --- /dev/null
>> > > +++ b/arch/arm/mach-omap2/gpio.c
>> > > @@ -0,0 +1,101 @@
>
> ..[snip]..
>
>> > > +		if (cpu_is_omap24xx() || cpu_is_omap34xx())
>> > > +			pdata->method = METHOD_GPIO_24XX;
>> > > +		if (cpu_is_omap44xx())
>> > > +			pdata->method = METHOD_GPIO_44XX;
>> > > +		pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i;
>> > > +		pdata->device_enable = omap_device_enable;
>> > > +		pdata->device_idle = omap_device_idle;
>> > > +		pdata->device_shutdown = omap_device_shutdown;
>> >
>> > These aren't valid for GPIO1 which is in WKUP.  Maybe we need
>> > to check if the hwmod is not in wkup_pwrdm before setting these?
>> 
>> I need to check how to implement this.
>> 
>
> There are two ways to implement this:
> 1. Use a flag in dev_attr of the device to indicate if the device belongs to
>    WKUP domain
> 2. We can add an API in powerdomain FW to provide information if the 
>    device belongs to a "always_on" domain or otherwise, and use 
>    this API for each device.
>

Actually, as I think about this more, my initial comment is wrong.

the omap_device* functions are perfectly valid for GPIO1 as they have
independent control that is managed by hwmod, so please ignore my
comment.  Your approach is fine.

Thanks,

Kevin



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

* Re: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
  2010-05-11 15:21         ` Kevin Hilman
@ 2010-05-11 15:54           ` Tony Lindgren
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Lindgren @ 2010-05-11 15:54 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Varadarajan, Charulatha, Nayak, Rajendra, paul, linux-omap

* Kevin Hilman <khilman@deeprootsystems.com> [100511 08:16]:
> Tony Lindgren <tony@atomide.com> writes:
> 
> > * Kevin Hilman <khilman@deeprootsystems.com> [100510 08:09]:
> >> Tony Lindgren <tony@atomide.com> writes:
> >> 
> >> > * Varadarajan, Charulatha <charu@ti.com> [100506 23:52]:
> >> >> Tony/ Kevin,
> >> >> 
> >> >> > -----Original Message-----
> >> >> > From: Varadarajan, Charulatha
> >> >> > Sent: Thursday, April 22, 2010 9:25 PM
> >> >> > To: linux-omap@vger.kernel.org
> >> >> > Cc: Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
> >> >> > khilman@deeprootsystems.com; Varadarajan, Charulatha
> >> >> > Subject: [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way
> >> >> > 
> >> >> > This patch series implements GPIO as an early platform driver.
> >> >> > It makes OMAP2PLUS specific GPIO to get adapted to HWMOD FW.
> >> >> > OMAP1 specific GPIO is implemented as early platform device.
> >> >> > 
> >> >> > This patch series is created on "origin/pm-wip/hwmods". 
> >> >> 
> >> >> Planning to send few more patches for adapting some other
> >> >> drivers to HWMOD FW. 
> >> >> Which tree should those patches be created on?
> >> >> LO mainline? or hwmods branch? or runtime branch?
> >> >
> >> > All the patches should be against the most recent tag
> >> > in Linus' mainline tree, currently v2.6.34-rc6.
> >> >
> >> > If there are some dependencies to other patches, we need
> >> > to get those upstream immediately.
> >> 
> >> Please use pm-wip/runtime, which is currently based on v2.6.34-rc6
> >> + PM changes already submitted for 2.6.35 (3 patches)
> >
> > That's for the "few more patches for adapting some other drivers",
> > not for the GPIO patches, right?
> >
> > AFAIK, the GPIO patches should not have dependencies to the pm-wip.
> 
> Basing on pm-wip/runtime is for a couple reasons, but the most
> important is to avoid conflicts in the hwmod data files.  Since all the
> hwmods are in the same file, it makes it easy for me to track them
> if they apply onto existing hwmods.
> 
> > Kevin, let me know if you got some things ready to go that can
> > be pulled into omap-for-linus.
> 
> Nothing yet for hwmod.  The stuff that's mostly done is UART + MMC,
> but those both still need validation on OMAP2 and OMAP4.

OK, just trying to cut down dependencies between patches.
 
> >> In addition, this has the in-progress UART + MMC hwmod changes.
> >
> > Sounds like those are not ready to go yet then. So I guess it's
> > currently only your pm-next that's ready to go?
> 
> I've submitted PM core stuff in pm-next and I've also submitted some
> GPIO changes for 2.6.35.
> 
> I have a few more things to add to pm-next, and I'll be doing that
> today.

OK

Regards,

Tony

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

* RE: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-05 20:59                       ` Kevin Hilman
  2010-05-05 22:37                         ` Tony Lindgren
  2010-05-07  6:52                         ` Varadarajan, Charulatha
@ 2010-05-12 12:29                         ` Varadarajan, Charulatha
  2010-05-12 14:47                           ` Kevin Hilman
  2 siblings, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-12 12:29 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, Nayak, Rajendra, paul, tony

> 
> >> -----Original Message-----
> >> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
> >> Sent: Saturday, May 01, 2010 5:34 AM
> >> To: Varadarajan, Charulatha
> >> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
> tony@atomide.com
> >> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
> >>
[...]
> >> >
> >> > +static int init_gpio_info(void)
> >> > +{
> >> > +   gpio_bank_bits = 32;
> >> > +
> >> > +   if (cpu_is_omap15xx()) {
> >> > +           gpio_bank_count = 2;
> >> > +           gpio_bank_bits = 16;
> >> > +   } else if (cpu_is_omap16xx()) {
> >> > +           gpio_bank_count = 5;
> >> > +           gpio_bank_bits = 16;
> >> > +   } else if (cpu_is_omap7xx())
> >> > +           gpio_bank_count = 7;
> >> > +   else if (cpu_is_omap242x())
> >> > +           gpio_bank_count = 4;
> >> > +   else if (cpu_is_omap243x())
> >> > +           gpio_bank_count = 5;
> >> > +   else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> >> > +           gpio_bank_count = OMAP34XX_NR_GPIOS;
> >>
> >> Both the bank count and bank bits could be part of platform_data
> >> and set in the SoC specific init.  This is the GPIO driver part
> >> and we're trying to make this as SoC independent as possible.  Anytime
> >> you need to add a cpu_is* or #ifdef in this code indicates something
> >> that should be part of SoC specific init and passed in.
> >
> > bank count and bank bits are not specific to each device, but SoC specific.
> > Hence I did not consider passing it as part of platform_data, because this
> information would be duplicated across all devices in that SoC.
> >
> > It would be good if we have a way to pass the SoC specific data which is
> > common for all the devices rather than duplicating them by sending them via
> > platform_data.
> >
> > Anyways, I can move it to platform_data if there is no other way.
> 
> Probably the right place for the SoC specifics is attached to the SoC
> specific hwmod using the dev_attr pointer.  That struct can then
> be passed in via platform_data.
> 
> You can see how Thara did this for SmartReflex as an example.
> 

Using dev_attr for OMAP2PLUS is fine. How about OMAP1? 
1. To be implemented in a uniform way, may I get this info as 
part of platform_data? 
2. Use dev_attr for OMAP2PLUS and use platform_data for OMAP1? 

Any other way? Please suggest.

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

* RE: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-05-05 22:31           ` Tony Lindgren
  2010-05-07  6:52             ` Varadarajan, Charulatha
@ 2010-05-12 12:29             ` Varadarajan, Charulatha
  2010-05-12 14:49               ` Kevin Hilman
  1 sibling, 1 reply; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-12 12:29 UTC (permalink / raw)
  To: Varadarajan, Charulatha, Tony Lindgren
  Cc: linux-omap, Nayak, Rajendra, paul, khilman

Tony/Kevin,

> > > +{
> > > +	if (cpu_is_omap242x())
> > > +		gpio_bank_count = 4;
> > > +	else if (cpu_is_omap243x())
> > > +		gpio_bank_count = 5;
> > > +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
> > > +		gpio_bank_count = OMAP34XX_NR_GPIOS;
> > > +
> > > +	if (gpio_init())
> > > +		return -EINVAL;
> > > +
> > > +	early_platform_driver_register_all("earlygpio");
> > > +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
> > > +	return 0;
> > > +}
> >
> > Then please replace this init with something like:
> 
> Okay.
> 
> >
> > #ifdef CONFIG_ARCH_OMAP2
> > int __init omap242x_gpio_init(void)
> > {
> > 	if (!cpu_is_omap2420())
> > 		return -EINVAL;
> >
> > 	gpio_bank_count = 4;
> >
> > 	return gpio_init(METHOD_GPIO_24XX);
> > }
> > subsys_initcall(omap242x_gpio_init);
> >
> > int __init omap243x_gpio_init(void)
> > {
> > 	if (!cpu_is_omap2430())
> > 		return -EINVAL;
> >
> > 	gpio_bank_count = 5;
> >
> > 	return gpio_init(METHOD_GPIO_24XX);
> > }
> > subsys_initcall(omap243x_gpio_init);
> > #endif
> >
> > #ifdef CONFIG_ARCH_OMAP3
> > int __init omap34xx_gpio_init(void)
> > {
> > 	if (!cpu_is_omap34xx())
> > 		return -EINVAL;
> >
> > 	gpio_bank_count = OMAP34X_NR_GPIOS;
> >
> > 	return gpio_init(METHOD_GPIO_34XX);
> > }
> > subsys_initcall(omap34xx_gpio_init);
> > #endif
> > ...
> >
> > This way it will be more future proof when new omaps get added
> > and the if else stuff disappears. Also then you'll have an omap
> > specific function to initialize the gpio stuff.
> >
> > Note that then early_platform_driver_register_all and
> > early_platform_driver_probe can be moved to gpio_init.
> >
> > With multi-omap build the subsys_initcall runs for all of the
> > selected platforms, but returns early except for the machine
> > we're running on. All the code is optimized out for omap
> > specific product kernels.
> 
> Okay. Will do the needful and send new patch series in 2 weeks.

subsys_initcall is not sufficient for SoC specific gpio_init as it needs
to be done before machine_init functions access gpio APIs. Hence I am 
making SoC specific gpio_init as postcore_initcall.


> 


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

* Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
  2010-05-12 12:29                         ` Varadarajan, Charulatha
@ 2010-05-12 14:47                           ` Kevin Hilman
  0 siblings, 0 replies; 33+ messages in thread
From: Kevin Hilman @ 2010-05-12 14:47 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: linux-omap, Nayak, Rajendra, paul, tony

"Varadarajan, Charulatha" <charu@ti.com> writes:

>> 
>> >> -----Original Message-----
>> >> From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>> >> Sent: Saturday, May 01, 2010 5:34 AM
>> >> To: Varadarajan, Charulatha
>> >> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com;
>> tony@atomide.com
>> >> Subject: Re: [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device
>> >>
> [...]
>> >> >
>> >> > +static int init_gpio_info(void)
>> >> > +{
>> >> > +   gpio_bank_bits = 32;
>> >> > +
>> >> > +   if (cpu_is_omap15xx()) {
>> >> > +           gpio_bank_count = 2;
>> >> > +           gpio_bank_bits = 16;
>> >> > +   } else if (cpu_is_omap16xx()) {
>> >> > +           gpio_bank_count = 5;
>> >> > +           gpio_bank_bits = 16;
>> >> > +   } else if (cpu_is_omap7xx())
>> >> > +           gpio_bank_count = 7;
>> >> > +   else if (cpu_is_omap242x())
>> >> > +           gpio_bank_count = 4;
>> >> > +   else if (cpu_is_omap243x())
>> >> > +           gpio_bank_count = 5;
>> >> > +   else if (cpu_is_omap34xx() || cpu_is_omap44xx())
>> >> > +           gpio_bank_count = OMAP34XX_NR_GPIOS;
>> >>
>> >> Both the bank count and bank bits could be part of platform_data
>> >> and set in the SoC specific init.  This is the GPIO driver part
>> >> and we're trying to make this as SoC independent as possible.  Anytime
>> >> you need to add a cpu_is* or #ifdef in this code indicates something
>> >> that should be part of SoC specific init and passed in.
>> >
>> > bank count and bank bits are not specific to each device, but SoC specific.
>> > Hence I did not consider passing it as part of platform_data, because this
>> information would be duplicated across all devices in that SoC.
>> >
>> > It would be good if we have a way to pass the SoC specific data which is
>> > common for all the devices rather than duplicating them by sending them via
>> > platform_data.
>> >
>> > Anyways, I can move it to platform_data if there is no other way.
>> 
>> Probably the right place for the SoC specifics is attached to the SoC
>> specific hwmod using the dev_attr pointer.  That struct can then
>> be passed in via platform_data.
>> 
>> You can see how Thara did this for SmartReflex as an example.
>> 
>
> Using dev_attr for OMAP2PLUS is fine. How about OMAP1? 
> 1. To be implemented in a uniform way, may I get this info as 
> part of platform_data? 
> 2. Use dev_attr for OMAP2PLUS and use platform_data for OMAP1? 

Not sure I understand the question.

You should be able to use a dev_attr struct in OMAP1 and OMAP2+, as
there is technically nothing hwmod specific in the dev_attr.  It
is attached to the hwmod as a 'void *' and should be passed into the driver
as the platform_data.

Kevin


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

* Re: [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO
  2010-05-12 12:29             ` Varadarajan, Charulatha
@ 2010-05-12 14:49               ` Kevin Hilman
  0 siblings, 0 replies; 33+ messages in thread
From: Kevin Hilman @ 2010-05-12 14:49 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: Tony Lindgren, linux-omap, Nayak, Rajendra, paul

"Varadarajan, Charulatha" <charu@ti.com> writes:

> Tony/Kevin,
>
>> > > +{
>> > > +	if (cpu_is_omap242x())
>> > > +		gpio_bank_count = 4;
>> > > +	else if (cpu_is_omap243x())
>> > > +		gpio_bank_count = 5;
>> > > +	else if (cpu_is_omap34xx() || cpu_is_omap44xx())
>> > > +		gpio_bank_count = OMAP34XX_NR_GPIOS;
>> > > +
>> > > +	if (gpio_init())
>> > > +		return -EINVAL;
>> > > +
>> > > +	early_platform_driver_register_all("earlygpio");
>> > > +	early_platform_driver_probe("earlygpio", gpio_bank_count, 0);
>> > > +	return 0;
>> > > +}
>> >
>> > Then please replace this init with something like:
>> 
>> Okay.
>> 
>> >
>> > #ifdef CONFIG_ARCH_OMAP2
>> > int __init omap242x_gpio_init(void)
>> > {
>> > 	if (!cpu_is_omap2420())
>> > 		return -EINVAL;
>> >
>> > 	gpio_bank_count = 4;
>> >
>> > 	return gpio_init(METHOD_GPIO_24XX);
>> > }
>> > subsys_initcall(omap242x_gpio_init);
>> >
>> > int __init omap243x_gpio_init(void)
>> > {
>> > 	if (!cpu_is_omap2430())
>> > 		return -EINVAL;
>> >
>> > 	gpio_bank_count = 5;
>> >
>> > 	return gpio_init(METHOD_GPIO_24XX);
>> > }
>> > subsys_initcall(omap243x_gpio_init);
>> > #endif
>> >
>> > #ifdef CONFIG_ARCH_OMAP3
>> > int __init omap34xx_gpio_init(void)
>> > {
>> > 	if (!cpu_is_omap34xx())
>> > 		return -EINVAL;
>> >
>> > 	gpio_bank_count = OMAP34X_NR_GPIOS;
>> >
>> > 	return gpio_init(METHOD_GPIO_34XX);
>> > }
>> > subsys_initcall(omap34xx_gpio_init);
>> > #endif
>> > ...
>> >
>> > This way it will be more future proof when new omaps get added
>> > and the if else stuff disappears. Also then you'll have an omap
>> > specific function to initialize the gpio stuff.
>> >
>> > Note that then early_platform_driver_register_all and
>> > early_platform_driver_probe can be moved to gpio_init.
>> >
>> > With multi-omap build the subsys_initcall runs for all of the
>> > selected platforms, but returns early except for the machine
>> > we're running on. All the code is optimized out for omap
>> > specific product kernels.
>> 
>> Okay. Will do the needful and send new patch series in 2 weeks.
>
> subsys_initcall is not sufficient for SoC specific gpio_init as it needs
> to be done before machine_init functions access gpio APIs. Hence I am 
> making SoC specific gpio_init as postcore_initcall.

OK.  Please add a comment at the postcore_initcall() location with the
details as to why it is needed and what it needs to go before etc.

Kevin

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

* Re: [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3
  2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
  2010-04-22 15:55             ` [PATCH 7/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420 Charulatha V
@ 2010-05-20 10:13             ` Benoit Cousson
  2010-05-20 10:16               ` Varadarajan, Charulatha
  1 sibling, 1 reply; 33+ messages in thread
From: Benoit Cousson @ 2010-05-20 10:13 UTC (permalink / raw)
  To: Varadarajan, Charulatha; +Cc: linux-omap, Nayak, Rajendra, paul, tony, khilman

On 4/22/2010 5:55 PM, Varadarajan, Charulatha wrote:
> Add hwmod structures for GPIO module on OMAP3

[snip]

> +
> +static struct omap_hwmod omap3xxx_gpio1_hwmod = {
> +       .name           = "gpio1_hwmod",

You should remove the "_hwmod" prefix of all the hwmod name in order to 
align with the convention we have on OMAP4.
It will increase the data size without bringing any extra information.

Thanks,
Benoit

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

* RE: [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3
  2010-05-20 10:13             ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Benoit Cousson
@ 2010-05-20 10:16               ` Varadarajan, Charulatha
  0 siblings, 0 replies; 33+ messages in thread
From: Varadarajan, Charulatha @ 2010-05-20 10:16 UTC (permalink / raw)
  To: Cousson, Benoit; +Cc: linux-omap, Nayak, Rajendra, paul, tony, khilman



> -----Original Message-----
> From: Cousson, Benoit
> Sent: Thursday, May 20, 2010 3:43 PM
> To: Varadarajan, Charulatha
> Cc: linux-omap@vger.kernel.org; Nayak, Rajendra; paul@pwsan.com; tony@atomide.com;
> khilman@deeprootsystems.com
> Subject: Re: [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3
> 
> On 4/22/2010 5:55 PM, Varadarajan, Charulatha wrote:
> > Add hwmod structures for GPIO module on OMAP3
> 
> [snip]
> 
> > +
> > +static struct omap_hwmod omap3xxx_gpio1_hwmod = {
> > +       .name           = "gpio1_hwmod",
> 
> You should remove the "_hwmod" prefix of all the hwmod name in order to
> align with the convention we have on OMAP4.
> It will increase the data size without bringing any extra information.
> 

Yep. Will change the naming convention as followed in OMAP4.

> Thanks,
> Benoit

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

end of thread, other threads:[~2010-05-20 10:16 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-22 15:55 [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Charulatha V
2010-04-22 15:55 ` [PATCH 1/9] OMAP:GPIO: Modify init() in preparation for platform device implementation Charulatha V
2010-04-22 15:55   ` [PATCH 2/9] OMAP:GPIO: Introduce support for OMAP15xx chip specific GPIO Charulatha V
2010-04-22 15:55     ` [PATCH 3/9] OMAP:GPIO: Introduce support for OMAP16xx " Charulatha V
2010-04-22 15:55       ` [PATCH 4/9] OMAP:GPIO: Introduce support for OMAP7xx " Charulatha V
2010-04-22 15:55         ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS " Charulatha V
2010-04-22 15:55           ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Charulatha V
2010-04-22 15:55             ` [PATCH 7/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2420 Charulatha V
2010-04-22 15:55               ` [PATCH 8/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP2430 Charulatha V
2010-04-22 15:55                 ` [PATCH 9/9] OMAP:GPIO: Implement GPIO as a platform device Charulatha V
2010-05-01  0:04                   ` Kevin Hilman
2010-05-04 15:59                     ` Varadarajan, Charulatha
2010-05-05 20:59                       ` Kevin Hilman
2010-05-05 22:37                         ` Tony Lindgren
2010-05-07  6:52                         ` Varadarajan, Charulatha
2010-05-12 12:29                         ` Varadarajan, Charulatha
2010-05-12 14:47                           ` Kevin Hilman
2010-05-20 10:13             ` [PATCH 6/9] OMAP:GPIO:hwmod: add GPIO hwmods for OMAP3 Benoit Cousson
2010-05-20 10:16               ` Varadarajan, Charulatha
2010-04-30 23:03           ` [PATCH 5/9] OMAP:GPIO: Introduce support for OMAP2PLUS chip specific GPIO Kevin Hilman
2010-05-04 15:59             ` Varadarajan, Charulatha
2010-05-11 14:43               ` Varadarajan, Charulatha
2010-05-11 15:25                 ` Kevin Hilman
2010-05-05 22:31           ` Tony Lindgren
2010-05-07  6:52             ` Varadarajan, Charulatha
2010-05-12 12:29             ` Varadarajan, Charulatha
2010-05-12 14:49               ` Kevin Hilman
2010-05-07  6:57 ` [PATCH 00/09] OMAP:GPIO:Implement GPIO in HWMOD way Varadarajan, Charulatha
2010-05-07 15:32   ` Tony Lindgren
2010-05-10 15:14     ` Kevin Hilman
2010-05-10 22:22       ` Tony Lindgren
2010-05-11 15:21         ` Kevin Hilman
2010-05-11 15:54           ` Tony Lindgren

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.