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 <ch...@ti.com>
Signed-off-by: Rajendra Nayak <rna...@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

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to