INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
        INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_gpio, "mmp2-gpio", NULL),
        INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"),
        INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"),
        INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"),
 
        INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
        INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
-       INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
        INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
        INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
        INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
 
        INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
        INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
        INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"),
        INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
        OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
        {}
 };
        OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
        {}
 };
 
        OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "mmp2-gpio", NULL),
        OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
        {}
 };
 
 };
 
 struct platform_device mmp2_device_gpio = {
-       .name           = "pxa-gpio",
+       .name           = "mmp2-gpio",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(mmp2_resource_gpio),
        .resource       = mmp2_resource_gpio,
 
 };
 
 struct platform_device pxa168_device_gpio = {
-       .name           = "pxa-gpio",
+       .name           = "mmp-gpio",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(pxa168_resource_gpio),
        .resource       = pxa168_resource_gpio,
 
 };
 
 struct platform_device pxa910_device_gpio = {
-       .name           = "pxa-gpio",
+       .name           = "mmp-gpio",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(pxa910_resource_gpio),
        .resource       = pxa910_resource_gpio,
 
        },
 };
 
-struct platform_device pxa_device_gpio = {
-       .name           = "pxa-gpio",
+struct platform_device pxa25x_device_gpio = {
+#ifdef CONFIG_CPU_PXA26x
+       .name           = "pxa26x-gpio",
+#else
+       .name           = "pxa25x-gpio",
+#endif
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(pxa_resource_gpio),
+       .resource       = pxa_resource_gpio,
+};
+
+struct platform_device pxa27x_device_gpio = {
+       .name           = "pxa27x-gpio",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(pxa_resource_gpio),
+       .resource       = pxa_resource_gpio,
+};
+
+struct platform_device pxa3xx_device_gpio = {
+       .name           = "pxa3xx-gpio",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(pxa_resource_gpio),
+       .resource       = pxa_resource_gpio,
+};
+
+struct platform_device pxa93x_device_gpio = {
+       .name           = "pxa93x-gpio",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(pxa_resource_gpio),
        .resource       = pxa_resource_gpio,
 
 extern struct platform_device sa1100_device_rtc;
 extern struct platform_device pxa_device_rtc;
 extern struct platform_device pxa_device_ac97;
-extern struct platform_device pxa_device_gpio;
 
 extern struct platform_device pxa27x_device_i2c_power;
 extern struct platform_device pxa27x_device_ohci;
 extern struct platform_device pxa_device_asoc_ssp3;
 extern struct platform_device pxa_device_asoc_ssp4;
 
+extern struct platform_device pxa25x_device_gpio;
+extern struct platform_device pxa27x_device_gpio;
+extern struct platform_device pxa3xx_device_gpio;
+extern struct platform_device pxa93x_device_gpio;
+
 void __init pxa_register_device(struct platform_device *dev, void *data);
 
        INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
        INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
        INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
+#ifdef CONFIG_CPU_PXA26x
+       INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL),
+#else
+       INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL),
+#endif
        INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
                register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
-               pxa_register_device(&pxa_device_gpio, &pxa25x_gpio_info);
+               pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
                ret = platform_add_devices(pxa25x_devices,
                                           ARRAY_SIZE(pxa25x_devices));
                if (ret)
 
        INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
        INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
        INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL),
        INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
                register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
-               pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info);
+               pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info);
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
 
 
        INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
        INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
        INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_pxa3xx_gpio, "pxa3xx-gpio", NULL),
+       INIT_CLKREG(&clk_pxa3xx_gpio, "pxa93x-gpio", NULL),
        INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 }
 
 static struct platform_device *devices[] __initdata = {
-       &pxa_device_gpio,
        &pxa27x_device_udc,
        &pxa_device_pmu,
        &pxa_device_i2s,
                register_syscore_ops(&pxa3xx_mfp_syscore_ops);
                register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
-               if (!of_have_populated_dt())
-                       ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+               if (of_have_populated_dt())
+                       return 0;
+
+               ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+               if (ret)
+                       return ret;
+               if (cpu_is_pxa300() || cpu_is_pxa310() || cpu_is_pxa320())
+                       ret = platform_device_register(&pxa3xx_device_gpio);
        }
 
        return ret;
 
 
 #include <mach/pxa930.h>
 
+#include "devices.h"
+
 static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
 
        MFP_ADDR(GPIO0, 0x02e0),
 
 static int __init pxa930_init(void)
 {
+       int ret = 0;
+
        if (cpu_is_pxa93x()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa930_mfp_addr_map);
+               ret = platform_device_register(&pxa93x_device_gpio);
        }
 
        if (cpu_is_pxa935())
 
 
        clk = mmp_clk_register_apbc("gpio", "vctcxo",
                                apbc_base + APBC_GPIO, 10, 0, &clk_lock);
-       clk_register_clkdev(clk, NULL, "pxa-gpio");
+       clk_register_clkdev(clk, NULL, "mmp2-gpio");
 
        clk = mmp_clk_register_apbc("kpc", "clk32",
                                apbc_base + APBC_KPC, 10, 0, &clk_lock);
 
 
        clk = mmp_clk_register_apbc("gpio", "vctcxo",
                                apbc_base + APBC_GPIO, 10, 0, &clk_lock);
-       clk_register_clkdev(clk, NULL, "pxa-gpio");
+       clk_register_clkdev(clk, NULL, "mmp-gpio");
 
        clk = mmp_clk_register_apbc("kpc", "clk32",
                                apbc_base + APBC_KPC, 10, 0, &clk_lock);
 
 
        clk = mmp_clk_register_apbc("gpio", "vctcxo",
                                apbc_base + APBC_GPIO, 10, 0, &clk_lock);
