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

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

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

GPIO driver uses runtime APIs.Clock FW APIs are used to enable
iclk and fclk when CONFIG_PM_RUNTIME is not defined.

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

Signed-off-by: Charulatha V <[email protected]>
Signed-off-by: Rajendra Nayak <[email protected]>
---
 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            |  389 +++++++++++-----------------------
 8 files changed, 178 insertions(+), 293 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 58a0474..d2d63ca 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 9cba556..3962234 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 a5c0c9c..4d76598 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 70deebc..55a5796 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -21,6 +21,8 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -147,102 +149,11 @@ struct gpio_bank {
        struct gpio_chip chip;
        struct clk *dbck;
        u32 mod_usage;
+       struct device *dev;
+       bool dbck_flag;
 };
 
-#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 +173,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)
 {
@@ -587,6 +481,12 @@ void omap_set_gpio_debounce(int gpio, int enable)
                return;
        }
 
+       if ((bank->dbck_flag == true) && (!bank->dbck)) {
+               bank->dbck = clk_get(bank->dev, "dbck");
+               if (IS_ERR(bank->dbck))
+                       pr_err("GPIO: Could not get dbck\n");
+       }
+
        spin_lock_irqsave(&bank->lock, flags);
        val = __raw_readl(reg);
 
@@ -1467,7 +1367,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);
@@ -1581,24 +1482,6 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned 
offset)
 
 /*---------------------------------------------------------------------*/
 
-static int initialized;
-#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_ick;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2)
-static struct clk * gpio_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2430)
-static struct clk * gpio5_ick;
-static struct clk * gpio5_fck;
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
-#endif
-
 static void __init omap_gpio_show_rev(void)
 {
        u32 rev;
@@ -1621,6 +1504,17 @@ static void __init omap_gpio_show_rev(void)
  */
 static struct lock_class_key gpio_lock_class;
 
+static inline int init_gpio_info(void)
+{
+       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 +1580,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,139 +1624,102 @@ static void __init omap_gpio_chip_init(struct 
gpio_bank *bank)
        set_irq_data(bank->irq, bank);
 }
 
-static int __init _omap_gpio_init(void)
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
-       int i;
-       int gpio = 0;
+       static int gpio_init_done;
+       struct omap_gpio_platform_data *pdata;
+       int id;
        struct gpio_bank *bank;
-       int bank_size = SZ_8K;  /* Module 4KB + L4 4KB except on omap1 */
-       char clk_name[11];
-
-       initialized = 1;
+       struct resource *res;
 
-#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]);
-               }
-       }
-#endif
+       if (!gpio_init_done) {
+               int ret;
 
+               gpio_bank_count = pdata->gpio_attr->gpio_bank_count;
+               gpio_bank_bits = pdata->gpio_attr->gpio_bank_bits;
 
-#ifdef CONFIG_ARCH_OMAP15XX
-       if (cpu_is_omap15xx()) {
-               gpio_bank_count = 2;
-               gpio_bank = gpio_bank_1510;
-               bank_size = SZ_2K;
+               ret = init_gpio_info();
+               if (ret)
+                       return ret;
        }
-#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;
+
+       id = pdev->id;
+       bank = &gpio_bank[id];
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (unlikely(!res)) {
+               pr_err("GPIO Bank %i Invalid IRQ resource\n", id);
+               return -ENODEV;
        }
-#endif
-#ifdef CONFIG_ARCH_OMAP3
-       if (cpu_is_omap34xx()) {
-               gpio_bank_count = OMAP34XX_NR_GPIOS;
-               gpio_bank = gpio_bank_34xx;
+       bank->irq = res->start;
+       bank->virtual_irq_start = pdata->virtual_irq_start;
+       bank->method = pdata->method;
+       bank->dev = &pdev->dev;
+
+       spin_lock_init(&bank->lock);
+
+       /* Static mapping, never released */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (unlikely(!res)) {
+               pr_err("GPIO Bank %i Invalid mem resource\n", id);
+               return -ENODEV;
        }
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       if (cpu_is_omap44xx()) {
-               gpio_bank_count = OMAP34XX_NR_GPIOS;
-               gpio_bank = gpio_bank_44xx;
+
+       bank->base = ioremap(res->start, resource_size(res));
+       if (!bank->base) {
+               pr_err("Could not ioremap gpio bank%i\n", id);
+               return -ENOMEM;
        }
-#endif
-       for (i = 0; i < gpio_bank_count; i++) {
 
-               bank = &gpio_bank[i];
-               spin_lock_init(&bank->lock);
+       pm_runtime_enable(bank->dev);
 
-               /* Static mapping, never released */
-               bank->base = ioremap(bank->pbase, bank_size);
-               if (!bank->base) {
-                       printk(KERN_ERR "Could not ioremap gpio bank%i\n", i);
-                       continue;
-               }
+       pm_runtime_get_sync(bank->dev);
 
-               omap_gpio_mod_init(bank, i);
-               omap_gpio_chip_init(bank);
+       if (cpu_class_is_omap2()) {
+#ifndef CONFIG_PM_RUNTIME
+               struct clk *clock;
+
+               clock = clk_get(bank->dev, "ick");
+               if (IS_ERR(clock))
+                       pr_err("GPIO %d: Could not get ick\n", id + 1);
+               else
+                       clk_enable(clock);
+
 
-               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 (pdata->gpio_attr->fck_flag) {
+                       clock = clk_get(bank->dev, "fck");
+                       if (IS_ERR(clock))
+                               pr_err("GPIO %d: Could not get fck\n", id + 1);
+                       else
+                               clk_enable(clock);
                }
+#endif
+               bank->dbck_flag = pdata->gpio_attr->dbck_flag;
+       } else if (pdata->gpio_attr->arm_gpio_ck_flag && !gpio_init_done) {
+               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_mod_init(bank, id);
+       omap_gpio_chip_init(bank);
 
-       omap_gpio_show_rev();
+       if (!gpio_init_done) {
+               omap_gpio_show_rev();
+               gpio_init_done = 1;
+       }
 
        return 0;
 }
@@ -2210,25 +2068,34 @@ void omap_gpio_restore_context(void)
 }
 #endif
 
+static struct platform_driver omap_gpio_driver = {
+       .probe          = omap_gpio_probe,
+       .driver         = {
+               .name   = "omap-gpio",
+       },
+};
+
 /*
- * This may get called early from board specific init
- * for boards that have interrupts routed via FPGA.
+ * gpio driver register needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap_gpio_drv_reg() is a postcore_initcall.
  */
+static int __init omap_gpio_drv_reg(void)
+{
+       return platform_driver_register(&omap_gpio_driver);
+}
+postcore_initcall(omap_gpio_drv_reg);
+
+/* TODO: Remove omap_gpio_init() and its usage from board files */
 int __init omap_gpio_init(void)
 {
-       if (!initialized)
-               return _omap_gpio_init();
-       else
-               return 0;
+       return 0;
 }
 
 static int __init omap_gpio_sysinit(void)
 {
        int ret = 0;
 
-       if (!initialized)
-               ret = _omap_gpio_init();
-
        mpuio_init();
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-- 
1.6.3.3

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

Reply via email to