-       clk_register_clkdev(clk, NULL, "pxa-gpio");
+       clk_register_clkdev(clk, NULL, "mmp-gpio");
 
        clk = mmp_clk_register_apbc("kpc", "clk32",
                                apbc_base + APBC_KPC, 10, 0, &clk_lock);
 
 #endif
 };
 
-enum {
+enum pxa_gpio_type {
        PXA25X_GPIO = 0,
        PXA26X_GPIO,
        PXA27X_GPIO,
        PXA3XX_GPIO,
        PXA93X_GPIO,
        MMP_GPIO = 0x10,
+       MMP2_GPIO,
+};
+
+struct pxa_gpio_id {
+       enum pxa_gpio_type      type;
+       int                     gpio_nums;
 };
 
 static DEFINE_SPINLOCK(gpio_lock);
 static struct pxa_gpio_chip *pxa_gpio_chips;
-static int gpio_type;
+static enum pxa_gpio_type gpio_type;
 static void __iomem *gpio_reg_base;
 
+static struct pxa_gpio_id pxa25x_id = {
+       .type           = PXA25X_GPIO,
+       .gpio_nums      = 85,
+};
+
+static struct pxa_gpio_id pxa26x_id = {
+       .type           = PXA26X_GPIO,
+       .gpio_nums      = 90,
+};
+
+static struct pxa_gpio_id pxa27x_id = {
+       .type           = PXA27X_GPIO,
+       .gpio_nums      = 121,
+};
+
+static struct pxa_gpio_id pxa3xx_id = {
+       .type           = PXA3XX_GPIO,
+       .gpio_nums      = 128,
+};
+
+static struct pxa_gpio_id pxa93x_id = {
+       .type           = PXA93X_GPIO,
+       .gpio_nums      = 192,
+};
+
+static struct pxa_gpio_id mmp_id = {
+       .type           = MMP_GPIO,
+       .gpio_nums      = 128,
+};
+
+static struct pxa_gpio_id mmp2_id = {
+       .type           = MMP2_GPIO,
+       .gpio_nums      = 192,
+};
+
 #define for_each_gpio_chip(i, c)                       \
        for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
 
        .irq_set_wake   = pxa_gpio_set_wake,
 };
 
-static int pxa_gpio_nums(void)
+static int pxa_gpio_nums(struct platform_device *pdev)
 {
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+       struct pxa_gpio_id *pxa_id = (struct pxa_gpio_id *)id->driver_data;
        int count = 0;
 
-#ifdef CONFIG_ARCH_PXA
-       if (cpu_is_pxa25x()) {
-#ifdef CONFIG_CPU_PXA26x
-               count = 89;
-               gpio_type = PXA26X_GPIO;
-#elif defined(CONFIG_PXA25x)
-               count = 84;
-               gpio_type = PXA26X_GPIO;
-#endif /* CONFIG_CPU_PXA26x */
-       } else if (cpu_is_pxa27x()) {
-               count = 120;
-               gpio_type = PXA27X_GPIO;
-       } else if (cpu_is_pxa93x()) {
-               count = 191;
-               gpio_type = PXA93X_GPIO;
-       } else if (cpu_is_pxa3xx()) {
-               count = 127;
-               gpio_type = PXA3XX_GPIO;
-       }
-#endif /* CONFIG_ARCH_PXA */
-
-#ifdef CONFIG_ARCH_MMP
-       if (cpu_is_pxa168() || cpu_is_pxa910()) {
-               count = 127;
-               gpio_type = MMP_GPIO;
-       } else if (cpu_is_mmp2()) {
-               count = 191;
-               gpio_type = MMP_GPIO;
+       switch (pxa_id->type) {
+       case PXA25X_GPIO:
+       case PXA26X_GPIO:
+       case PXA27X_GPIO:
+       case PXA3XX_GPIO:
+       case PXA93X_GPIO:
+       case MMP_GPIO:
+       case MMP2_GPIO:
+               gpio_type = pxa_id->type;
+               count = pxa_id->gpio_nums - 1;
+               break;
+       default:
+               count = -EINVAL;
+               break;
        }
-#endif /* CONFIG_ARCH_MMP */
        return count;
 }
 
 
        ret = pxa_gpio_probe_dt(pdev);
        if (ret < 0) {
-               pxa_last_gpio = pxa_gpio_nums();
+               pxa_last_gpio = pxa_gpio_nums(pdev);
 #ifdef CONFIG_ARCH_PXA
                if (gpio_is_pxa_type(gpio_type))
                        irq_base = PXA_GPIO_TO_IRQ(0);
        return 0;
 }
 
+static const struct platform_device_id gpio_id_table[] = {
+       { "pxa25x-gpio",        (unsigned long)&pxa25x_id },
+       { "pxa26x-gpio",        (unsigned long)&pxa26x_id },
+       { "pxa27x-gpio",        (unsigned long)&pxa27x_id },
+       { "pxa3xx-gpio",        (unsigned long)&pxa3xx_id },
+       { "pxa93x-gpio",        (unsigned long)&pxa93x_id },
+       { "mmp-gpio",           (unsigned long)&mmp_id },
+       { "mmp2-gpio",          (unsigned long)&mmp2_id },
+       { },
+};
+
 static struct platform_driver pxa_gpio_driver = {
        .probe          = pxa_gpio_probe,
        .driver         = {
                .name   = "pxa-gpio",
                .of_match_table = of_match_ptr(pxa_gpio_dt_ids),
        },
+       .id_table       = gpio_id_table,
 };
 module_platform_driver(pxa_gpio_driver);